@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.

When publishing buildables in Differential, ignore autobuilds (local lint and unit)

Summary:
Depends on D19280. Ref T13110. Although Harbormaster cares about all builds, Differential does not practically care about local lint and unit results in determining build status.

In Differential, orient publishing around "remote builds" instead of "builds".

This does not yet change any of the draft logic, it just makes the timeline story use newer logic.

Test Plan: Used `bin/harbormaster publish` (with some guard-clause removal) to publish some buildables to revisions without anything crashing.

Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam

Maniphest Tasks: T13110

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

+229 -35
+2
src/__phutil_library_map__.php
··· 530 530 'DifferentialRevisionAffectedFilesHeraldField' => 'applications/differential/herald/DifferentialRevisionAffectedFilesHeraldField.php', 531 531 'DifferentialRevisionAuthorHeraldField' => 'applications/differential/herald/DifferentialRevisionAuthorHeraldField.php', 532 532 'DifferentialRevisionAuthorProjectsHeraldField' => 'applications/differential/herald/DifferentialRevisionAuthorProjectsHeraldField.php', 533 + 'DifferentialRevisionBuildableTransaction' => 'applications/differential/xaction/DifferentialRevisionBuildableTransaction.php', 533 534 'DifferentialRevisionCloseDetailsController' => 'applications/differential/controller/DifferentialRevisionCloseDetailsController.php', 534 535 'DifferentialRevisionCloseTransaction' => 'applications/differential/xaction/DifferentialRevisionCloseTransaction.php', 535 536 'DifferentialRevisionClosedStatusDatasource' => 'applications/differential/typeahead/DifferentialRevisionClosedStatusDatasource.php', ··· 5780 5781 'DifferentialRevisionAffectedFilesHeraldField' => 'DifferentialRevisionHeraldField', 5781 5782 'DifferentialRevisionAuthorHeraldField' => 'DifferentialRevisionHeraldField', 5782 5783 'DifferentialRevisionAuthorProjectsHeraldField' => 'DifferentialRevisionHeraldField', 5784 + 'DifferentialRevisionBuildableTransaction' => 'DifferentialRevisionTransactionType', 5783 5785 'DifferentialRevisionCloseDetailsController' => 'DifferentialController', 5784 5786 'DifferentialRevisionCloseTransaction' => 'DifferentialRevisionActionTransaction', 5785 5787 'DifferentialRevisionClosedStatusDatasource' => 'PhabricatorTypeaheadDatasource',
+54 -1
src/applications/differential/harbormaster/DifferentialBuildableEngine.php
··· 1 1 <?php 2 2 3 3 final class DifferentialBuildableEngine 4 - extends HarbormasterBuildableEngine {} 4 + extends HarbormasterBuildableEngine { 5 + 6 + protected function getPublishableObject() { 7 + $object = $this->getObject(); 8 + 9 + if ($object instanceof DifferentialDiff) { 10 + return $object->getRevision(); 11 + } 12 + 13 + return $object; 14 + } 15 + 16 + public function publishBuildable( 17 + HarbormasterBuildable $old, 18 + HarbormasterBuildable $new) { 19 + 20 + // If we're publishing to a diff that is not actually attached to a 21 + // revision, we have nothing to publish to, so just bail out. 22 + $revision = $this->getPublishableObject(); 23 + if (!$revision) { 24 + return; 25 + } 26 + 27 + // Don't publish manual buildables. 28 + if ($new->getIsManualBuildable()) { 29 + return; 30 + } 31 + 32 + // Don't publish anything if the buildable is still building. Differential 33 + // treats more buildables as "building" than Harbormaster does, but the 34 + // Differential definition is a superset of the Harbormaster definition. 35 + if ($new->isBuilding()) { 36 + return; 37 + } 38 + 39 + $viewer = $this->getViewer(); 40 + 41 + $old_status = $revision->getBuildableStatus($new->getPHID()); 42 + $new_status = $revision->newBuildableStatus($viewer, $new->getPHID()); 43 + if ($old_status === $new_status) { 44 + return; 45 + } 46 + 47 + $buildable_type = DifferentialRevisionBuildableTransaction::TRANSACTIONTYPE; 48 + 49 + $xaction = $this->newTransaction() 50 + ->setMetadataValue('harbormaster:buildablePHID', $new->getPHID()) 51 + ->setTransactionType($buildable_type) 52 + ->setNewValue($new_status); 53 + 54 + $this->applyTransactions(array($xaction)); 55 + } 56 + 57 + }
-4
src/applications/differential/storage/DifferentialDiff.php
··· 509 509 return null; 510 510 } 511 511 512 - public function getHarbormasterPublishablePHID() { 513 - return $this->getHarbormasterContainerPHID(); 514 - } 515 - 516 512 public function getBuildVariables() { 517 513 $results = array(); 518 514
+73 -4
src/applications/differential/storage/DifferentialRevision.php
··· 62 62 const PROPERTY_HAS_BROADCAST = 'draft.broadcast'; 63 63 const PROPERTY_LINES_ADDED = 'lines.added'; 64 64 const PROPERTY_LINES_REMOVED = 'lines.removed'; 65 + const PROPERTY_BUILDABLES = 'buildables'; 65 66 66 67 public static function initializeNewRevision(PhabricatorUser $actor) { 67 68 $app = id(new PhabricatorApplicationQuery()) ··· 740 741 return $this->getProperty(self::PROPERTY_LINES_REMOVED); 741 742 } 742 743 744 + 745 + public function getBuildableStatus($phid) { 746 + $buildables = $this->getProperty(self::PROPERTY_BUILDABLES); 747 + if (!is_array($buildables)) { 748 + $buildables = array(); 749 + } 750 + 751 + $buildable = idx($buildables, $phid); 752 + if (!is_array($buildable)) { 753 + $buildable = array(); 754 + } 755 + 756 + return idx($buildable, 'status'); 757 + } 758 + 759 + public function setBuildableStatus($phid, $status) { 760 + $buildables = $this->getProperty(self::PROPERTY_BUILDABLES); 761 + if (!is_array($buildables)) { 762 + $buildables = array(); 763 + } 764 + 765 + $buildable = idx($buildables, $phid); 766 + if (!is_array($buildable)) { 767 + $buildable = array(); 768 + } 769 + 770 + $buildable['status'] = $status; 771 + 772 + $buildables[$phid] = $buildable; 773 + 774 + return $this->setProperty(self::PROPERTY_BUILDABLES, $buildables); 775 + } 776 + 777 + public function newBuildableStatus(PhabricatorUser $viewer, $phid) { 778 + // For Differential, we're ignoring autobuilds (local lint and unit) 779 + // when computing build status. Differential only cares about remote 780 + // builds when making publishing and undrafting decisions. 781 + 782 + $builds = id(new HarbormasterBuildQuery()) 783 + ->setViewer($viewer) 784 + ->withBuildablePHIDs(array($phid)) 785 + ->withAutobuilds(false) 786 + ->withBuildStatuses( 787 + array( 788 + HarbormasterBuildStatus::STATUS_INACTIVE, 789 + HarbormasterBuildStatus::STATUS_PENDING, 790 + HarbormasterBuildStatus::STATUS_BUILDING, 791 + HarbormasterBuildStatus::STATUS_FAILED, 792 + HarbormasterBuildStatus::STATUS_ABORTED, 793 + HarbormasterBuildStatus::STATUS_ERROR, 794 + HarbormasterBuildStatus::STATUS_PAUSED, 795 + HarbormasterBuildStatus::STATUS_DEADLOCKED, 796 + )) 797 + ->execute(); 798 + 799 + // If we have nothing but passing builds, the buildable passes. 800 + if (!$builds) { 801 + return HarbormasterBuildableStatus::STATUS_PASSED; 802 + } 803 + 804 + // If we have any completed, non-passing builds, the buildable fails. 805 + foreach ($builds as $build) { 806 + $status = $build->getBuildStatusObject(); 807 + if ($status->isComplete()) { 808 + return HarbormasterBuildableStatus::STATUS_FAILED; 809 + } 810 + } 811 + 812 + // Otherwise, we're still waiting for the build to pass or fail. 813 + return null; 814 + } 815 + 743 816 public function loadActiveBuilds(PhabricatorUser $viewer) { 744 817 $diff = $this->getActiveDiff(); 745 818 ··· 785 858 } 786 859 787 860 public function getHarbormasterContainerPHID() { 788 - return $this->getPHID(); 789 - } 790 - 791 - public function getHarbormasterPublishablePHID() { 792 861 return $this->getPHID(); 793 862 } 794 863
+93
src/applications/differential/xaction/DifferentialRevisionBuildableTransaction.php
··· 1 + <?php 2 + 3 + final class DifferentialRevisionBuildableTransaction 4 + extends DifferentialRevisionTransactionType { 5 + 6 + // NOTE: This uses an older constant for compatibility. We should perhaps 7 + // migrate these at some point. 8 + const TRANSACTIONTYPE = 'harbormaster:buildable'; 9 + 10 + public function generateNewValue($object, $value) { 11 + return $value; 12 + } 13 + 14 + public function generateOldValue($object) { 15 + return $object->getBuildableStatus($this->getBuildablePHID()); 16 + } 17 + 18 + public function applyInternalEffects($object, $value) { 19 + $object->setBuildableStatus($this->getBuildablePHID(), $value); 20 + } 21 + 22 + public function getIcon() { 23 + return $this->newBuildableStatus()->getIcon(); 24 + } 25 + 26 + public function getColor() { 27 + return $this->newBuildableStatus()->getColor(); 28 + } 29 + 30 + public function getActionName() { 31 + return $this->newBuildableStatus()->getActionName(); 32 + } 33 + 34 + public function shouldHideForFeed() { 35 + return !$this->newBuildableStatus()->isFailed(); 36 + } 37 + 38 + public function shouldHideForMail() { 39 + return !$this->newBuildableStatus()->isFailed(); 40 + } 41 + 42 + public function getTitle() { 43 + $new = $this->getNewValue(); 44 + $buildable_phid = $this->getBuildablePHID(); 45 + 46 + switch ($new) { 47 + case HarbormasterBuildableStatus::STATUS_PASSED: 48 + return pht( 49 + '%s completed remote builds in %s.', 50 + $this->renderAuthor(), 51 + $this->renderHandle($buildable_phid)); 52 + case HarbormasterBuildableStatus::STATUS_FAILED: 53 + return pht( 54 + '%s failed remote builds in %s!', 55 + $this->renderAuthor(), 56 + $this->renderHandle($buildable_phid)); 57 + } 58 + 59 + return null; 60 + } 61 + 62 + public function getTitleForFeed() { 63 + $new = $this->getNewValue(); 64 + $buildable_phid = $this->getBuildablePHID(); 65 + 66 + switch ($new) { 67 + case HarbormasterBuildableStatus::STATUS_PASSED: 68 + return pht( 69 + '%s completed remote builds in %s for %s.', 70 + $this->renderAuthor(), 71 + $this->renderHandle($buildable_phid), 72 + $this->renderObject()); 73 + case HarbormasterBuildableStatus::STATUS_FAILED: 74 + return pht( 75 + '%s failed remote builds in %s for %s!', 76 + $this->renderAuthor(), 77 + $this->renderHandle($buildable_phid), 78 + $this->renderObject()); 79 + } 80 + 81 + return null; 82 + } 83 + 84 + private function newBuildableStatus() { 85 + $new = $this->getNewValue(); 86 + return HarbormasterBuildableStatus::newBuildableStatusObject($new); 87 + } 88 + 89 + private function getBuildablePHID() { 90 + return $this->getMetadataValue('harbormaster:buildablePHID'); 91 + } 92 + 93 + }
+7 -3
src/applications/harbormaster/engine/HarbormasterBuildableEngine.php
··· 45 45 return $this->object; 46 46 } 47 47 48 + protected function getPublishableObject() { 49 + return $this->getObject(); 50 + } 51 + 48 52 public function publishBuildable( 49 53 HarbormasterBuildable $old, 50 54 HarbormasterBuildable $new) { ··· 60 64 } 61 65 62 66 final protected function newEditor() { 63 - $publishable = $this->getObject(); 67 + $publishable = $this->getPublishableObject(); 64 68 65 69 $viewer = $this->getViewer(); 66 70 ··· 83 87 } 84 88 85 89 final protected function newTransaction() { 86 - $publishable = $this->getObject(); 90 + $publishable = $this->getPublishableObject(); 87 91 88 92 return $publishable->getApplicationTransactionTemplate(); 89 93 } 90 94 91 95 final protected function applyTransactions(array $xactions) { 92 - $publishable = $this->getObject(); 96 + $publishable = $this->getPublishableObject(); 93 97 $editor = $this->newEditor(); 94 98 95 99 $editor->applyTransactions(
-15
src/applications/harbormaster/interface/HarbormasterBuildableInterface.php
··· 18 18 public function getHarbormasterBuildablePHID(); 19 19 public function getHarbormasterContainerPHID(); 20 20 21 - 22 - /** 23 - * Get the object PHID which build status should be published to. 24 - * 25 - * In some cases (like commits), this is the object itself. In other cases, 26 - * it is a different object: for example, diffs publish builds to revisions. 27 - * 28 - * This method can return `null` to disable publishing. 29 - * 30 - * @return phid|null Build status updates will be published to this object's 31 - * transaction timeline. 32 - */ 33 - public function getHarbormasterPublishablePHID(); 34 - 35 - 36 21 public function getBuildVariables(); 37 22 public function getAvailableBuildVariables(); 38 23
-4
src/applications/harbormaster/storage/HarbormasterBuildable.php
··· 333 333 return $this->getContainerPHID(); 334 334 } 335 335 336 - public function getHarbormasterPublishablePHID() { 337 - return $this->getBuildableObject()->getHarbormasterPublishablePHID(); 338 - } 339 - 340 336 public function getBuildVariables() { 341 337 return array(); 342 338 }
-4
src/applications/repository/storage/PhabricatorRepositoryCommit.php
··· 517 517 return $this->getRepository()->getPHID(); 518 518 } 519 519 520 - public function getHarbormasterPublishablePHID() { 521 - return $this->getPHID(); 522 - } 523 - 524 520 public function getBuildVariables() { 525 521 $results = array(); 526 522