diff --git a/contrib/buildbot/server.py b/contrib/buildbot/server.py --- a/contrib/buildbot/server.py +++ b/contrib/buildbot/server.py @@ -1051,7 +1051,17 @@ buildConfig = properties.get('env.OS_NAME', 'UNKNOWN') buildName = f"{buildName} ({buildConfig})" - if status == BuildStatus.Failure: + if status == BuildStatus.Success: + # Upon success, we only report if there is a website preview + # available. + preview_url_log = tc.getPreviewUrl(buildId) + if preview_url_log: + msg = phab.createBuildStatusMessage(status, guest_url, buildName) + msg += f"\n{preview_url_log}\n" + + phab.commentOnRevision(revisionPHID, msg, buildName) + + elif status == BuildStatus.Failure: msg = phab.createBuildStatusMessage( status, guest_url, buildName) # We add two newlines to break away from the (IMPORTANT) diff --git a/contrib/buildbot/teamcity_wrapper.py b/contrib/buildbot/teamcity_wrapper.py --- a/contrib/buildbot/teamcity_wrapper.py +++ b/contrib/buildbot/teamcity_wrapper.py @@ -165,6 +165,14 @@ ret += line.decode('utf-8') return ret.replace('\r\n', '\n') + def getPreviewUrl(self, buildId): + try: + return self.get_artifact(buildId, "artifacts.tar.gz!/preview_url.log") + except TeamcityRequestException: + # This is likely a 404 and the log doesn't exist. + pass + return None + def getBuildProblems(self, buildId): endpoint = self.build_url( "app/rest/problemOccurrences", diff --git a/contrib/buildbot/test/test_endpoint_status.py b/contrib/buildbot/test/test_endpoint_status.py --- a/contrib/buildbot/test/test_endpoint_status.py +++ b/contrib/buildbot/test/test_endpoint_status.py @@ -15,13 +15,12 @@ import mock import requests +from build import BuildStatus from phabricator_wrapper import BITCOIN_ABC_REPO from server import BADGE_TC_BASE from teamcity_wrapper import BuildInfo from testutil import AnyWith -from build import BuildStatus - class statusRequestData(test.mocks.fixture.MockData): def __init__(self): @@ -864,6 +863,50 @@ ), }], objectIdentifier='789') + def test_status_preview_available(self): + data = statusRequestData() + data.buildResult = 'success' + data.branch = 'phabricator/diff/456' + + self.teamcity.getPreviewUrl = mock.Mock() + self.teamcity.getPreviewUrl.return_value = "Preview is available at http://127.0.0.1:8080 for the next 10 minutes." + + self.configure_build_info( + properties=test.mocks.teamcity.buildInfo_properties(propsList=[{ + 'name': 'env.OS_NAME', + 'value': 'linux', + }]), + ) + + self.teamcity.session.send.side_effect = [ + test.mocks.teamcity.Response(), + test.mocks.teamcity.Response(), + test.mocks.teamcity.Response(), + ] + + self.phab.differential.revision.edit = mock.Mock() + self.phab.differential.diff.search.return_value = test.mocks.phabricator.Result([{ + 'id': '456', + 'fields': { + 'revisionPHID': '789' + }, + }]) + self.phab.differential.revision.search.return_value = test.mocks.phabricator.differential_revision_search_result() + + response = self.app.post('/status', headers=self.headers, json=data) + self.assertEqual(response.status_code, 200) + build_url = self.teamcity.build_url( + "viewLog.html", + { + "buildTypeId": data.buildTypeId, + "buildId": DEFAULT_BUILD_ID, + } + ) + self.phab.differential.revision.edit.assert_called_with(transactions=[{ + "type": "comment", + "value": f"Build [[{build_url} | build-name (linux)]] passed.\nPreview is available at http://127.0.0.1:8080 for the next 10 minutes.\n", + }], objectIdentifier='789') + def test_status_revision_testsFailed(self): data = statusRequestData() data.branch = 'phabricator/diff/456'