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

Modularize HarbormasterBuildTransaction

Summary: Ref T13072. Update "HarbormasterBuild" to use modern modular transactions.

Test Plan:
- Aborted, restarted, paused, and resumed a build.
- Used `bin/harbormaster restart`.
- Grepped for use of old "::TYPE_COMMAND" constant, didn't find any hits.

Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam

Maniphest Tasks: T13072

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

+162 -191
+5 -1
src/__phutil_library_map__.php
··· 1409 1409 'HarbormasterBuildLogViewController' => 'applications/harbormaster/controller/HarbormasterBuildLogViewController.php', 1410 1410 'HarbormasterBuildMessage' => 'applications/harbormaster/storage/HarbormasterBuildMessage.php', 1411 1411 'HarbormasterBuildMessageQuery' => 'applications/harbormaster/query/HarbormasterBuildMessageQuery.php', 1412 + 'HarbormasterBuildMessageTransaction' => 'applications/harbormaster/xaction/build/HarbormasterBuildMessageTransaction.php', 1412 1413 'HarbormasterBuildPHIDType' => 'applications/harbormaster/phid/HarbormasterBuildPHIDType.php', 1413 1414 'HarbormasterBuildPlan' => 'applications/harbormaster/storage/configuration/HarbormasterBuildPlan.php', 1414 1415 'HarbormasterBuildPlanBehavior' => 'applications/harbormaster/plan/HarbormasterBuildPlanBehavior.php', ··· 1459 1460 'HarbormasterBuildTransaction' => 'applications/harbormaster/storage/HarbormasterBuildTransaction.php', 1460 1461 'HarbormasterBuildTransactionEditor' => 'applications/harbormaster/editor/HarbormasterBuildTransactionEditor.php', 1461 1462 'HarbormasterBuildTransactionQuery' => 'applications/harbormaster/query/HarbormasterBuildTransactionQuery.php', 1463 + 'HarbormasterBuildTransactionType' => 'applications/harbormaster/xaction/build/HarbormasterBuildTransactionType.php', 1462 1464 'HarbormasterBuildUnitMessage' => 'applications/harbormaster/storage/build/HarbormasterBuildUnitMessage.php', 1463 1465 'HarbormasterBuildUnitMessageQuery' => 'applications/harbormaster/query/HarbormasterBuildUnitMessageQuery.php', 1464 1466 'HarbormasterBuildView' => 'applications/harbormaster/view/HarbormasterBuildView.php', ··· 7628 7630 'PhabricatorDestructibleInterface', 7629 7631 ), 7630 7632 'HarbormasterBuildMessageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 7633 + 'HarbormasterBuildMessageTransaction' => 'HarbormasterBuildTransactionType', 7631 7634 'HarbormasterBuildPHIDType' => 'PhabricatorPHIDType', 7632 7635 'HarbormasterBuildPlan' => array( 7633 7636 'HarbormasterDAO', ··· 7698 7701 'HarbormasterBuildTargetPHIDType' => 'PhabricatorPHIDType', 7699 7702 'HarbormasterBuildTargetQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 7700 7703 'HarbormasterBuildTargetSearchEngine' => 'PhabricatorApplicationSearchEngine', 7701 - 'HarbormasterBuildTransaction' => 'PhabricatorApplicationTransaction', 7704 + 'HarbormasterBuildTransaction' => 'PhabricatorModularTransaction', 7702 7705 'HarbormasterBuildTransactionEditor' => 'PhabricatorApplicationTransactionEditor', 7703 7706 'HarbormasterBuildTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 7707 + 'HarbormasterBuildTransactionType' => 'PhabricatorModularTransactionType', 7704 7708 'HarbormasterBuildUnitMessage' => array( 7705 7709 'HarbormasterDAO', 7706 7710 'PhabricatorPolicyInterface',
-88
src/applications/harbormaster/editor/HarbormasterBuildTransactionEditor.php
··· 11 11 return pht('Harbormaster Builds'); 12 12 } 13 13 14 - public function getTransactionTypes() { 15 - $types = parent::getTransactionTypes(); 16 - 17 - $types[] = HarbormasterBuildTransaction::TYPE_COMMAND; 18 - 19 - return $types; 20 - } 21 - 22 - protected function getCustomTransactionOldValue( 23 - PhabricatorLiskDAO $object, 24 - PhabricatorApplicationTransaction $xaction) { 25 - 26 - switch ($xaction->getTransactionType()) { 27 - case HarbormasterBuildTransaction::TYPE_COMMAND: 28 - return null; 29 - } 30 - 31 - return parent::getCustomTransactionOldValue($object, $xaction); 32 - } 33 - 34 - protected function getCustomTransactionNewValue( 35 - PhabricatorLiskDAO $object, 36 - PhabricatorApplicationTransaction $xaction) { 37 - 38 - switch ($xaction->getTransactionType()) { 39 - case HarbormasterBuildTransaction::TYPE_COMMAND: 40 - return $xaction->getNewValue(); 41 - } 42 - 43 - return parent::getCustomTransactionNewValue($object, $xaction); 44 - } 45 - 46 - protected function applyCustomInternalTransaction( 47 - PhabricatorLiskDAO $object, 48 - PhabricatorApplicationTransaction $xaction) { 49 - 50 - switch ($xaction->getTransactionType()) { 51 - case HarbormasterBuildTransaction::TYPE_COMMAND: 52 - return $this->executeBuildCommand($object, $xaction); 53 - } 54 - 55 - return parent::applyCustomInternalTransaction($object, $xaction); 56 - } 57 - 58 - private function executeBuildCommand( 59 - HarbormasterBuild $build, 60 - HarbormasterBuildTransaction $xaction) { 61 - 62 - $actor = $this->getActor(); 63 - $message_type = $xaction->getNewValue(); 64 - 65 - // TODO: Restore logic that tests if the command can issue without causing 66 - // anything to lapse into an invalid state. This should not be the same 67 - // as the logic which powers the web UI: for example, if an "abort" is 68 - // queued we want to disable "Abort" in the web UI, but should obviously 69 - // process it here. 70 - 71 - switch ($message_type) { 72 - case HarbormasterBuildCommand::COMMAND_ABORT: 73 - // TODO: This should move to external effects, perhaps. 74 - $build->releaseAllArtifacts($actor); 75 - $build->setBuildStatus(HarbormasterBuildStatus::STATUS_ABORTED); 76 - break; 77 - case HarbormasterBuildCommand::COMMAND_RESTART: 78 - $build->restartBuild($actor); 79 - $build->setBuildStatus(HarbormasterBuildStatus::STATUS_BUILDING); 80 - break; 81 - case HarbormasterBuildCommand::COMMAND_RESUME: 82 - $build->setBuildStatus(HarbormasterBuildStatus::STATUS_BUILDING); 83 - break; 84 - case HarbormasterBuildCommand::COMMAND_PAUSE: 85 - $build->setBuildStatus(HarbormasterBuildStatus::STATUS_PAUSED); 86 - break; 87 - } 88 - } 89 - 90 - protected function applyCustomExternalTransaction( 91 - PhabricatorLiskDAO $object, 92 - PhabricatorApplicationTransaction $xaction) { 93 - 94 - switch ($xaction->getTransactionType()) { 95 - case HarbormasterBuildTransaction::TYPE_COMMAND: 96 - return; 97 - } 98 - 99 - return parent::applyCustomExternalTransaction($object, $xaction); 100 - } 101 - 102 14 }
+3 -1
src/applications/harbormaster/engine/HarbormasterBuildEngine.php
··· 124 124 125 125 $xactions = array(); 126 126 127 + $message_xaction = HarbormasterBuildMessageTransaction::TRANSACTIONTYPE; 128 + 127 129 $messages = $build->getUnprocessedMessagesForApply(); 128 130 foreach ($messages as $message) { 129 131 $message_type = $message->getType(); 130 132 131 133 $xactions[] = $build->getApplicationTransactionTemplate() 132 134 ->setAuthorPHID($message->getAuthorPHID()) 133 - ->setTransactionType(HarbormasterBuildTransaction::TYPE_COMMAND) 135 + ->setTransactionType($message_xaction) 134 136 ->setNewValue($message_type); 135 137 } 136 138
+19 -31
src/applications/harbormaster/management/HarbormasterManagementRestartWorkflow.php
··· 32 32 33 33 if (!$ids && !$active) { 34 34 throw new PhutilArgumentUsageException( 35 - pht('Use --id or --active to select builds.')); 35 + pht('Use "--id" or "--active" to select builds.')); 36 36 } if ($ids && $active) { 37 37 throw new PhutilArgumentUsageException( 38 - pht('Use one of --id or --active to select builds, but not both.')); 38 + pht('Use one of "--id" or "--active" to select builds, but not both.')); 39 39 } 40 40 41 41 $query = id(new HarbormasterBuildQuery()) ··· 48 48 } 49 49 $builds = $query->execute(); 50 50 51 - $console = PhutilConsole::getConsole(); 52 51 $count = count($builds); 53 52 if (!$count) { 54 - $console->writeOut("%s\n", pht('No builds to restart.')); 53 + $this->logSkip( 54 + pht('SKIP'), 55 + pht('No builds to restart.')); 55 56 return 0; 56 57 } 58 + 57 59 $prompt = pht('Restart %s build(s)?', new PhutilNumber($count)); 58 60 if (!phutil_console_confirm($prompt)) { 59 - $console->writeOut("%s\n", pht('Cancelled.')); 60 - return 1; 61 + throw new ArcanistUserAbortException(); 61 62 } 62 63 63 - $app_phid = id(new PhabricatorHarbormasterApplication())->getPHID(); 64 - $editor = id(new HarbormasterBuildTransactionEditor()) 65 - ->setActor($viewer) 66 - ->setActingAsPHID($app_phid) 67 - ->setContentSource($this->newContentSource()); 68 64 foreach ($builds as $build) { 69 - $console->writeOut( 70 - "<bg:blue> %s </bg> %s\n", 65 + $this->logInfo( 71 66 pht('RESTARTING'), 72 67 pht('Build %d: %s', $build->getID(), $build->getName())); 68 + 73 69 if (!$build->canRestartBuild()) { 74 - $console->writeOut( 75 - "<bg:yellow> %s </bg> %s\n", 70 + $this->logWarn( 76 71 pht('INVALID'), 77 - pht('Cannot be restarted.')); 72 + pht('Build can not be restarted.')); 78 73 continue; 79 74 } 80 - $xactions = array(); 81 - $xactions[] = id(new HarbormasterBuildTransaction()) 82 - ->setTransactionType(HarbormasterBuildTransaction::TYPE_COMMAND) 83 - ->setNewValue(HarbormasterBuildCommand::COMMAND_RESTART); 84 - try { 85 - $editor->applyTransactions($build, $xactions); 86 - } catch (Exception $e) { 87 - $message = phutil_console_wrap($e->getMessage(), 2); 88 - $console->writeOut( 89 - "<bg:red> %s </bg>\n%s\n", 90 - pht('FAILED'), 91 - $message); 92 - continue; 93 - } 94 - $console->writeOut("<bg:green> %s </bg>\n", pht('SUCCESS')); 75 + 76 + $build->sendMessage( 77 + $viewer, 78 + HarbormasterBuildCommand::COMMAND_RESTART); 79 + 80 + $this->logOkay( 81 + pht('QUEUED'), 82 + pht('Sent a restart message to build.')); 95 83 } 96 84 97 85 return 0;
+3 -70
src/applications/harbormaster/storage/HarbormasterBuildTransaction.php
··· 1 1 <?php 2 2 3 3 final class HarbormasterBuildTransaction 4 - extends PhabricatorApplicationTransaction { 5 - 6 - const TYPE_COMMAND = 'harbormaster:build:command'; 4 + extends PhabricatorModularTransaction { 7 5 8 6 public function getApplicationName() { 9 7 return 'harbormaster'; ··· 13 11 return HarbormasterBuildPHIDType::TYPECONST; 14 12 } 15 13 16 - public function getTitle() { 17 - $author_phid = $this->getAuthorPHID(); 18 - 19 - $old = $this->getOldValue(); 20 - $new = $this->getNewValue(); 21 - 22 - switch ($this->getTransactionType()) { 23 - case self::TYPE_COMMAND: 24 - switch ($new) { 25 - case HarbormasterBuildCommand::COMMAND_RESTART: 26 - return pht( 27 - '%s restarted this build.', 28 - $this->renderHandleLink($author_phid)); 29 - case HarbormasterBuildCommand::COMMAND_ABORT: 30 - return pht( 31 - '%s aborted this build.', 32 - $this->renderHandleLink($author_phid)); 33 - case HarbormasterBuildCommand::COMMAND_RESUME: 34 - return pht( 35 - '%s resumed this build.', 36 - $this->renderHandleLink($author_phid)); 37 - case HarbormasterBuildCommand::COMMAND_PAUSE: 38 - return pht( 39 - '%s paused this build.', 40 - $this->renderHandleLink($author_phid)); 41 - } 42 - } 43 - return parent::getTitle(); 14 + public function getBaseTransactionClass() { 15 + return 'HarbormasterBuildTransactionType'; 44 16 } 45 17 46 - public function getIcon() { 47 - $author_phid = $this->getAuthorPHID(); 48 - 49 - $old = $this->getOldValue(); 50 - $new = $this->getNewValue(); 51 - 52 - switch ($this->getTransactionType()) { 53 - case self::TYPE_COMMAND: 54 - switch ($new) { 55 - case HarbormasterBuildCommand::COMMAND_RESTART: 56 - return 'fa-backward'; 57 - case HarbormasterBuildCommand::COMMAND_RESUME: 58 - return 'fa-play'; 59 - case HarbormasterBuildCommand::COMMAND_PAUSE: 60 - return 'fa-pause'; 61 - case HarbormasterBuildCommand::COMMAND_ABORT: 62 - return 'fa-exclamation-triangle'; 63 - } 64 - } 65 - 66 - return parent::getIcon(); 67 - } 68 - 69 - public function getColor() { 70 - $author_phid = $this->getAuthorPHID(); 71 - 72 - $old = $this->getOldValue(); 73 - $new = $this->getNewValue(); 74 - 75 - switch ($this->getTransactionType()) { 76 - case self::TYPE_COMMAND: 77 - switch ($new) { 78 - case HarbormasterBuildCommand::COMMAND_PAUSE: 79 - case HarbormasterBuildCommand::COMMAND_ABORT: 80 - return 'red'; 81 - } 82 - } 83 - return parent::getColor(); 84 - } 85 18 }
+128
src/applications/harbormaster/xaction/build/HarbormasterBuildMessageTransaction.php
··· 1 + <?php 2 + 3 + final class HarbormasterBuildMessageTransaction 4 + extends HarbormasterBuildTransactionType { 5 + 6 + const TRANSACTIONTYPE = 'harbormaster:build:command'; 7 + 8 + public function generateOldValue($object) { 9 + return null; 10 + } 11 + 12 + public function getTitle() { 13 + $new = $this->getNewValue(); 14 + 15 + switch ($new) { 16 + case HarbormasterBuildCommand::COMMAND_RESTART: 17 + return pht( 18 + '%s restarted this build.', 19 + $this->renderAuthor()); 20 + case HarbormasterBuildCommand::COMMAND_ABORT: 21 + return pht( 22 + '%s aborted this build.', 23 + $this->renderAuthor()); 24 + case HarbormasterBuildCommand::COMMAND_RESUME: 25 + return pht( 26 + '%s resumed this build.', 27 + $this->renderAuthor()); 28 + case HarbormasterBuildCommand::COMMAND_PAUSE: 29 + return pht( 30 + '%s paused this build.', 31 + $this->renderAuthor()); 32 + } 33 + 34 + return pht( 35 + '%s issued an unknown command ("%s") to this build.', 36 + $this->renderAuthor(), 37 + $this->renderValue($new)); 38 + } 39 + 40 + public function getIcon() { 41 + $new = $this->getNewValue(); 42 + 43 + switch ($new) { 44 + case HarbormasterBuildCommand::COMMAND_RESTART: 45 + return 'fa-backward'; 46 + case HarbormasterBuildCommand::COMMAND_RESUME: 47 + return 'fa-play'; 48 + case HarbormasterBuildCommand::COMMAND_PAUSE: 49 + return 'fa-pause'; 50 + case HarbormasterBuildCommand::COMMAND_ABORT: 51 + return 'fa-exclamation-triangle'; 52 + default: 53 + return 'fa-question'; 54 + } 55 + } 56 + 57 + public function getColor() { 58 + $new = $this->getNewValue(); 59 + 60 + switch ($new) { 61 + case HarbormasterBuildCommand::COMMAND_PAUSE: 62 + case HarbormasterBuildCommand::COMMAND_ABORT: 63 + return 'red'; 64 + } 65 + 66 + return parent::getColor(); 67 + } 68 + 69 + public function getTransactionTypeForConduit($xaction) { 70 + return 'message'; 71 + } 72 + 73 + public function getFieldValuesForConduit($xaction, $data) { 74 + return array( 75 + 'type' => $xaction->getNewValue(), 76 + ); 77 + } 78 + 79 + public function validateTransactions($object, array $xactions) { 80 + $errors = array(); 81 + 82 + // TODO: Restore logic that tests if the command can issue without causing 83 + // anything to lapse into an invalid state. This should not be the same 84 + // as the logic which powers the web UI: for example, if an "abort" is 85 + // queued we want to disable "Abort" in the web UI, but should obviously 86 + // process it here. 87 + 88 + return $errors; 89 + } 90 + 91 + public function applyInternalEffects($object, $value) { 92 + $actor = $this->getActor(); 93 + $build = $object; 94 + 95 + $new = $this->getNewValue(); 96 + 97 + switch ($new) { 98 + case HarbormasterBuildCommand::COMMAND_ABORT: 99 + $build->setBuildStatus(HarbormasterBuildStatus::STATUS_ABORTED); 100 + break; 101 + case HarbormasterBuildCommand::COMMAND_RESTART: 102 + $build->restartBuild($actor); 103 + $build->setBuildStatus(HarbormasterBuildStatus::STATUS_BUILDING); 104 + break; 105 + case HarbormasterBuildCommand::COMMAND_RESUME: 106 + $build->setBuildStatus(HarbormasterBuildStatus::STATUS_BUILDING); 107 + break; 108 + case HarbormasterBuildCommand::COMMAND_PAUSE: 109 + $build->setBuildStatus(HarbormasterBuildStatus::STATUS_PAUSED); 110 + break; 111 + } 112 + } 113 + 114 + public function applyExternalEffects($object, $value) { 115 + $actor = $this->getActor(); 116 + $build = $object; 117 + 118 + $new = $this->getNewValue(); 119 + 120 + switch ($new) { 121 + case HarbormasterBuildCommand::COMMAND_ABORT: 122 + $build->releaseAllArtifacts($actor); 123 + break; 124 + } 125 + } 126 + 127 + 128 + }
+4
src/applications/harbormaster/xaction/build/HarbormasterBuildTransactionType.php
··· 1 + <?php 2 + 3 + abstract class HarbormasterBuildTransactionType 4 + extends PhabricatorModularTransactionType {}