mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 05:50:55 +01:00
Allow entire buildables to restart/stop/resume
Summary: Ref T1049. Creates convenience actions at the Buildable level to stop, resume, or restart all builds. Test Plan: - Stopped all builds. - Resumed all builds. - Restarted all builds. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T1049 Differential Revision: https://secure.phabricator.com/D7899
This commit is contained in:
parent
b952b6f619
commit
46139bd1f6
7 changed files with 195 additions and 13 deletions
|
@ -728,6 +728,7 @@ phutil_register_library_map(array(
|
||||||
'HarbormasterBuildViewController' => 'applications/harbormaster/controller/HarbormasterBuildViewController.php',
|
'HarbormasterBuildViewController' => 'applications/harbormaster/controller/HarbormasterBuildViewController.php',
|
||||||
'HarbormasterBuildWorker' => 'applications/harbormaster/worker/HarbormasterBuildWorker.php',
|
'HarbormasterBuildWorker' => 'applications/harbormaster/worker/HarbormasterBuildWorker.php',
|
||||||
'HarbormasterBuildable' => 'applications/harbormaster/storage/HarbormasterBuildable.php',
|
'HarbormasterBuildable' => 'applications/harbormaster/storage/HarbormasterBuildable.php',
|
||||||
|
'HarbormasterBuildableActionController' => 'applications/harbormaster/controller/HarbormasterBuildableActionController.php',
|
||||||
'HarbormasterBuildableInterface' => 'applications/harbormaster/interface/HarbormasterBuildableInterface.php',
|
'HarbormasterBuildableInterface' => 'applications/harbormaster/interface/HarbormasterBuildableInterface.php',
|
||||||
'HarbormasterBuildableListController' => 'applications/harbormaster/controller/HarbormasterBuildableListController.php',
|
'HarbormasterBuildableListController' => 'applications/harbormaster/controller/HarbormasterBuildableListController.php',
|
||||||
'HarbormasterBuildableQuery' => 'applications/harbormaster/query/HarbormasterBuildableQuery.php',
|
'HarbormasterBuildableQuery' => 'applications/harbormaster/query/HarbormasterBuildableQuery.php',
|
||||||
|
@ -3206,6 +3207,7 @@ phutil_register_library_map(array(
|
||||||
1 => 'PhabricatorPolicyInterface',
|
1 => 'PhabricatorPolicyInterface',
|
||||||
2 => 'HarbormasterBuildableInterface',
|
2 => 'HarbormasterBuildableInterface',
|
||||||
),
|
),
|
||||||
|
'HarbormasterBuildableActionController' => 'HarbormasterController',
|
||||||
'HarbormasterBuildableListController' =>
|
'HarbormasterBuildableListController' =>
|
||||||
array(
|
array(
|
||||||
0 => 'HarbormasterController',
|
0 => 'HarbormasterController',
|
||||||
|
|
|
@ -53,6 +53,10 @@ final class PhabricatorApplicationHarbormaster extends PhabricatorApplication {
|
||||||
'edit/(?:(?P<id>\d+)/)?' => 'HarbormasterStepEditController',
|
'edit/(?:(?P<id>\d+)/)?' => 'HarbormasterStepEditController',
|
||||||
'delete/(?:(?P<id>\d+)/)?' => 'HarbormasterStepDeleteController',
|
'delete/(?:(?P<id>\d+)/)?' => 'HarbormasterStepDeleteController',
|
||||||
),
|
),
|
||||||
|
'buildable/' => array(
|
||||||
|
'(?P<id>\d+)/(?P<action>stop|resume|restart)/'
|
||||||
|
=> 'HarbormasterBuildableActionController',
|
||||||
|
),
|
||||||
'build/' => array(
|
'build/' => array(
|
||||||
'(?:(?P<id>\d+)/)?' => 'HarbormasterBuildViewController',
|
'(?:(?P<id>\d+)/)?' => 'HarbormasterBuildViewController',
|
||||||
'(?P<action>stop|resume|restart)/(?P<id>\d+)/(?:(?P<via>[^/]+)/)?'
|
'(?P<action>stop|resume|restart)/(?P<id>\d+)/(?:(?P<via>[^/]+)/)?'
|
||||||
|
|
|
@ -21,6 +21,11 @@ final class HarbormasterBuildActionController
|
||||||
$build = id(new HarbormasterBuildQuery())
|
$build = id(new HarbormasterBuildQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->withIDs(array($this->id))
|
->withIDs(array($this->id))
|
||||||
|
->requireCapabilities(
|
||||||
|
array(
|
||||||
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
))
|
||||||
->executeOne();
|
->executeOne();
|
||||||
if (!$build) {
|
if (!$build) {
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
|
@ -42,7 +47,7 @@ final class HarbormasterBuildActionController
|
||||||
|
|
||||||
switch ($this->via) {
|
switch ($this->via) {
|
||||||
case 'buildable':
|
case 'buildable':
|
||||||
$return_uri = $build->getBuildable()->getMonogram();
|
$return_uri = '/'.$build->getBuildable()->getMonogram();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$return_uri = $this->getApplicationURI('/build/'.$build->getID().'/');
|
$return_uri = $this->getApplicationURI('/build/'.$build->getID().'/');
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class HarbormasterBuildableActionController
|
||||||
|
extends HarbormasterController {
|
||||||
|
|
||||||
|
private $id;
|
||||||
|
private $action;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->id = $data['id'];
|
||||||
|
$this->action = $data['action'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$viewer = $request->getUser();
|
||||||
|
$command = $this->action;
|
||||||
|
|
||||||
|
$buildable = id(new HarbormasterBuildableQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withIDs(array($this->id))
|
||||||
|
->needBuilds(true)
|
||||||
|
->requireCapabilities(
|
||||||
|
array(
|
||||||
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
|
))
|
||||||
|
->executeOne();
|
||||||
|
if (!$buildable) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$issuable = array();
|
||||||
|
|
||||||
|
foreach ($buildable->getBuilds() as $build) {
|
||||||
|
switch ($command) {
|
||||||
|
case HarbormasterBuildCommand::COMMAND_RESTART:
|
||||||
|
if ($build->canRestartBuild()) {
|
||||||
|
$issuable[] = $build;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HarbormasterBuildCommand::COMMAND_STOP:
|
||||||
|
if ($build->canStopBuild()) {
|
||||||
|
$issuable[] = $build;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HarbormasterBuildCommand::COMMAND_RESUME:
|
||||||
|
if ($build->canResumeBuild()) {
|
||||||
|
$issuable[] = $build;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return new Aphront400Response();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$return_uri = $buildable->getMonogram();
|
||||||
|
if ($request->isDialogFormPost() && $issuable) {
|
||||||
|
foreach ($issuable as $build) {
|
||||||
|
id(new HarbormasterBuildCommand())
|
||||||
|
->setAuthorPHID($viewer->getPHID())
|
||||||
|
->setTargetPHID($build->getPHID())
|
||||||
|
->setCommand($command)
|
||||||
|
->save();
|
||||||
|
|
||||||
|
PhabricatorWorker::scheduleTask(
|
||||||
|
'HarbormasterBuildWorker',
|
||||||
|
array(
|
||||||
|
'buildID' => $build->getID()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return id(new AphrontRedirectResponse())->setURI($return_uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($command) {
|
||||||
|
case HarbormasterBuildCommand::COMMAND_RESTART:
|
||||||
|
if ($issuable) {
|
||||||
|
$title = pht('Really restart all builds?');
|
||||||
|
$body = pht(
|
||||||
|
'Progress on all builds will be discarded, and all builds will '.
|
||||||
|
'restart. Side effects of the builds will occur again. Really '.
|
||||||
|
'restart all builds?');
|
||||||
|
$submit = pht('Restart All Builds');
|
||||||
|
} else {
|
||||||
|
$title = pht('Unable to Restart Build');
|
||||||
|
$body = pht('No builds can be restarted.');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HarbormasterBuildCommand::COMMAND_STOP:
|
||||||
|
if ($issuable) {
|
||||||
|
$title = pht('Really stop all builds?');
|
||||||
|
$body = pht(
|
||||||
|
'If you stop all build, work will halt once the current steps '.
|
||||||
|
'complete. You can resume the builds later.');
|
||||||
|
$submit = pht('Stop All Builds');
|
||||||
|
} else {
|
||||||
|
$title = pht('Unable to Stop Build');
|
||||||
|
$body = pht('No builds can be stopped.');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case HarbormasterBuildCommand::COMMAND_RESUME:
|
||||||
|
if ($issuable) {
|
||||||
|
$title = pht('Really resume all builds?');
|
||||||
|
$body = pht('Work will continue on all builds. Really resume?');
|
||||||
|
$submit = pht('Resume All Builds');
|
||||||
|
} else {
|
||||||
|
$title = pht('Unable to Resume Build');
|
||||||
|
$body = pht('No builds can be resumed.');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dialog = id(new AphrontDialogView())
|
||||||
|
->setUser($viewer)
|
||||||
|
->setTitle($title)
|
||||||
|
->appendChild($body)
|
||||||
|
->addCancelButton($return_uri);
|
||||||
|
|
||||||
|
if ($issuable) {
|
||||||
|
$dialog->addSubmitButton($submit);
|
||||||
|
}
|
||||||
|
|
||||||
|
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -20,19 +20,15 @@ final class HarbormasterBuildableViewController
|
||||||
->withIDs(array($id))
|
->withIDs(array($id))
|
||||||
->needBuildableHandles(true)
|
->needBuildableHandles(true)
|
||||||
->needContainerHandles(true)
|
->needContainerHandles(true)
|
||||||
|
->needBuilds(true)
|
||||||
->executeOne();
|
->executeOne();
|
||||||
if (!$buildable) {
|
if (!$buildable) {
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
}
|
}
|
||||||
|
|
||||||
$builds = id(new HarbormasterBuildQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->withBuildablePHIDs(array($buildable->getPHID()))
|
|
||||||
->execute();
|
|
||||||
|
|
||||||
$build_list = id(new PHUIObjectItemListView())
|
$build_list = id(new PHUIObjectItemListView())
|
||||||
->setUser($viewer);
|
->setUser($viewer);
|
||||||
foreach ($builds as $build) {
|
foreach ($buildable->getBuilds() as $build) {
|
||||||
$view_uri = $this->getApplicationURI('/build/'.$build->getID().'/');
|
$view_uri = $this->getApplicationURI('/build/'.$build->getID().'/');
|
||||||
$item = id(new PHUIObjectItemView())
|
$item = id(new PHUIObjectItemView())
|
||||||
->setObjectName(pht('Build %d', $build->getID()))
|
->setObjectName(pht('Build %d', $build->getID()))
|
||||||
|
@ -152,7 +148,56 @@ final class HarbormasterBuildableViewController
|
||||||
$list = id(new PhabricatorActionListView())
|
$list = id(new PhabricatorActionListView())
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->setObject($buildable)
|
->setObject($buildable)
|
||||||
->setObjectURI("/B{$id}");
|
->setObjectURI($buildable->getMonogram());
|
||||||
|
|
||||||
|
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||||
|
$viewer,
|
||||||
|
$buildable,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT);
|
||||||
|
|
||||||
|
$can_restart = false;
|
||||||
|
$can_resume = false;
|
||||||
|
$can_stop = false;
|
||||||
|
|
||||||
|
foreach ($buildable->getBuilds() as $build) {
|
||||||
|
if ($build->canRestartBuild()) {
|
||||||
|
$can_restart = true;
|
||||||
|
}
|
||||||
|
if ($build->canResumeBuild()) {
|
||||||
|
$can_resume = true;
|
||||||
|
}
|
||||||
|
if ($build->canStopBuild()) {
|
||||||
|
$can_stop = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$restart_uri = "buildable/{$id}/restart/";
|
||||||
|
$stop_uri = "buildable/{$id}/stop/";
|
||||||
|
$resume_uri = "buildable/{$id}/resume/";
|
||||||
|
|
||||||
|
$list->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setIcon('backward')
|
||||||
|
->setName(pht('Restart All Builds'))
|
||||||
|
->setHref($this->getApplicationURI($restart_uri))
|
||||||
|
->setWorkflow(true)
|
||||||
|
->setDisabled(!$can_restart || !$can_edit));
|
||||||
|
|
||||||
|
$list->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setIcon('stop')
|
||||||
|
->setName(pht('Stop All Builds'))
|
||||||
|
->setHref($this->getApplicationURI($stop_uri))
|
||||||
|
->setWorkflow(true)
|
||||||
|
->setDisabled(!$can_stop || !$can_edit));
|
||||||
|
|
||||||
|
$list->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setIcon('play')
|
||||||
|
->setName(pht('Resume All Builds'))
|
||||||
|
->setHref($this->getApplicationURI($resume_uri))
|
||||||
|
->setWorkflow(true)
|
||||||
|
->setDisabled(!$can_resume || !$can_edit));
|
||||||
|
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,6 +177,7 @@ final class HarbormasterBuildable extends HarbormasterDAO
|
||||||
public function getCapabilities() {
|
public function getCapabilities() {
|
||||||
return array(
|
return array(
|
||||||
PhabricatorPolicyCapability::CAN_VIEW,
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,9 +192,7 @@ final class HarbormasterBuildable extends HarbormasterDAO
|
||||||
}
|
}
|
||||||
|
|
||||||
public function describeAutomaticCapability($capability) {
|
public function describeAutomaticCapability($capability) {
|
||||||
return pht(
|
return pht('A buildable inherits policies from the underlying object.');
|
||||||
'Users must be able to see the revision or repository to see a '.
|
|
||||||
'buildable.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -311,6 +311,7 @@ final class HarbormasterBuild extends HarbormasterDAO
|
||||||
public function getCapabilities() {
|
public function getCapabilities() {
|
||||||
return array(
|
return array(
|
||||||
PhabricatorPolicyCapability::CAN_VIEW,
|
PhabricatorPolicyCapability::CAN_VIEW,
|
||||||
|
PhabricatorPolicyCapability::CAN_EDIT,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,8 +326,7 @@ final class HarbormasterBuild extends HarbormasterDAO
|
||||||
}
|
}
|
||||||
|
|
||||||
public function describeAutomaticCapability($capability) {
|
public function describeAutomaticCapability($capability) {
|
||||||
return pht(
|
return pht('A build inherits policies from its buildable.');
|
||||||
'Users must be able to see a buildable to view its build plans.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue