1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-29 00:40:57 +01:00

Modularize individual Harbormaster build messages

Summary:
Ref T13072. Further modularize build messages by applying each one in a separate transaction type.

This makes it easier to add new types of messages (although I have no particular plans to do this, offhand) and reduces the amount of switch-boilerplate.

This will probably also simplify validating "harbormaster.sendmessage".

Test Plan:
  - Applied all commands.
  - Ran migration, saw transactions render properly

Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam

Maniphest Tasks: T13072

Differential Revision: https://secure.phabricator.com/D21690
This commit is contained in:
epriestley 2021-07-15 15:07:40 -07:00
parent 6dfea0adad
commit 8bbee92139
8 changed files with 203 additions and 102 deletions

View file

@ -0,0 +1,34 @@
<?php
// See T13072. Turn the old "process a command" transaction into modular
// transactions that each handle one particular type of command.
$xactions_table = new HarbormasterBuildTransaction();
$xactions_conn = $xactions_table->establishConnection('w');
$row_iterator = new LiskRawMigrationIterator(
$xactions_conn,
$xactions_table->getTableName());
$map = array(
'"pause"' => 'message/pause',
'"abort"' => 'message/abort',
'"resume"' => 'message/resume',
'"restart"' => 'message/restart',
);
foreach ($row_iterator as $row) {
if ($row['transactionType'] !== 'harbormaster:build:command') {
continue;
}
$raw_value = $row['newValue'];
if (isset($map[$raw_value])) {
queryfx(
$xactions_conn,
'UPDATE %R SET transactionType = %s WHERE id = %d',
$xactions_table,
$map[$raw_value],
$row['id']);
}
}

View file

@ -1408,7 +1408,11 @@ phutil_register_library_map(array(
'HarbormasterBuildLogView' => 'applications/harbormaster/view/HarbormasterBuildLogView.php',
'HarbormasterBuildLogViewController' => 'applications/harbormaster/controller/HarbormasterBuildLogViewController.php',
'HarbormasterBuildMessage' => 'applications/harbormaster/storage/HarbormasterBuildMessage.php',
'HarbormasterBuildMessageAbortTransaction' => 'applications/harbormaster/xaction/build/HarbormasterBuildMessageAbortTransaction.php',
'HarbormasterBuildMessagePauseTransaction' => 'applications/harbormaster/xaction/build/HarbormasterBuildMessagePauseTransaction.php',
'HarbormasterBuildMessageQuery' => 'applications/harbormaster/query/HarbormasterBuildMessageQuery.php',
'HarbormasterBuildMessageRestartTransaction' => 'applications/harbormaster/xaction/build/HarbormasterBuildMessageRestartTransaction.php',
'HarbormasterBuildMessageResumeTransaction' => 'applications/harbormaster/xaction/build/HarbormasterBuildMessageResumeTransaction.php',
'HarbormasterBuildMessageTransaction' => 'applications/harbormaster/xaction/build/HarbormasterBuildMessageTransaction.php',
'HarbormasterBuildPHIDType' => 'applications/harbormaster/phid/HarbormasterBuildPHIDType.php',
'HarbormasterBuildPlan' => 'applications/harbormaster/storage/configuration/HarbormasterBuildPlan.php',
@ -7629,7 +7633,11 @@ phutil_register_library_map(array(
'PhabricatorPolicyInterface',
'PhabricatorDestructibleInterface',
),
'HarbormasterBuildMessageAbortTransaction' => 'HarbormasterBuildMessageTransaction',
'HarbormasterBuildMessagePauseTransaction' => 'HarbormasterBuildMessageTransaction',
'HarbormasterBuildMessageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'HarbormasterBuildMessageRestartTransaction' => 'HarbormasterBuildMessageTransaction',
'HarbormasterBuildMessageResumeTransaction' => 'HarbormasterBuildMessageTransaction',
'HarbormasterBuildMessageTransaction' => 'HarbormasterBuildTransactionType',
'HarbormasterBuildPHIDType' => 'PhabricatorPHIDType',
'HarbormasterBuildPlan' => array(

View file

@ -124,12 +124,18 @@ final class HarbormasterBuildEngine extends Phobject {
$xactions = array();
$message_xaction = HarbormasterBuildMessageTransaction::TRANSACTIONTYPE;
$messages = $build->getUnprocessedMessagesForApply();
foreach ($messages as $message) {
$message_type = $message->getType();
$message_xaction =
HarbormasterBuildMessageTransaction::getTransactionTypeForMessageType(
$message_type);
if (!$message_xaction) {
continue;
}
$xactions[] = $build->getApplicationTransactionTemplate()
->setAuthorPHID($message->getAuthorPHID())
->setTransactionType($message_xaction)

View file

@ -0,0 +1,41 @@
<?php
final class HarbormasterBuildMessageAbortTransaction
extends HarbormasterBuildMessageTransaction {
const TRANSACTIONTYPE = 'message/abort';
public function getMessageType() {
return 'abort';
}
public function getTitle() {
return pht(
'%s aborted this build.',
$this->renderAuthor());
}
public function getIcon() {
return 'fa-exclamation-triangle';
}
public function getColor() {
return 'red';
}
public function applyInternalEffects($object, $value) {
$actor = $this->getActor();
$build = $object;
$build->setBuildStatus(HarbormasterBuildStatus::STATUS_ABORTED);
}
public function applyExternalEffects($object, $value) {
$actor = $this->getActor();
$build = $object;
$build->releaseAllArtifacts($actor);
}
}

View file

@ -0,0 +1,33 @@
<?php
final class HarbormasterBuildMessagePauseTransaction
extends HarbormasterBuildMessageTransaction {
const TRANSACTIONTYPE = 'message/pause';
public function getMessageType() {
return 'pause';
}
public function getTitle() {
return pht(
'%s paused this build.',
$this->renderAuthor());
}
public function getIcon() {
return 'fa-pause';
}
public function getColor() {
return 'red';
}
public function applyInternalEffects($object, $value) {
$actor = $this->getActor();
$build = $object;
$build->setBuildStatus(HarbormasterBuildStatus::STATUS_PAUSED);
}
}

View file

@ -0,0 +1,30 @@
<?php
final class HarbormasterBuildMessageRestartTransaction
extends HarbormasterBuildMessageTransaction {
const TRANSACTIONTYPE = 'message/restart';
public function getMessageType() {
return 'restart';
}
public function getTitle() {
return pht(
'%s restarted this build.',
$this->renderAuthor());
}
public function getIcon() {
return 'fa-backward';
}
public function applyInternalEffects($object, $value) {
$actor = $this->getActor();
$build = $object;
$build->restartBuild($actor);
$build->setBuildStatus(HarbormasterBuildStatus::STATUS_BUILDING);
}
}

View file

@ -0,0 +1,29 @@
<?php
final class HarbormasterBuildMessageResumeTransaction
extends HarbormasterBuildMessageTransaction {
const TRANSACTIONTYPE = 'message/resume';
public function getMessageType() {
return 'resume';
}
public function getTitle() {
return pht(
'%s resumed this build.',
$this->renderAuthor());
}
public function getIcon() {
return 'fa-play';
}
public function applyInternalEffects($object, $value) {
$actor = $this->getActor();
$build = $object;
$build->setBuildStatus(HarbormasterBuildStatus::STATUS_BUILDING);
}
}

View file

@ -1,81 +1,38 @@
<?php
final class HarbormasterBuildMessageTransaction
abstract class HarbormasterBuildMessageTransaction
extends HarbormasterBuildTransactionType {
const TRANSACTIONTYPE = 'harbormaster:build:command';
public function generateOldValue($object) {
final public function generateOldValue($object) {
return null;
}
public function getTitle() {
$new = $this->getNewValue();
switch ($new) {
case HarbormasterBuildCommand::COMMAND_RESTART:
return pht(
'%s restarted this build.',
$this->renderAuthor());
case HarbormasterBuildCommand::COMMAND_ABORT:
return pht(
'%s aborted this build.',
$this->renderAuthor());
case HarbormasterBuildCommand::COMMAND_RESUME:
return pht(
'%s resumed this build.',
$this->renderAuthor());
case HarbormasterBuildCommand::COMMAND_PAUSE:
return pht(
'%s paused this build.',
$this->renderAuthor());
}
return pht(
'%s issued an unknown command ("%s") to this build.',
$this->renderAuthor(),
$this->renderValue($new));
}
public function getIcon() {
$new = $this->getNewValue();
switch ($new) {
case HarbormasterBuildCommand::COMMAND_RESTART:
return 'fa-backward';
case HarbormasterBuildCommand::COMMAND_RESUME:
return 'fa-play';
case HarbormasterBuildCommand::COMMAND_PAUSE:
return 'fa-pause';
case HarbormasterBuildCommand::COMMAND_ABORT:
return 'fa-exclamation-triangle';
default:
return 'fa-question';
}
}
public function getColor() {
$new = $this->getNewValue();
switch ($new) {
case HarbormasterBuildCommand::COMMAND_PAUSE:
case HarbormasterBuildCommand::COMMAND_ABORT:
return 'red';
}
return parent::getColor();
}
public function getTransactionTypeForConduit($xaction) {
final public function getTransactionTypeForConduit($xaction) {
return 'message';
}
public function getFieldValuesForConduit($xaction, $data) {
final public function getFieldValuesForConduit($xaction, $data) {
return array(
'type' => $xaction->getNewValue(),
);
}
final public static function getTransactionTypeForMessageType($message_type) {
$message_xactions = id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
->execute();
foreach ($message_xactions as $message_xaction) {
if ($message_xaction->getMessageType() === $message_type) {
return $message_xaction->getTransactionTypeConstant();
}
}
return null;
}
abstract public function getMessageType();
public function validateTransactions($object, array $xactions) {
$errors = array();
@ -88,41 +45,4 @@ final class HarbormasterBuildMessageTransaction
return $errors;
}
public function applyInternalEffects($object, $value) {
$actor = $this->getActor();
$build = $object;
$new = $this->getNewValue();
switch ($new) {
case HarbormasterBuildCommand::COMMAND_ABORT:
$build->setBuildStatus(HarbormasterBuildStatus::STATUS_ABORTED);
break;
case HarbormasterBuildCommand::COMMAND_RESTART:
$build->restartBuild($actor);
$build->setBuildStatus(HarbormasterBuildStatus::STATUS_BUILDING);
break;
case HarbormasterBuildCommand::COMMAND_RESUME:
$build->setBuildStatus(HarbormasterBuildStatus::STATUS_BUILDING);
break;
case HarbormasterBuildCommand::COMMAND_PAUSE:
$build->setBuildStatus(HarbormasterBuildStatus::STATUS_PAUSED);
break;
}
}
public function applyExternalEffects($object, $value) {
$actor = $this->getActor();
$build = $object;
$new = $this->getNewValue();
switch ($new) {
case HarbormasterBuildCommand::COMMAND_ABORT:
$build->releaseAllArtifacts($actor);
break;
}
}
}