launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #27795
[Merge] ~ilasc/launchpad:revision-status-retrieval-api into launchpad:master
Ioana Lasc has proposed merging ~ilasc/launchpad:revision-status-retrieval-api into launchpad:master with ~ilasc/launchpad:revision-status-submission-api as a prerequisite.
Commit message:
Add retrieval API for revision status reports.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~ilasc/launchpad/+git/launchpad/+merge/412513
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~ilasc/launchpad:revision-status-retrieval-api into launchpad:master.
diff --git a/lib/lp/_schema_circular_imports.py b/lib/lp/_schema_circular_imports.py
index 5ac46de..e512526 100644
--- a/lib/lp/_schema_circular_imports.py
+++ b/lib/lp/_schema_circular_imports.py
@@ -66,7 +66,6 @@ from lp.code.interfaces.diff import IPreviewDiff
from lp.code.interfaces.gitref import IGitRef
from lp.code.interfaces.gitrepository import (
IGitRepository,
- IRevisionStatusArtifact,
IRevisionStatusReport,
)
from lp.code.interfaces.gitrule import (
@@ -521,6 +520,8 @@ patch_entry_return_type(IGitRepository, 'subscribe', IGitSubscription)
patch_entry_return_type(IGitRepository, 'getSubscription', IGitSubscription)
patch_reference_property(IGitRepository, 'code_import', ICodeImport)
patch_entry_return_type(IGitRepository, 'getRefByPath', IGitRef)
+patch_collection_return_type(
+ IGitRepository, 'getStatusReports', IRevisionStatusReport)
patch_collection_property(
IGitRepository, '_api_landing_targets', IBranchMergeProposal)
patch_collection_property(
diff --git a/lib/lp/code/interfaces/gitrepository.py b/lib/lp/code/interfaces/gitrepository.py
index 074e868..9543dc6 100644
--- a/lib/lp/code/interfaces/gitrepository.py
+++ b/lib/lp/code/interfaces/gitrepository.py
@@ -833,7 +833,7 @@ class RevisionStatusReportsFeatureDisabled(Unauthorized):
def __init__(self):
super(RevisionStatusReportsFeatureDisabled, self).__init__(
- "You do not have permission to create revision status reports")
+ "You do not have permission to create/view status reports.")
class IRevisionStatusReportView(Interface):
@@ -933,10 +933,13 @@ class IRevisionStatusReportSet(Interface):
"""
def findRevisionStatusReportByID(id):
- """Returns the RevisionStatusReport for a given ID."""
+ """Returns the `RevisionStatusReport` for a given ID."""
def findRevisionStatusReportByCreator(creator):
- """Returns the RevisionStatusReport for a creator."""
+ """Returns the `RevisionStatusReport` for a creator."""
+
+ def findRevisionStatusReportsByCommit(commmit_sha1):
+ """Returns the list of `RevisionStatusReport` for a commit."""
class IRevisionStatusArtifactSet(Interface):
@@ -1194,6 +1197,18 @@ class IGitRepositoryEdit(IWebhookTarget, IAccessTokenTarget):
:param result: The result of the new report.
"""
+ @operation_parameters(
+ commit_sha1=TextLine(title=_("The commit sha1 of the status report.")))
+ @scoped(AccessTokenScope.REPOSITORY_BUILD_STATUS.title)
+ @operation_returns_collection_of(Interface)
+ @export_read_operation()
+ @operation_for_version("devel")
+ def getStatusReports(commit_sha1):
+ """Retrieves the list of reports that exist for the sha1 commit.
+
+ :param commit_sha1: The commit sha1 for the report.
+ """
+
# XXX cjwatson 2015-01-19 bug=760849: "beta" is a lie to get WADL
# generation working. Individual attributes must set their version to
diff --git a/lib/lp/code/model/gitrepository.py b/lib/lp/code/model/gitrepository.py
index 3d78862..539bae1 100644
--- a/lib/lp/code/model/gitrepository.py
+++ b/lib/lp/code/model/gitrepository.py
@@ -85,9 +85,9 @@ from lp.app.enums import (
PUBLIC_INFORMATION_TYPES,
)
from lp.app.errors import (
+ NotFoundError,
SubscriptionPrivacyViolation,
UserCannotUnsubscribePerson,
- NotFoundError,
)
from lp.app.interfaces.informationtype import IInformationType
from lp.app.interfaces.launchpad import (
@@ -186,11 +186,6 @@ from lp.registry.model.accesspolicy import (
)
from lp.registry.model.person import Person
from lp.registry.model.teammembership import TeamParticipation
-from lp.services.webapp import (
- Navigation,
- stepthrough,
- )
-
from lp.services.auth.interfaces import IAccessTokenSet
from lp.services.auth.model import AccessTokenTargetMixin
from lp.services.auth.utils import create_access_token_secret
@@ -227,12 +222,17 @@ from lp.services.propertycache import (
cachedproperty,
get_property_cache,
)
+from lp.services.webapp import (
+ Navigation,
+ stepthrough,
+ )
from lp.services.webapp.authorization import check_permission
from lp.services.webapp.interfaces import ILaunchBag
from lp.services.webhooks.interfaces import IWebhookSet
from lp.services.webhooks.model import WebhookTargetMixin
from lp.snappy.interfaces.snap import ISnapSet
+
REVISION_STATUS_REPORT_ALLOW_CREATE = 'revision_status_report.allow_create'
logger = logging.getLogger(__name__)
@@ -381,7 +381,9 @@ class RevisionStatusReportNavigation(Navigation):
report_id = int(id)
except ValueError:
raise NotFoundError(id)
- report = IStore(RevisionStatusReport).find(RevisionStatusReport, id=report_id).one()
+ report = IStore(
+ RevisionStatusReport).find(
+ RevisionStatusReport, id=report_id).one()
if report is None:
raise NotFoundError(id)
return report
@@ -410,6 +412,12 @@ class RevisionStatusReportSet:
RevisionStatusReport,
creator=creator)
+ def findRevisionStatusReportsByCommit(self, commit_sha1):
+ """Returns a list of `RevisionStatusReport` for a commit."""
+ return IStore(RevisionStatusReport).find(
+ RevisionStatusReport,
+ commit_sha1=commit_sha1)
+
class RevisionStatusArtifact(StormBase):
__storm_table__ = 'RevisionStatusArtifact'
@@ -672,6 +680,17 @@ class GitRepository(StormBase, WebhookTargetMixin, AccessTokenTargetMixin,
url, result_summary, result)
return report
+ def getStatusReports(self, commit_sha1):
+
+ if not getFeatureFlag(REVISION_STATUS_REPORT_ALLOW_CREATE):
+ raise RevisionStatusReportsFeatureDisabled()
+
+ reports = getUtility(
+ IRevisionStatusReportSet).findRevisionStatusReportsByCommit(
+ commit_sha1)
+ return reports
+
+
@property
def namespace(self):
"""See `IGitRepository`."""
diff --git a/lib/lp/code/model/tests/test_gitrepository.py b/lib/lp/code/model/tests/test_gitrepository.py
index cb100d5..5368614 100644
--- a/lib/lp/code/model/tests/test_gitrepository.py
+++ b/lib/lp/code/model/tests/test_gitrepository.py
@@ -580,7 +580,6 @@ class TestGitRepository(TestCaseWithFactory):
repository = removeSecurityProxy(self.factory.makeGitRepository())
title = self.factory.getUniqueUnicode('report-title')
commit_sha1 = hashlib.sha1(b"Some content").hexdigest()
- lfa = self.factory.makeLibraryFileAlias(db_only=True)
result_summary = "120/120 tests passed"
report = self.factory.makeRevisionStatusReport(
@@ -4288,7 +4287,7 @@ class TestGitRepositoryWebservice(TestCaseWithFactory):
self.assertEqual(401, response.status)
self.assertIn(
- b'You do not have permission to create revision status reports',
+ b'You do not have permission to create/view status reports',
response.body)
def test_newRevisionStatusReport(self):
@@ -4327,6 +4326,52 @@ class TestGitRepositoryWebservice(TestCaseWithFactory):
report.id)),
response.getHeader("Location"))
+ def test_getRevisionStatusReports(self):
+ repository = self.factory.makeGitRepository()
+ requester = repository.owner
+ title = self.factory.getUniqueUnicode('report-title')
+ result_summary = "120/120 tests passed"
+ commit_sha1 = hashlib.sha1(b"First she").hexdigest()
+
+ result_summary2 = "Lint"
+ title2 = "Invalid import in test_file.py"
+
+ report1 = self.factory.makeRevisionStatusReport(
+ user=repository.owner, git_repository=repository,
+ title=title, commit_sha1=commit_sha1,
+ result_summary=result_summary,
+ result=RevisionStatusResult.SUCCEEDED)
+
+ report2 = self.factory.makeRevisionStatusReport(
+ user=repository.owner, git_repository=repository,
+ title=title2, commit_sha1=commit_sha1,
+ result_summary=result_summary2,
+ result=RevisionStatusResult.FAILED)
+
+ webservice = webservice_for_person(None, default_api_version="devel")
+ with person_logged_in(requester):
+ repository_url = api_url(repository)
+
+ secret, _ = self.factory.makeAccessToken(
+ owner=requester, target=repository,
+ scopes=[AccessTokenScope.REPOSITORY_BUILD_STATUS])
+ header = {'Authorization': 'Token %s' % secret}
+
+ self.useFixture(FeatureFixture(
+ {REVISION_STATUS_REPORT_ALLOW_CREATE: "on"}))
+
+ response = webservice.named_get(
+ repository_url, "getStatusReports",
+ headers=header,
+ commit_sha1=commit_sha1)
+ self.assertEqual(200, response.status)
+ with person_logged_in(requester):
+ result = getUtility(
+ IRevisionStatusReportSet).findRevisionStatusReportsByCommit(
+ commit_sha1)
+
+ self.assertEqual(list(result), [report1, report2])
+
def test_set_target(self):
# The repository owner can move the repository to another target;
# this redirects to the new location.