Path: blob/master/src/applications/harbormaster/controller/HarbormasterBuildkiteHookController.php
12256 views
<?php12final class HarbormasterBuildkiteHookController3extends HarbormasterController {45public function shouldRequireLogin() {6return false;7}89/**10* @phutil-external-symbol class PhabricatorStartup11*/12public function handleRequest(AphrontRequest $request) {13$raw_body = PhabricatorStartup::getRawInput();14$body = phutil_json_decode($raw_body);1516$event = idx($body, 'event');17if ($event != 'build.finished') {18return $this->newHookResponse(pht('OK: Ignored event.'));19}2021$build = idx($body, 'build');22if (!is_array($build)) {23throw new Exception(24pht(25'Expected "%s" property to contain a dictionary.',26'build'));27}2829$meta_data = idx($build, 'meta_data');30if (!is_array($meta_data)) {31throw new Exception(32pht(33'Expected "%s" property to contain a dictionary.',34'build.meta_data'));35}3637$target_phid = idx($meta_data, 'buildTargetPHID');38if (!$target_phid) {39return $this->newHookResponse(pht('OK: No Harbormaster target PHID.'));40}4142$viewer = PhabricatorUser::getOmnipotentUser();43$target = id(new HarbormasterBuildTargetQuery())44->setViewer($viewer)45->withPHIDs(array($target_phid))46->needBuildSteps(true)47->executeOne();48if (!$target) {49throw new Exception(50pht(51'Harbormaster build target "%s" does not exist.',52$target_phid));53}5455$step = $target->getBuildStep();56$impl = $step->getStepImplementation();57if (!($impl instanceof HarbormasterBuildkiteBuildStepImplementation)) {58throw new Exception(59pht(60'Harbormaster build target "%s" is not a Buildkite build step. '.61'Only Buildkite steps may be updated via the Buildkite hook.',62$target_phid));63}6465$webhook_token = $impl->getSetting('webhook.token');66$request_token = $request->getHTTPHeader('X-Buildkite-Token');6768if (!phutil_hashes_are_identical($webhook_token, $request_token)) {69throw new Exception(70pht(71'Buildkite request to target "%s" had the wrong authentication '.72'token. The Buildkite pipeline and Harbormaster build step must '.73'be configured with the same token.',74$target_phid));75}7677$state = idx($build, 'state');78switch ($state) {79case 'passed':80$message_type = HarbormasterMessageType::MESSAGE_PASS;81break;82default:83$message_type = HarbormasterMessageType::MESSAGE_FAIL;84break;85}8687$api_method = 'harbormaster.sendmessage';88$api_params = array(89'buildTargetPHID' => $target_phid,90'type' => $message_type,91);9293$unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();9495id(new ConduitCall($api_method, $api_params))96->setUser($viewer)97->execute();9899unset($unguarded);100101return $this->newHookResponse(pht('OK: Processed event.'));102}103104private function newHookResponse($message) {105$response = new AphrontWebpageResponse();106$response->setContent($message);107return $response;108}109110}111112113