← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~ilasc/launchpad:add-properties-column-to-revisionstatusreport into launchpad:master

 

Ioana Lasc has proposed merging ~ilasc/launchpad:add-properties-column-to-revisionstatusreport into launchpad:master.

Commit message:
Add a properties attribute to RevisionStatusReport

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~ilasc/launchpad/+git/launchpad/+merge/427821
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~ilasc/launchpad:add-properties-column-to-revisionstatusreport into launchpad:master.
diff --git a/lib/lp/code/interfaces/revisionstatus.py b/lib/lp/code/interfaces/revisionstatus.py
index 37da501..0734df8 100644
--- a/lib/lp/code/interfaces/revisionstatus.py
+++ b/lib/lp/code/interfaces/revisionstatus.py
@@ -28,7 +28,7 @@ from lazr.restful.declarations import (
 from lazr.restful.fields import Reference
 from lazr.restful.interface import copy_field
 from zope.interface import Attribute, Interface
-from zope.schema import Bytes, Choice, Datetime, Int, TextLine
+from zope.schema import Bytes, Choice, Datetime, Dict, Int, TextLine
 from zope.security.interfaces import Unauthorized
 
 from lp import _
@@ -160,6 +160,17 @@ class IRevisionStatusReportEditableAttributes(Interface):
         )
     )
 
+    properties = exported(
+        Dict(
+            title=_("General-purpose metadata"),
+            description=_("A dictionary of general-purpose metadata."),
+            key_type=TextLine(title=_("ARG name")),
+            value_type=TextLine(title=_("ARG value")),
+            required=False,
+            readonly=False,
+        )
+    )
+
     @mutator_for(result)
     @operation_parameters(result=copy_field(result))
     @export_write_operation()
@@ -223,17 +234,22 @@ class IRevisionStatusReportEdit(Interface):
             title=_("A short summary of the result."), required=False
         ),
         result=Choice(vocabulary=RevisionStatusResult, required=False),
+        properties=Dict(
+            title=_("Properties dictionary"),
+            required=False,
+        ),
     )
     @scoped(AccessTokenScope.REPOSITORY_BUILD_STATUS.title)
     @export_write_operation()
     @operation_for_version("devel")
-    def update(title, url, result_summary, result):
+    def update(title, url, result_summary, result, properties):
         """Updates a status report.
 
         :param title: A short title for the report.
         :param url: The external url of the report.
         :param result_summary: A short summary of the result.
         :param result: The result of the report.
+        :param properties: A dictionary of general-purpose metadata.
         """
 
 
diff --git a/lib/lp/code/model/revisionstatus.py b/lib/lp/code/model/revisionstatus.py
index bcbca59..ebc5914 100644
--- a/lib/lp/code/model/revisionstatus.py
+++ b/lib/lp/code/model/revisionstatus.py
@@ -11,6 +11,7 @@ import io
 import os
 
 import pytz
+from storm.databases.postgres import JSON
 from storm.expr import Desc
 from storm.locals import And, DateTime, Int, Reference, Unicode
 from zope.component import getUtility
@@ -70,6 +71,8 @@ class RevisionStatusReport(StormBase):
         name="date_finished", tzinfo=pytz.UTC, allow_none=True
     )
 
+    properties = JSON("properties", allow_none=True)
+
     def __init__(
         self,
         git_repository,
@@ -80,6 +83,7 @@ class RevisionStatusReport(StormBase):
         result_summary,
         result,
         ci_build=None,
+        properties=None,
     ):
         super().__init__()
         self.creator = user
@@ -91,6 +95,7 @@ class RevisionStatusReport(StormBase):
         self.ci_build = ci_build
         self.date_created = UTC_NOW
         self.transitionToNewResult(result)
+        self.properties = properties
 
     def setLog(self, log_data):
         filename = "%s-%s.txt" % (self.title, self.commit_sha1)
@@ -147,7 +152,14 @@ class RevisionStatusReport(StormBase):
             self.date_finished = UTC_NOW
         self.result = result
 
-    def update(self, title=None, url=None, result_summary=None, result=None):
+    def update(
+        self,
+        title=None,
+        url=None,
+        result_summary=None,
+        result=None,
+        properties=None,
+    ):
         if title is not None:
             self.title = title
         if url is not None:
@@ -156,6 +168,8 @@ class RevisionStatusReport(StormBase):
             self.result_summary = result_summary
         if result is not None:
             self.transitionToNewResult(result)
+        if properties is not None:
+            self.properties = properties
 
     def getArtifactURLs(self, artifact_type):
         clauses = [
@@ -200,6 +214,7 @@ class RevisionStatusReportSet:
         date_finished=None,
         log=None,
         ci_build=None,
+        properties=None,
     ):
         """See `IRevisionStatusReportSet`."""
         store = IStore(RevisionStatusReport)
@@ -212,6 +227,7 @@ class RevisionStatusReportSet:
             result_summary,
             result,
             ci_build=ci_build,
+            properties=properties,
         )
         store.add(report)
         return report
diff --git a/lib/lp/code/model/tests/test_revisionstatus.py b/lib/lp/code/model/tests/test_revisionstatus.py
index 3c42053..f3a9e11 100644
--- a/lib/lp/code/model/tests/test_revisionstatus.py
+++ b/lib/lp/code/model/tests/test_revisionstatus.py
@@ -150,6 +150,19 @@ class TestRevisionStatusReport(TestCaseWithFactory):
         )
         self.assertEqual("test", report.title)
 
+    def test_properties(self):
+        test_properties = {
+            "launchpad.source-name": "go-module",
+            "launchpad.source-version": "v0.0.1",
+            "soss.source_url": "some url",
+            "soss.commit_id": "some commit id",
+        }
+        repo = self.factory.makeGitRepository()
+        report = self.factory.makeRevisionStatusReport(
+            git_repository=repo, commit_sha1="123"
+        )
+        self.assertEqual(test_properties, report.properties)
+
     def test_latest_log(self):
         report = self.factory.makeRevisionStatusReport()
         self.makeRevisionStatusArtifact(report=report)
@@ -334,6 +347,12 @@ class TestRevisionStatusReportWebservice(TestCaseWithFactory):
         report = self.factory.makeRevisionStatusReport(
             result=RevisionStatusResult.FAILED
         )
+        test_properties = {
+            "launchpad.source-name": "go-module",
+            "launchpad.source-version": "v0.0.1",
+            "soss.source_url": "some url",
+            "soss.commit_id": "some commit id",
+        }
         requester = report.creator
         repository = report.git_repository
         initial_commit_sha1 = report.commit_sha1
@@ -352,11 +371,21 @@ class TestRevisionStatusReportWebservice(TestCaseWithFactory):
                     commit_sha1=initial_commit_sha1,
                     result_summary=initial_result_summary,
                     result=RevisionStatusResult.FAILED,
+                    properties=test_properties,
                 ),
             )
             date_finished_before_update = report.date_finished
+            new_properties = {
+                "launchpad.source-name": "new-go-module",
+                "launchpad.source-version": "v2.2.1",
+                "soss.source_url": "new url",
+                "soss.commit_id": "new commit id",
+            }
         response = webservice.named_post(
-            report_url, "update", result="Succeeded"
+            report_url,
+            "update",
+            result="Succeeded",
+            properties=new_properties,
         )
         self.assertEqual(200, response.status)
         with person_logged_in(requester):
@@ -368,6 +397,7 @@ class TestRevisionStatusReportWebservice(TestCaseWithFactory):
                     result_summary=Equals(initial_result_summary),
                     result=Equals(RevisionStatusResult.SUCCEEDED),
                     date_finished=GreaterThan(date_finished_before_update),
+                    properties=Equals(new_properties),
                 ),
             )
 
diff --git a/lib/lp/testing/factory.py b/lib/lp/testing/factory.py
index ac56caf..0695f8a 100644
--- a/lib/lp/testing/factory.py
+++ b/lib/lp/testing/factory.py
@@ -2180,6 +2180,7 @@ class LaunchpadObjectFactory(ObjectFactory):
         url=None,
         result=None,
         ci_build=None,
+        properties=None,
     ):
         """Create a new RevisionStatusReport."""
         if title is None:
@@ -2198,6 +2199,13 @@ class LaunchpadObjectFactory(ObjectFactory):
                 commit_sha1 = hashlib.sha1(self.getUniqueBytes()).hexdigest()
         if result_summary is None:
             result_summary = self.getUniqueUnicode()
+        if properties is None:
+            properties = {
+                "launchpad.source-name": "go-module",
+                "launchpad.source-version": "v0.0.1",
+                "soss.source_url": "some url",
+                "soss.commit_id": "some commit id",
+            }
         return getUtility(IRevisionStatusReportSet).new(
             user,
             title,
@@ -2207,6 +2215,7 @@ class LaunchpadObjectFactory(ObjectFactory):
             result_summary,
             result,
             ci_build=ci_build,
+            properties=properties,
         )
 
     def makeRevisionStatusArtifact(