Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15202159
D20252.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
8 KB
Referenced Files
None
Subscribers
None
D20252.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1443,6 +1443,7 @@
'HarbormasterQueryBuildsConduitAPIMethod' => 'applications/harbormaster/conduit/HarbormasterQueryBuildsConduitAPIMethod.php',
'HarbormasterQueryBuildsSearchEngineAttachment' => 'applications/harbormaster/engineextension/HarbormasterQueryBuildsSearchEngineAttachment.php',
'HarbormasterRemarkupRule' => 'applications/harbormaster/remarkup/HarbormasterRemarkupRule.php',
+ 'HarbormasterRestartException' => 'applications/harbormaster/exception/HarbormasterRestartException.php',
'HarbormasterRunBuildPlansHeraldAction' => 'applications/harbormaster/herald/HarbormasterRunBuildPlansHeraldAction.php',
'HarbormasterSchemaSpec' => 'applications/harbormaster/storage/HarbormasterSchemaSpec.php',
'HarbormasterScratchTable' => 'applications/harbormaster/storage/HarbormasterScratchTable.php',
@@ -7093,6 +7094,7 @@
'HarbormasterQueryBuildsConduitAPIMethod' => 'HarbormasterConduitAPIMethod',
'HarbormasterQueryBuildsSearchEngineAttachment' => 'PhabricatorSearchEngineAttachment',
'HarbormasterRemarkupRule' => 'PhabricatorObjectRemarkupRule',
+ 'HarbormasterRestartException' => 'Exception',
'HarbormasterRunBuildPlansHeraldAction' => 'HeraldAction',
'HarbormasterSchemaSpec' => 'PhabricatorConfigSchemaSpec',
'HarbormasterScratchTable' => 'HarbormasterDAO',
diff --git a/src/applications/harbormaster/constants/HarbormasterBuildStatus.php b/src/applications/harbormaster/constants/HarbormasterBuildStatus.php
--- a/src/applications/harbormaster/constants/HarbormasterBuildStatus.php
+++ b/src/applications/harbormaster/constants/HarbormasterBuildStatus.php
@@ -52,6 +52,10 @@
return ($this->key === self::STATUS_PASSED);
}
+ public function isFailed() {
+ return ($this->key === self::STATUS_FAILED);
+ }
+
/**
* Get a human readable name for a build status constant.
diff --git a/src/applications/harbormaster/controller/HarbormasterBuildActionController.php b/src/applications/harbormaster/controller/HarbormasterBuildActionController.php
--- a/src/applications/harbormaster/controller/HarbormasterBuildActionController.php
+++ b/src/applications/harbormaster/controller/HarbormasterBuildActionController.php
@@ -64,19 +64,13 @@
'restart. Side effects of the build will occur again. Really '.
'restart build?');
$submit = pht('Restart Build');
- } else if (!$build->getBuildPlan()->canRestartBuildPlan()) {
- $title = pht('Not Restartable');
- $body = pht(
- 'The build plan for this build is not restartable, so you '.
- 'can not restart the build.');
} else {
- $title = pht('Unable to Restart Build');
- if ($build->isRestarting()) {
- $body = pht(
- 'This build is already restarting. You can not reissue a '.
- 'restart command to a restarting build.');
- } else {
- $body = pht('You can not restart this build.');
+ try {
+ $build->assertCanRestartBuild();
+ throw new Exception(pht('Expected to be unable to restart build.'));
+ } catch (HarbormasterRestartException $ex) {
+ $title = $ex->getTitle();
+ $body = $ex->getBody();
}
}
break;
diff --git a/src/applications/harbormaster/exception/HarbormasterRestartException.php b/src/applications/harbormaster/exception/HarbormasterRestartException.php
new file mode 100644
--- /dev/null
+++ b/src/applications/harbormaster/exception/HarbormasterRestartException.php
@@ -0,0 +1,33 @@
+<?php
+
+final class HarbormasterRestartException extends Exception {
+
+ private $title;
+ private $body = array();
+
+ public function __construct($title, $body = null) {
+ $this->setTitle($title);
+ $this->appendParagraph($body);
+
+ parent::__construct($title);
+ }
+
+ public function setTitle($title) {
+ $this->title = $title;
+ return $this;
+ }
+
+ public function getTitle() {
+ return $this->title;
+ }
+
+ public function appendParagraph($description) {
+ $this->body[] = $description;
+ return $this;
+ }
+
+ public function getBody() {
+ return $this->body;
+ }
+
+}
diff --git a/src/applications/harbormaster/plan/HarbormasterBuildPlanBehavior.php b/src/applications/harbormaster/plan/HarbormasterBuildPlanBehavior.php
--- a/src/applications/harbormaster/plan/HarbormasterBuildPlanBehavior.php
+++ b/src/applications/harbormaster/plan/HarbormasterBuildPlanBehavior.php
@@ -15,6 +15,7 @@
const BEHAVIOR_RESTARTABLE = 'restartable';
const RESTARTABLE_ALWAYS = 'always';
+ const RESTARTABLE_IF_FAILED = 'failed';
const RESTARTABLE_NEVER = 'never';
const BEHAVIOR_DRAFTS = 'hold-drafts';
@@ -251,6 +252,12 @@
->setIsDefault(true)
->setDescription(
pht('The build may be restarted.')),
+ id(new HarbormasterBuildPlanBehaviorOption())
+ ->setKey(self::RESTARTABLE_IF_FAILED)
+ ->setIcon('fa-times-circle-o yellow')
+ ->setName(pht('If Failed'))
+ ->setDescription(
+ pht('The build may be restarted if it has failed.')),
id(new HarbormasterBuildPlanBehaviorOption())
->setKey(self::RESTARTABLE_NEVER)
->setIcon('fa-times red')
diff --git a/src/applications/harbormaster/storage/build/HarbormasterBuild.php b/src/applications/harbormaster/storage/build/HarbormasterBuild.php
--- a/src/applications/harbormaster/storage/build/HarbormasterBuild.php
+++ b/src/applications/harbormaster/storage/build/HarbormasterBuild.php
@@ -183,6 +183,10 @@
return $this->getBuildStatusObject()->isPassed();
}
+ public function isFailed() {
+ return $this->getBuildStatusObject()->isFailed();
+ }
+
public function getURI() {
$id = $this->getID();
return "/harbormaster/build/{$id}/";
@@ -211,16 +215,60 @@
}
public function canRestartBuild() {
- if ($this->isAutobuild()) {
+ try {
+ $this->assertCanRestartBuild();
+ return true;
+ } catch (HarbormasterRestartException $ex) {
return false;
}
+ }
+
+ public function assertCanRestartBuild() {
+ if ($this->isAutobuild()) {
+ throw new HarbormasterRestartException(
+ pht('Can Not Restart Autobuild'),
+ pht(
+ 'This build can not be restarted because it is an automatic '.
+ 'build.'));
+ }
+ $restartable = HarbormasterBuildPlanBehavior::BEHAVIOR_RESTARTABLE;
$plan = $this->getBuildPlan();
- if (!$plan->canRestartBuildPlan()) {
- return false;
+
+ $option = HarbormasterBuildPlanBehavior::getBehavior($restartable)
+ ->getPlanOption($plan);
+ $option_key = $option->getKey();
+
+ $never_restartable = HarbormasterBuildPlanBehavior::RESTARTABLE_NEVER;
+ $is_never = ($option_key === $never_restartable);
+ if ($is_never) {
+ throw new HarbormasterRestartException(
+ pht('Build Plan Prevents Restart'),
+ pht(
+ 'This build can not be restarted because the build plan is '.
+ 'configured to prevent the build from restarting.'));
+ }
+
+ $failed_restartable = HarbormasterBuildPlanBehavior::RESTARTABLE_IF_FAILED;
+ $is_failed = ($option_key === $failed_restartable);
+ if ($is_failed) {
+ if (!$this->isFailed()) {
+ throw new HarbormasterRestartException(
+ pht('Only Restartable if Failed'),
+ pht(
+ 'This build can not be restarted because the build plan is '.
+ 'configured to prevent the build from restarting unless it '.
+ 'has failed, and it has not failed.'));
+ }
}
- return !$this->isRestarting();
+ if ($this->isRestarting()) {
+ throw new HarbormasterRestartException(
+ pht('Already Restarting'),
+ pht(
+ 'This build is already restarting. You can not reissue a restart '.
+ 'command to a restarting build.'));
+ }
}
public function canPauseBuild() {
diff --git a/src/applications/harbormaster/storage/configuration/HarbormasterBuildPlan.php b/src/applications/harbormaster/storage/configuration/HarbormasterBuildPlan.php
--- a/src/applications/harbormaster/storage/configuration/HarbormasterBuildPlan.php
+++ b/src/applications/harbormaster/storage/configuration/HarbormasterBuildPlan.php
@@ -175,16 +175,6 @@
$capability);
}
- public function canRestartBuildPlan() {
- $restartable = HarbormasterBuildPlanBehavior::BEHAVIOR_RESTARTABLE;
- $is_restartable = HarbormasterBuildPlanBehavior::RESTARTABLE_ALWAYS;
-
- $option = HarbormasterBuildPlanBehavior::getBehavior($restartable)
- ->getPlanOption($this);
-
- return ($option->getKey() === $is_restartable);
- }
-
/* -( PhabricatorSubscribableInterface )----------------------------------- */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 24, 8:53 PM (4 h, 56 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7191552
Default Alt Text
D20252.diff (8 KB)
Attached To
Mode
D20252: Add an "Restartable: If Failed" behavior to Harbormaster build plans
Attached
Detach File
Event Timeline
Log In to Comment