@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Render build status on revisions and commits

Summary:
This uses an event listener to render the status of builds on their buildables. The revision and commit view now renders out the status of each of the builds.

Currently the revision controller has the results for the latest diff rendered out. We might want to show the status of previous diffs in the future, but for now I think the latest diff should do fine.

There's also a number of bug fixes in this diff, including a particularly nasty one where builds would have a build plan PHID generated for them, which resulted in handle lookups always returning invalid objects.

Test Plan: Ran builds against diffs and commits, saw them appear on the revision and commit view controllers.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T1049

Differential Revision: https://secure.phabricator.com/D7544

authored by

James Rhodes and committed by
epriestley
79ef667d fd8d9ff0

+154 -29
+2
src/__phutil_library_map__.php
··· 700 700 'HarbormasterStepAddController' => 'applications/harbormaster/controller/HarbormasterStepAddController.php', 701 701 'HarbormasterStepDeleteController' => 'applications/harbormaster/controller/HarbormasterStepDeleteController.php', 702 702 'HarbormasterStepEditController' => 'applications/harbormaster/controller/HarbormasterStepEditController.php', 703 + 'HarbormasterUIEventListener' => 'applications/harbormaster/event/HarbormasterUIEventListener.php', 703 704 'HeraldAction' => 'applications/herald/storage/HeraldAction.php', 704 705 'HeraldAdapter' => 'applications/herald/adapter/HeraldAdapter.php', 705 706 'HeraldApplyTranscript' => 'applications/herald/storage/transcript/HeraldApplyTranscript.php', ··· 3002 3003 'HarbormasterStepAddController' => 'HarbormasterController', 3003 3004 'HarbormasterStepDeleteController' => 'HarbormasterController', 3004 3005 'HarbormasterStepEditController' => 'HarbormasterController', 3006 + 'HarbormasterUIEventListener' => 'PhabricatorEventListener', 3005 3007 'HeraldAction' => 'HeraldDAO', 3006 3008 'HeraldApplyTranscript' => 'HeraldDAO', 3007 3009 'HeraldCapabilityManageGlobalRules' => 'PhabricatorPolicyCapability',
+6
src/applications/harbormaster/application/PhabricatorApplicationHarbormaster.php
··· 26 26 return self::GROUP_UTILITIES; 27 27 } 28 28 29 + public function getEventListeners() { 30 + return array( 31 + new HarbormasterUIEventListener(), 32 + ); 33 + } 34 + 29 35 public function isBeta() { 30 36 return true; 31 37 }
+15
src/applications/harbormaster/controller/HarbormasterBuildViewController.php
··· 187 187 pht('Status'), 188 188 $this->getStatus($build)); 189 189 190 + $handles = id(new PhabricatorHandleQuery()) 191 + ->setViewer($viewer) 192 + ->withPHIDs(array( 193 + $build->getBuildablePHID(), 194 + $build->getBuildPlanPHID())) 195 + ->execute(); 196 + 197 + $properties->addProperty( 198 + pht('Buildable'), 199 + $handles[$build->getBuildablePHID()]->renderLink()); 200 + 201 + $properties->addProperty( 202 + pht('Build Plan'), 203 + $handles[$build->getBuildPlanPHID()]->renderLink()); 204 + 190 205 } 191 206 192 207 private function getStatus(HarbormasterBuild $build) {
-1
src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
··· 28 28 $builds = id(new HarbormasterBuildQuery()) 29 29 ->setViewer($viewer) 30 30 ->withBuildablePHIDs(array($buildable->getPHID())) 31 - ->needBuildPlans(true) 32 31 ->execute(); 33 32 34 33 $build_list = id(new PHUIObjectItemListView())
+106
src/applications/harbormaster/event/HarbormasterUIEventListener.php
··· 1 + <?php 2 + 3 + final class HarbormasterUIEventListener 4 + extends PhabricatorEventListener { 5 + 6 + public function register() { 7 + $this->listen(PhabricatorEventType::TYPE_UI_WILLRENDERPROPERTIES); 8 + } 9 + 10 + public function handleEvent(PhutilEvent $event) { 11 + switch ($event->getType()) { 12 + case PhabricatorEventType::TYPE_UI_WILLRENDERPROPERTIES: 13 + $this->handlePropertyEvent($event); 14 + break; 15 + } 16 + } 17 + 18 + private function handlePropertyEvent($ui_event) { 19 + $user = $ui_event->getUser(); 20 + $object = $ui_event->getValue('object'); 21 + 22 + if (!$object || !$object->getPHID()) { 23 + // No object, or the object has no PHID yet.. 24 + return; 25 + } 26 + 27 + $target = null; 28 + if ($object instanceof PhabricatorRepositoryCommit) { 29 + $target = $object; 30 + } elseif ($object instanceof DifferentialRevision) { 31 + $target = $object->loadActiveDiff(); 32 + } else { 33 + return; 34 + } 35 + 36 + if (!$this->canUseApplication($ui_event->getUser())) { 37 + return; 38 + } 39 + 40 + $buildables = id(new HarbormasterBuildableQuery()) 41 + ->setViewer($user) 42 + ->withBuildablePHIDs(array($target->getPHID())) 43 + ->execute(); 44 + if (!$buildables) { 45 + return; 46 + } 47 + 48 + $builds = id(new HarbormasterBuildQuery()) 49 + ->setViewer($user) 50 + ->withBuildablePHIDs(mpull($buildables, 'getPHID')) 51 + ->execute(); 52 + if (!$builds) { 53 + return; 54 + } 55 + 56 + $build_handles = id(new PhabricatorHandleQuery()) 57 + ->setViewer($user) 58 + ->withPHIDs(mpull($builds, 'getPHID')) 59 + ->execute(); 60 + 61 + $status_view = new PHUIStatusListView(); 62 + 63 + foreach ($builds as $build) { 64 + $item = new PHUIStatusItemView(); 65 + $item->setTarget( 66 + $build_handles[$build->getPHID()]->renderLink()); 67 + 68 + switch ($build->getBuildStatus()) { 69 + case HarbormasterBuild::STATUS_INACTIVE: 70 + $item->setIcon('open-dark', pht('Inactive')); 71 + break; 72 + case HarbormasterBuild::STATUS_PENDING: 73 + $item->setIcon('open-blue', pht('Pending')); 74 + break; 75 + case HarbormasterBuild::STATUS_WAITING: 76 + $item->setIcon('up-blue', pht('Waiting on Resource')); 77 + break; 78 + case HarbormasterBuild::STATUS_BUILDING: 79 + $item->setIcon('right-blue', pht('Building')); 80 + break; 81 + case HarbormasterBuild::STATUS_PASSED: 82 + $item->setIcon('accept-green', pht('Passed')); 83 + break; 84 + case HarbormasterBuild::STATUS_FAILED: 85 + $item->setIcon('reject-red', pht('Failed')); 86 + break; 87 + case HarbormasterBuild::STATUS_ERROR: 88 + $item->setIcon('minus-red', pht('Unexpected Error')); 89 + break; 90 + case HarbormasterBuild::STATUS_CANCELLED: 91 + $item->setIcon('minus-dark', pht('Cancelled')); 92 + break; 93 + default: 94 + $item->setIcon('question', pht('Unknown')); 95 + break; 96 + } 97 + 98 + 99 + $status_view->addItem($item); 100 + } 101 + 102 + $view = $ui_event->getValue('view'); 103 + $view->addProperty(pht('Build Status'), $status_view); 104 + } 105 + 106 + }
+7 -1
src/applications/harbormaster/phid/HarbormasterPHIDTypeBuild.php
··· 30 30 array $objects) { 31 31 32 32 foreach ($handles as $phid => $handle) { 33 - $build_plan = $objects[$phid]; 33 + $build = $objects[$phid]; 34 + $handles[$phid]->setName(pht( 35 + 'Build %d: %s', 36 + $build->getID(), 37 + $build->getName())); 38 + $handles[$phid]->setURI( 39 + '/harbormaster/build/'.$build->getID()); 34 40 } 35 41 } 36 42
+13 -22
src/applications/harbormaster/query/HarbormasterBuildQuery.php
··· 9 9 private $buildablePHIDs; 10 10 private $buildPlanPHIDs; 11 11 12 - private $needBuildPlans; 13 - 14 12 public function withIDs(array $ids) { 15 13 $this->ids = $ids; 16 14 return $this; ··· 33 31 34 32 public function withBuildPlanPHIDs(array $build_plan_phids) { 35 33 $this->buildPlanPHIDs = $build_plan_phids; 36 - return $this; 37 - } 38 - 39 - public function needBuildPlans($need_plans) { 40 - $this->needBuildPlans = $need_plans; 41 34 return $this; 42 35 } 43 36 ··· 82 75 } 83 76 84 77 protected function didFilterPage(array $page) { 85 - if ($this->needBuildPlans) { 86 - $plans = array(); 78 + $plans = array(); 87 79 88 - $plan_phids = array_filter(mpull($page, 'getBuildPlanPHID')); 89 - if ($plan_phids) { 90 - $plans = id(new PhabricatorObjectQuery()) 91 - ->setViewer($this->getViewer()) 92 - ->withPHIDs($plan_phids) 93 - ->setParentQuery($this) 94 - ->execute(); 95 - $plans = mpull($plans, null, 'getPHID'); 96 - } 80 + $plan_phids = array_filter(mpull($page, 'getBuildPlanPHID')); 81 + if ($plan_phids) { 82 + $plans = id(new PhabricatorObjectQuery()) 83 + ->setViewer($this->getViewer()) 84 + ->withPHIDs($plan_phids) 85 + ->setParentQuery($this) 86 + ->execute(); 87 + $plans = mpull($plans, null, 'getPHID'); 88 + } 97 89 98 - foreach ($page as $key => $build) { 99 - $plan_phid = $build->getBuildPlanPHID(); 100 - $build->attachBuildPlan(idx($plans, $plan_phid)); 101 - } 90 + foreach ($page as $key => $build) { 91 + $plan_phid = $build->getBuildPlanPHID(); 92 + $build->attachBuildPlan(idx($plans, $plan_phid)); 102 93 } 103 94 104 95 return $page;
+4 -3
src/applications/harbormaster/step/VariableBuildStepImplementation.php
··· 16 16 $object = $buildable->getBuildableObject(); 17 17 18 18 $repo = null; 19 - if ($object instanceof DifferentialRevision) { 20 - $results['buildable.revision'] = $object->getID(); 21 - $repo = $object->getRepository(); 19 + if ($object instanceof DifferentialDiff) { 20 + $revision = $object->getRevision(); 21 + $results['buildable.revision'] = $revision->getID(); 22 + $repo = $revision->getRepository(); 22 23 } else if ($object instanceof PhabricatorRepositoryCommit) { 23 24 $results['buildable.commit'] = $object->getCommitIdentifier(); 24 25 $repo = $object->getRepository();
+1 -1
src/applications/harbormaster/storage/build/HarbormasterBuild.php
··· 65 65 66 66 public function generatePHID() { 67 67 return PhabricatorPHID::generateNewPHID( 68 - HarbormasterPHIDTypeBuildPlan::TYPECONST); 68 + HarbormasterPHIDTypeBuild::TYPECONST); 69 69 } 70 70 71 71 public function attachBuildable(HarbormasterBuildable $buildable) {
-1
src/applications/harbormaster/worker/HarbormasterBuildWorker.php
··· 18 18 ->setViewer(PhabricatorUser::getOmnipotentUser()) 19 19 ->withBuildStatuses(array(HarbormasterBuild::STATUS_PENDING)) 20 20 ->withIDs(array($id)) 21 - ->needBuildPlans(true) 22 21 ->executeOne(); 23 22 if (!$build) { 24 23 throw new PhabricatorWorkerPermanentFailureException(