Page MenuHomePhabricator

D14288.id.diff
No OneTemporary

D14288.id.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1108,6 +1108,7 @@
'HarbormasterBuiltinBuildStepGroup' => 'applications/harbormaster/stepgroup/HarbormasterBuiltinBuildStepGroup.php',
'HarbormasterCircleCIBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterCircleCIBuildStepImplementation.php',
'HarbormasterCircleCIBuildableInterface' => 'applications/harbormaster/interface/HarbormasterCircleCIBuildableInterface.php',
+ 'HarbormasterCircleCIHookController' => 'applications/harbormaster/controller/HarbormasterCircleCIHookController.php',
'HarbormasterConduitAPIMethod' => 'applications/harbormaster/conduit/HarbormasterConduitAPIMethod.php',
'HarbormasterController' => 'applications/harbormaster/controller/HarbormasterController.php',
'HarbormasterCreateArtifactConduitAPIMethod' => 'applications/harbormaster/conduit/HarbormasterCreateArtifactConduitAPIMethod.php',
@@ -5338,6 +5339,7 @@
'HarbormasterBuildableViewController' => 'HarbormasterController',
'HarbormasterBuiltinBuildStepGroup' => 'HarbormasterBuildStepGroup',
'HarbormasterCircleCIBuildStepImplementation' => 'HarbormasterBuildStepImplementation',
+ 'HarbormasterCircleCIHookController' => 'HarbormasterController',
'HarbormasterConduitAPIMethod' => 'ConduitAPIMethod',
'HarbormasterController' => 'PhabricatorController',
'HarbormasterCreateArtifactConduitAPIMethod' => 'HarbormasterConduitAPIMethod',
diff --git a/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php b/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php
--- a/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php
+++ b/src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php
@@ -91,6 +91,9 @@
'lint/' => array(
'(?P<id>\d+)/' => 'HarbormasterLintMessagesController',
),
+ 'hook/' => array(
+ 'circleci/' => 'HarbormasterCircleCIHookController',
+ ),
),
);
}
diff --git a/src/applications/harbormaster/controller/HarbormasterCircleCIHookController.php b/src/applications/harbormaster/controller/HarbormasterCircleCIHookController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/harbormaster/controller/HarbormasterCircleCIHookController.php
@@ -0,0 +1,87 @@
+<?php
+
+final class HarbormasterCircleCIHookController
+ extends HarbormasterController {
+
+ public function shouldRequireLogin() {
+ return false;
+ }
+
+ /**
+ * @phutil-external-symbol class PhabricatorStartup
+ */
+ public function handleRequest(AphrontRequest $request) {
+ $raw_body = PhabricatorStartup::getRawInput();
+ $body = phutil_json_decode($raw_body);
+
+ $payload = $body['payload'];
+
+ $parameters = idx($payload, 'build_parameters');
+ if (!$parameters) {
+ $parameters = array();
+ }
+
+ $target_phid = idx($parameters, 'HARBORMASTER_BUILD_TARGET_PHID');
+
+ // NOTE: We'll get callbacks here for builds we triggered, but also for
+ // arbitrary builds the system executes for other reasons. So it's normal
+ // to get some notifications with no Build Target PHID. We just ignore
+ // these under the assumption that they're routine builds caused by events
+ // like branch updates.
+
+ if ($target_phid) {
+ $viewer = PhabricatorUser::getOmnipotentUser();
+ $target = id(new HarbormasterBuildTargetQuery())
+ ->setViewer($viewer)
+ ->withPHIDs(array($target_phid))
+ ->needBuildSteps(true)
+ ->executeOne();
+ if ($target) {
+ $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
+ $this->updateTarget($target, $payload);
+ }
+ }
+
+ $response = new AphrontWebpageResponse();
+ $response->setContent(pht("Request OK\n"));
+ return $response;
+ }
+
+ private function updateTarget(
+ HarbormasterBuildTarget $target,
+ array $payload) {
+
+ $step = $target->getBuildStep();
+ $impl = $step->getStepImplementation();
+ if (!($impl instanceof HarbormasterCircleCIBuildStepImplementation)) {
+ throw new Exception(
+ pht(
+ 'Build target ("%s") has the wrong type of build step. Only '.
+ 'CircleCI build steps may be updated via the CircleCI webhook.',
+ $target->getPHID()));
+ }
+
+ switch (idx($payload, 'status')) {
+ case 'success':
+ case 'fixed':
+ $message_type = HarbormasterMessageType::MESSAGE_PASS;
+ break;
+ default:
+ $message_type = HarbormasterMessageType::MESSAGE_FAIL;
+ break;
+ }
+
+ $viewer = PhabricatorUser::getOmnipotentUser();
+
+ $api_method = 'harbormaster.sendmessage';
+ $api_params = array(
+ 'buildTargetPHID' => $target->getPHID(),
+ 'type' => $message_type,
+ );
+
+ id(new ConduitCall($api_method, $api_params))
+ ->setUser($viewer)
+ ->execute();
+ }
+
+}
diff --git a/src/applications/harbormaster/step/HarbormasterCircleCIBuildStepImplementation.php b/src/applications/harbormaster/step/HarbormasterCircleCIBuildStepImplementation.php
--- a/src/applications/harbormaster/step/HarbormasterCircleCIBuildStepImplementation.php
+++ b/src/applications/harbormaster/step/HarbormasterCircleCIBuildStepImplementation.php
@@ -20,6 +20,9 @@
}
public function getEditInstructions() {
+ $hook_uri = '/harbormaster/hook/circleci/';
+ $hook_uri = PhabricatorEnv::getProductionURI($hook_uri);
+
return pht(<<<EOTEXT
WARNING: This build step is new and experimental!
@@ -38,7 +41,15 @@
Webhook Configuration
=====================
-IMPORTANT: This has not been implemented yet.
+Add this webhook to your `circle.yml` file to make CircleCI report results
+to Harbormaster. Until you install this hook, builds will hang waiting for
+a response from CircleCI.
+
+```lang=yml
+notify:
+ webhooks:
+ - url: %s
+```
Environment
===========
@@ -50,7 +61,8 @@
| `HARBORMASTER_BUILD_TARGET_PHID` | PHID of the Build Target.
EOTEXT
- );
+ ,
+ $hook_uri);
}
public static function getGitHubPath($uri) {
diff --git a/src/applications/harbormaster/storage/HarbormasterBuildMessage.php b/src/applications/harbormaster/storage/HarbormasterBuildMessage.php
--- a/src/applications/harbormaster/storage/HarbormasterBuildMessage.php
+++ b/src/applications/harbormaster/storage/HarbormasterBuildMessage.php
@@ -17,8 +17,13 @@
private $buildTarget = self::ATTACHABLE;
public static function initializeNewMessage(PhabricatorUser $actor) {
+ $actor_phid = $actor->getPHID();
+ if (!$actor_phid) {
+ $actor_phid = id(new PhabricatorHarbormasterApplication())->getPHID();
+ }
+
return id(new HarbormasterBuildMessage())
- ->setAuthorPHID($actor->getPHID())
+ ->setAuthorPHID($actor_phid)
->setIsConsumed(0);
}

File Metadata

Mime Type
text/plain
Expires
Fri, Mar 28, 2:00 PM (1 w, 1 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7591622
Default Alt Text
D14288.id.diff (6 KB)

Event Timeline