public function execute(HarbormasterBuild $build, HarbormasterBuildTarget $build_target) { $viewer = PhabricatorUser::getOmnipotentUser(); $settings = $this->getSettings(); // TODO: We should probably have a separate temporary storage area for // execution stuff that doesn't step on configuration state? $lease_phid = $build_target->getDetail('exec.leasePHID'); if ($lease_phid) { $lease = id(new DrydockLeaseQuery())->setViewer($viewer)->withPHIDs(array($lease_phid))->executeOne(); if (!$lease) { throw new PhabricatorWorkerPermanentFailureException(pht('Lease "%s" could not be loaded.', $lease_phid)); } } else { $working_copy_type = id(new DrydockWorkingCopyBlueprintImplementation())->getType(); $allowed_phids = $build_target->getFieldValue('blueprintPHIDs'); if (!is_array($allowed_phids)) { $allowed_phids = array(); } $authorizing_phid = $build_target->getBuildStep()->getPHID(); $lease = DrydockLease::initializeNewLease()->setResourceType($working_copy_type)->setOwnerPHID($build_target->getPHID())->setAuthorizingPHID($authorizing_phid)->setAllowedBlueprintPHIDs($allowed_phids); $map = $this->buildRepositoryMap($build_target); $lease->setAttribute('repositories.map', $map); $task_id = $this->getCurrentWorkerTaskID(); if ($task_id) { $lease->setAwakenTaskIDs(array($task_id)); } // TODO: Maybe add a method to mark artifacts like this as pending? // Create the artifact now so that the lease is always disposed of, even // if this target is aborted. $build_target->createArtifact($viewer, $settings['name'], HarbormasterWorkingCopyArtifact::ARTIFACTCONST, array('drydockLeasePHID' => $lease->getPHID())); $lease->queueForActivation(); $build_target->setDetail('exec.leasePHID', $lease->getPHID())->save(); } if ($lease->isActivating()) { // TODO: Smart backoff? throw new PhabricatorWorkerYieldException(15); } if (!$lease->isActive()) { // TODO: We could just forget about this lease and retry? throw new PhabricatorWorkerPermanentFailureException(pht('Lease "%s" never activated.', $lease->getPHID())); } }
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(); }