mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 00:32:42 +01:00
Formalize "manual" buildables in Harbormaster
Summary: Ref T1049. Generally, it's useful to separate test/trial/manual runs from production/automatic runs. For example, you don't want to email a bunch of people that the build is broken just because you messed something up when writing a new build plan. You'd rather try it first, then promote it into production once you have some good runs. Similarly, test runs generally should not affect the outside world, etc. Finally, some build steps (like "wait for other buildables") may want to behave differently when run in production/automation than when run in a testing environment (where they should probably continue immediately). So, formalize the distinction between automatic buildables (those created passively by the system in response to events) and manual buildables (those created explicitly by users). Add filtering, and stop the automated parts of the system from interacting with the manual parts (for example, we won't show manual results on revisions). This also moves the "Apply Build Plan" to a third, new home: instead of the sidebar or Buildables, it's now on plans. I think this generally makes more sense given how things have developed. Broadly, this improves isolation of test environments. Test Plan: Created some builds, browsed around, used filters, etc. Reviewers: btrahan Reviewed By: btrahan CC: aran Maniphest Tasks: T1049 Differential Revision: https://secure.phabricator.com/D7824
This commit is contained in:
parent
4a56e26a67
commit
ac19c55822
14 changed files with 175 additions and 235 deletions
6
resources/sql/patches/20131224.harbormanual.sql
Normal file
6
resources/sql/patches/20131224.harbormanual.sql
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_buildable
|
||||||
|
ADD isManualBuildable BOOL NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_buildable
|
||||||
|
ADD KEY `key_manual` (isManualBuildable);
|
||||||
|
|
|
@ -707,8 +707,6 @@ 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',
|
||||||
'HarbormasterBuildableApplyController' => 'applications/harbormaster/controller/HarbormasterBuildableApplyController.php',
|
|
||||||
'HarbormasterBuildableEditController' => 'applications/harbormaster/controller/HarbormasterBuildableEditController.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',
|
||||||
'HarbormasterBuildableSearchEngine' => 'applications/harbormaster/query/HarbormasterBuildableSearchEngine.php',
|
'HarbormasterBuildableSearchEngine' => 'applications/harbormaster/query/HarbormasterBuildableSearchEngine.php',
|
||||||
|
@ -730,6 +728,7 @@ phutil_register_library_map(array(
|
||||||
'HarbormasterPlanEditController' => 'applications/harbormaster/controller/HarbormasterPlanEditController.php',
|
'HarbormasterPlanEditController' => 'applications/harbormaster/controller/HarbormasterPlanEditController.php',
|
||||||
'HarbormasterPlanListController' => 'applications/harbormaster/controller/HarbormasterPlanListController.php',
|
'HarbormasterPlanListController' => 'applications/harbormaster/controller/HarbormasterPlanListController.php',
|
||||||
'HarbormasterPlanOrderController' => 'applications/harbormaster/controller/HarbormasterPlanOrderController.php',
|
'HarbormasterPlanOrderController' => 'applications/harbormaster/controller/HarbormasterPlanOrderController.php',
|
||||||
|
'HarbormasterPlanRunController' => 'applications/harbormaster/controller/HarbormasterPlanRunController.php',
|
||||||
'HarbormasterPlanViewController' => 'applications/harbormaster/controller/HarbormasterPlanViewController.php',
|
'HarbormasterPlanViewController' => 'applications/harbormaster/controller/HarbormasterPlanViewController.php',
|
||||||
'HarbormasterRemarkupRule' => 'applications/harbormaster/remarkup/HarbormasterRemarkupRule.php',
|
'HarbormasterRemarkupRule' => 'applications/harbormaster/remarkup/HarbormasterRemarkupRule.php',
|
||||||
'HarbormasterScratchTable' => 'applications/harbormaster/storage/HarbormasterScratchTable.php',
|
'HarbormasterScratchTable' => 'applications/harbormaster/storage/HarbormasterScratchTable.php',
|
||||||
|
@ -3133,8 +3132,6 @@ phutil_register_library_map(array(
|
||||||
0 => 'HarbormasterDAO',
|
0 => 'HarbormasterDAO',
|
||||||
1 => 'PhabricatorPolicyInterface',
|
1 => 'PhabricatorPolicyInterface',
|
||||||
),
|
),
|
||||||
'HarbormasterBuildableApplyController' => 'HarbormasterController',
|
|
||||||
'HarbormasterBuildableEditController' => 'HarbormasterController',
|
|
||||||
'HarbormasterBuildableListController' =>
|
'HarbormasterBuildableListController' =>
|
||||||
array(
|
array(
|
||||||
0 => 'HarbormasterController',
|
0 => 'HarbormasterController',
|
||||||
|
@ -3164,6 +3161,7 @@ phutil_register_library_map(array(
|
||||||
1 => 'PhabricatorApplicationSearchResultsControllerInterface',
|
1 => 'PhabricatorApplicationSearchResultsControllerInterface',
|
||||||
),
|
),
|
||||||
'HarbormasterPlanOrderController' => 'HarbormasterController',
|
'HarbormasterPlanOrderController' => 'HarbormasterController',
|
||||||
|
'HarbormasterPlanRunController' => 'HarbormasterController',
|
||||||
'HarbormasterPlanViewController' => 'HarbormasterPlanController',
|
'HarbormasterPlanViewController' => 'HarbormasterPlanController',
|
||||||
'HarbormasterRemarkupRule' => 'PhabricatorRemarkupRuleObject',
|
'HarbormasterRemarkupRule' => 'PhabricatorRemarkupRuleObject',
|
||||||
'HarbormasterScratchTable' => 'HarbormasterDAO',
|
'HarbormasterScratchTable' => 'HarbormasterDAO',
|
||||||
|
|
|
@ -48,10 +48,6 @@ final class PhabricatorApplicationHarbormaster extends PhabricatorApplication {
|
||||||
'/harbormaster/' => array(
|
'/harbormaster/' => array(
|
||||||
'(?:query/(?P<queryKey>[^/]+)/)?'
|
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||||
=> 'HarbormasterBuildableListController',
|
=> 'HarbormasterBuildableListController',
|
||||||
'buildable/' => array(
|
|
||||||
'edit/(?:(?P<id>\d+)/)?' => 'HarbormasterBuildableEditController',
|
|
||||||
'apply/(?:(?P<id>\d+)/)?' => 'HarbormasterBuildableApplyController',
|
|
||||||
),
|
|
||||||
'step/' => array(
|
'step/' => array(
|
||||||
'add/(?:(?P<id>\d+)/)?' => 'HarbormasterStepAddController',
|
'add/(?:(?P<id>\d+)/)?' => 'HarbormasterStepAddController',
|
||||||
'edit/(?:(?P<id>\d+)/)?' => 'HarbormasterStepEditController',
|
'edit/(?:(?P<id>\d+)/)?' => 'HarbormasterStepEditController',
|
||||||
|
@ -67,6 +63,7 @@ final class PhabricatorApplicationHarbormaster extends PhabricatorApplication {
|
||||||
'edit/(?:(?P<id>\d+)/)?' => 'HarbormasterPlanEditController',
|
'edit/(?:(?P<id>\d+)/)?' => 'HarbormasterPlanEditController',
|
||||||
'order/(?:(?P<id>\d+)/)?' => 'HarbormasterPlanOrderController',
|
'order/(?:(?P<id>\d+)/)?' => 'HarbormasterPlanOrderController',
|
||||||
'disable/(?P<id>\d+)/' => 'HarbormasterPlanDisableController',
|
'disable/(?P<id>\d+)/' => 'HarbormasterPlanDisableController',
|
||||||
|
'run/(?P<id>\d+)/' => 'HarbormasterPlanRunController',
|
||||||
'(?P<id>\d+)/' => 'HarbormasterPlanViewController',
|
'(?P<id>\d+)/' => 'HarbormasterPlanViewController',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class HarbormasterBuildableApplyController
|
|
||||||
extends HarbormasterController {
|
|
||||||
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
|
||||||
$this->id = $data['id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processRequest() {
|
|
||||||
$request = $this->getRequest();
|
|
||||||
$viewer = $request->getUser();
|
|
||||||
|
|
||||||
$id = $this->id;
|
|
||||||
|
|
||||||
$buildable = id(new HarbormasterBuildableQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->withIDs(array($id))
|
|
||||||
->executeOne();
|
|
||||||
if ($buildable === null) {
|
|
||||||
throw new Exception("Buildable not found!");
|
|
||||||
}
|
|
||||||
|
|
||||||
$buildable_uri = '/B'.$buildable->getID();
|
|
||||||
|
|
||||||
if ($request->isDialogFormPost()) {
|
|
||||||
$plan = id(new HarbormasterBuildPlanQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->withIDs(array($request->getInt('build-plan')))
|
|
||||||
->executeOne();
|
|
||||||
|
|
||||||
HarbormasterBuildable::applyBuildPlans(
|
|
||||||
$buildable->getBuildablePHID(),
|
|
||||||
$buildable->getContainerPHID(),
|
|
||||||
array($plan->getPHID()));
|
|
||||||
|
|
||||||
return id(new AphrontRedirectResponse())->setURI($buildable_uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
$plans = id(new HarbormasterBuildPlanQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->execute();
|
|
||||||
|
|
||||||
$options = array();
|
|
||||||
foreach ($plans as $plan) {
|
|
||||||
$options[$plan->getID()] = $plan->getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: I'd really like to use the dialog that "Edit Differential
|
|
||||||
// Revisions" uses, but that code is quite hard-coded for the particular
|
|
||||||
// uses, so for now we just give a single dropdown.
|
|
||||||
|
|
||||||
$dialog = new AphrontDialogView();
|
|
||||||
$dialog->setTitle(pht('Apply which plan?'))
|
|
||||||
->setUser($viewer)
|
|
||||||
->addSubmitButton(pht('Apply'))
|
|
||||||
->addCancelButton($buildable_uri);
|
|
||||||
$dialog->appendChild(
|
|
||||||
phutil_tag(
|
|
||||||
'p',
|
|
||||||
array(),
|
|
||||||
pht(
|
|
||||||
'Select what build plan you want to apply to this buildable:')));
|
|
||||||
$dialog->appendChild(
|
|
||||||
id(new AphrontFormSelectControl())
|
|
||||||
->setUser($viewer)
|
|
||||||
->setName('build-plan')
|
|
||||||
->setOptions($options));
|
|
||||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,140 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class HarbormasterBuildableEditController
|
|
||||||
extends HarbormasterController {
|
|
||||||
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
|
||||||
$this->id = idx($data, 'id');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processRequest() {
|
|
||||||
$request = $this->getRequest();
|
|
||||||
$viewer = $request->getUser();
|
|
||||||
|
|
||||||
$this->requireApplicationCapability(
|
|
||||||
HarbormasterCapabilityManagePlans::CAPABILITY);
|
|
||||||
|
|
||||||
if ($this->id) {
|
|
||||||
$buildable = id(new HarbormasterBuildableQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->withIDs(array($this->id))
|
|
||||||
->executeOne();
|
|
||||||
if (!$buildable) {
|
|
||||||
return new Aphront404Response();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$buildable = HarbormasterBuildable::initializeNewBuildable($viewer);
|
|
||||||
}
|
|
||||||
|
|
||||||
$e_name = true;
|
|
||||||
$v_name = null;
|
|
||||||
|
|
||||||
$errors = array();
|
|
||||||
if ($request->isFormPost()) {
|
|
||||||
$v_name = $request->getStr('buildablePHID');
|
|
||||||
|
|
||||||
if ($v_name) {
|
|
||||||
$object = id(new PhabricatorObjectQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->withNames(array($v_name))
|
|
||||||
->executeOne();
|
|
||||||
|
|
||||||
if ($object instanceof DifferentialRevision) {
|
|
||||||
$revision = $object;
|
|
||||||
$object = $object->loadActiveDiff();
|
|
||||||
$buildable
|
|
||||||
->setBuildablePHID($object->getPHID())
|
|
||||||
->setContainerPHID($revision->getPHID());
|
|
||||||
} else if ($object instanceof PhabricatorRepositoryCommit) {
|
|
||||||
$buildable
|
|
||||||
->setBuildablePHID($object->getPHID())
|
|
||||||
->setContainerPHID($object->getRepository()->getPHID());
|
|
||||||
} else {
|
|
||||||
$e_name = pht('Invalid');
|
|
||||||
$errors[] = pht('Enter the name of a revision or commit.');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$e_name = pht('Required');
|
|
||||||
$errors[] = pht('You must choose a revision or commit to build.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$errors) {
|
|
||||||
$buildable->save();
|
|
||||||
|
|
||||||
$buildable_uri = '/B'.$buildable->getID();
|
|
||||||
return id(new AphrontRedirectResponse())->setURI($buildable_uri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($errors) {
|
|
||||||
$errors = id(new AphrontErrorView())->setErrors($errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
$is_new = (!$buildable->getID());
|
|
||||||
if ($is_new) {
|
|
||||||
$title = pht('New Buildable');
|
|
||||||
$cancel_uri = $this->getApplicationURI();
|
|
||||||
$save_button = pht('Create Buildable');
|
|
||||||
} else {
|
|
||||||
$id = $buildable->getID();
|
|
||||||
|
|
||||||
$title = pht('Edit Buildable');
|
|
||||||
$cancel_uri = "/B{$id}";
|
|
||||||
$save_button = pht('Save Buildable');
|
|
||||||
}
|
|
||||||
|
|
||||||
$form = id(new AphrontFormView())
|
|
||||||
->setUser($viewer);
|
|
||||||
|
|
||||||
if ($is_new) {
|
|
||||||
$form
|
|
||||||
->appendRemarkupInstructions(
|
|
||||||
pht(
|
|
||||||
'Enter the name of a commit or revision, like `rX123456789` '.
|
|
||||||
'or `D123`.'))
|
|
||||||
->appendChild(
|
|
||||||
id(new AphrontFormTextControl())
|
|
||||||
->setLabel('Buildable Name')
|
|
||||||
->setName('buildablePHID')
|
|
||||||
->setError($e_name)
|
|
||||||
->setValue($v_name));
|
|
||||||
} else {
|
|
||||||
$form->appendChild(
|
|
||||||
id(new AphrontFormMarkupControl())
|
|
||||||
->setLabel(pht('Buildable'))
|
|
||||||
->setValue($buildable->getBuildableHandle()->renderLink()));
|
|
||||||
}
|
|
||||||
|
|
||||||
$form->appendChild(
|
|
||||||
id(new AphrontFormSubmitControl())
|
|
||||||
->setValue($save_button)
|
|
||||||
->addCancelButton($cancel_uri));
|
|
||||||
|
|
||||||
$box = id(new PHUIObjectBoxView())
|
|
||||||
->setHeaderText($title)
|
|
||||||
->setFormError($errors)
|
|
||||||
->setForm($form);
|
|
||||||
|
|
||||||
$crumbs = $this->buildApplicationCrumbs();
|
|
||||||
if ($is_new) {
|
|
||||||
$crumbs->addTextCrumb(pht('New Buildable'));
|
|
||||||
} else {
|
|
||||||
$id = $buildable->getID();
|
|
||||||
$crumbs->addTextCrumb("B{$id}", "/B{$id}");
|
|
||||||
$crumbs->addTextCrumb(pht('Edit'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->buildApplicationPage(
|
|
||||||
array(
|
|
||||||
$crumbs,
|
|
||||||
$box,
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'title' => $title,
|
|
||||||
'device' => true,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -44,8 +44,14 @@ final class HarbormasterBuildableListController
|
||||||
$item->setHref("/B{$id}");
|
$item->setHref("/B{$id}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($buildable->getIsManualBuildable()) {
|
||||||
|
$item->addIcon('wrench-grey', pht('Manual'));
|
||||||
|
}
|
||||||
|
|
||||||
$list->addItem($item);
|
$list->addItem($item);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: This is proof-of-concept for getting meaningful status
|
// TODO: This is proof-of-concept for getting meaningful status
|
||||||
// information into this list, and should get an improvement pass
|
// information into this list, and should get an improvement pass
|
||||||
// once we're a little farther along.
|
// once we're a little farther along.
|
||||||
|
@ -86,8 +92,7 @@ final class HarbormasterBuildableListController
|
||||||
$nav->addFilter('new/', pht('New Build Plan'));
|
$nav->addFilter('new/', pht('New Build Plan'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$nav->addLabel('Utilities');
|
$nav->addLabel(pht('Build Plans'));
|
||||||
$nav->addFilter('buildable/edit/', pht('New Manual Build'));
|
|
||||||
$nav->addFilter('plan/', pht('Manage Build Plans'));
|
$nav->addFilter('plan/', pht('Manage Build Plans'));
|
||||||
|
|
||||||
$nav->selectFilter(null);
|
$nav->selectFilter(null);
|
||||||
|
|
|
@ -118,15 +118,6 @@ final class HarbormasterBuildableViewController
|
||||||
->setObject($buildable)
|
->setObject($buildable)
|
||||||
->setObjectURI("/B{$id}");
|
->setObjectURI("/B{$id}");
|
||||||
|
|
||||||
$apply_uri = $this->getApplicationURI('/buildable/apply/'.$id.'/');
|
|
||||||
|
|
||||||
$list->addAction(
|
|
||||||
id(new PhabricatorActionView())
|
|
||||||
->setName(pht('Apply Build Plan'))
|
|
||||||
->setIcon('edit')
|
|
||||||
->setHref($apply_uri)
|
|
||||||
->setWorkflow(true));
|
|
||||||
|
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,6 +144,12 @@ final class HarbormasterBuildableViewController
|
||||||
$buildable->getContainerHandle()->renderLink());
|
$buildable->getContainerHandle()->renderLink());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$properties->addProperty(
|
||||||
|
pht('Origin'),
|
||||||
|
$buildable->getIsManualBuildable()
|
||||||
|
? pht('Manual Buildable')
|
||||||
|
: pht('Automatic Buildable'));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class HarbormasterPlanRunController
|
||||||
|
extends HarbormasterController {
|
||||||
|
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->id = $data['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$viewer = $request->getUser();
|
||||||
|
|
||||||
|
$this->requireApplicationCapability(
|
||||||
|
HarbormasterCapabilityManagePlans::CAPABILITY);
|
||||||
|
|
||||||
|
$plan_id = $this->id;
|
||||||
|
$plan = id(new HarbormasterBuildPlanQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withIDs(array($plan_id))
|
||||||
|
->executeOne();
|
||||||
|
if (!$plan) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$e_name = true;
|
||||||
|
$v_name = null;
|
||||||
|
|
||||||
|
$errors = array();
|
||||||
|
if ($request->isFormPost()) {
|
||||||
|
$buildable = HarbormasterBuildable::initializeNewBuildable($viewer)
|
||||||
|
->setIsManualBuildable(true);
|
||||||
|
|
||||||
|
$v_name = $request->getStr('buildablePHID');
|
||||||
|
|
||||||
|
if ($v_name) {
|
||||||
|
$object = id(new PhabricatorObjectQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withNames(array($v_name))
|
||||||
|
->executeOne();
|
||||||
|
|
||||||
|
if ($object instanceof DifferentialRevision) {
|
||||||
|
$revision = $object;
|
||||||
|
$object = $object->loadActiveDiff();
|
||||||
|
$buildable
|
||||||
|
->setBuildablePHID($object->getPHID())
|
||||||
|
->setContainerPHID($revision->getPHID());
|
||||||
|
} else if ($object instanceof PhabricatorRepositoryCommit) {
|
||||||
|
$buildable
|
||||||
|
->setBuildablePHID($object->getPHID())
|
||||||
|
->setContainerPHID($object->getRepository()->getPHID());
|
||||||
|
} else {
|
||||||
|
$e_name = pht('Invalid');
|
||||||
|
$errors[] = pht('Enter the name of a revision or commit.');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$e_name = pht('Required');
|
||||||
|
$errors[] = pht('You must choose a revision or commit to build.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$errors) {
|
||||||
|
$buildable->save();
|
||||||
|
|
||||||
|
$buildable_uri = '/B'.$buildable->getID();
|
||||||
|
return id(new AphrontRedirectResponse())->setURI($buildable_uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($errors) {
|
||||||
|
$errors = id(new AphrontErrorView())->setErrors($errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
$title = pht('Run Build Plan Manually');
|
||||||
|
$cancel_uri = $this->getApplicationURI("plan/{$plan_id}/");
|
||||||
|
$save_button = pht('Run Plan Manually');
|
||||||
|
|
||||||
|
$form = id(new PHUIFormLayoutView())
|
||||||
|
->setUser($viewer)
|
||||||
|
->appendRemarkupInstructions(
|
||||||
|
pht(
|
||||||
|
"Enter the name of a commit or revision to run this plan on.\n\n".
|
||||||
|
"For example: `rX123456` or `D123`"))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormTextControl())
|
||||||
|
->setLabel('Buildable Name')
|
||||||
|
->setName('buildablePHID')
|
||||||
|
->setError($e_name)
|
||||||
|
->setValue($v_name));
|
||||||
|
|
||||||
|
$dialog = id(new AphrontDialogView())
|
||||||
|
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||||
|
->setUser($viewer)
|
||||||
|
->setTitle($title)
|
||||||
|
->appendChild($form)
|
||||||
|
->addCancelButton($cancel_uri)
|
||||||
|
->addSubmitButton($save_button);
|
||||||
|
|
||||||
|
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -200,10 +200,18 @@ final class HarbormasterPlanViewController
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setName(pht('Add Build Step'))
|
->setName(pht('Add Build Step'))
|
||||||
->setHref($this->getApplicationURI("step/add/{$id}/"))
|
->setHref($this->getApplicationURI("step/add/{$id}/"))
|
||||||
->setWorkflow($can_edit)
|
->setWorkflow(true)
|
||||||
->setDisabled(!$can_edit)
|
->setDisabled(!$can_edit)
|
||||||
->setIcon('new'));
|
->setIcon('new'));
|
||||||
|
|
||||||
|
$list->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setName(pht('Run Plan Manually'))
|
||||||
|
->setHref($this->getApplicationURI("plan/run/{$id}/"))
|
||||||
|
->setWorkflow(true)
|
||||||
|
->setDisabled(!$can_edit)
|
||||||
|
->setIcon('start-sandcastle'));
|
||||||
|
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ final class HarbormasterBuildableQuery
|
||||||
private $phids;
|
private $phids;
|
||||||
private $buildablePHIDs;
|
private $buildablePHIDs;
|
||||||
private $containerPHIDs;
|
private $containerPHIDs;
|
||||||
|
private $manualBuildables;
|
||||||
|
|
||||||
private $needContainerObjects;
|
private $needContainerObjects;
|
||||||
private $needContainerHandles;
|
private $needContainerHandles;
|
||||||
|
@ -33,6 +34,11 @@ final class HarbormasterBuildableQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withManualBuildables($manual) {
|
||||||
|
$this->manualBuildables = $manual;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function needContainerObjects($need) {
|
public function needContainerObjects($need) {
|
||||||
$this->needContainerObjects = $need;
|
$this->needContainerObjects = $need;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -197,6 +203,13 @@ final class HarbormasterBuildableQuery
|
||||||
$this->containerPHIDs);
|
$this->containerPHIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->manualBuildables !== null) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'isManualBuildable = %d',
|
||||||
|
(int)$this->manualBuildables);
|
||||||
|
}
|
||||||
|
|
||||||
$where[] = $this->buildPagingClause($conn_r);
|
$where[] = $this->buildPagingClause($conn_r);
|
||||||
|
|
||||||
return $this->formatWhereClause($where);
|
return $this->formatWhereClause($where);
|
||||||
|
|
|
@ -42,6 +42,9 @@ final class HarbormasterBuildableSearchEngine
|
||||||
$buildable_phids = array_merge($commits, $diffs);
|
$buildable_phids = array_merge($commits, $diffs);
|
||||||
$saved->setParameter('buildablePHIDs', $buildable_phids);
|
$saved->setParameter('buildablePHIDs', $buildable_phids);
|
||||||
|
|
||||||
|
$saved->setParameter(
|
||||||
|
'manual',
|
||||||
|
$this->readBoolFromRequest($request, 'manual'));
|
||||||
|
|
||||||
return $saved;
|
return $saved;
|
||||||
}
|
}
|
||||||
|
@ -63,6 +66,11 @@ final class HarbormasterBuildableSearchEngine
|
||||||
$query->withBuildablePHIDs($buildable_phids);
|
$query->withBuildablePHIDs($buildable_phids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$manual = $saved->getParameter('manual');
|
||||||
|
if ($manual !== null) {
|
||||||
|
$query->withManualBuildables($manual);
|
||||||
|
}
|
||||||
|
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +134,18 @@ final class HarbormasterBuildableSearchEngine
|
||||||
id(new AphrontFormTextControl())
|
id(new AphrontFormTextControl())
|
||||||
->setLabel(pht('Commits'))
|
->setLabel(pht('Commits'))
|
||||||
->setName('commits')
|
->setName('commits')
|
||||||
->setValue(implode(', ', $commit_names)));
|
->setValue(implode(', ', $commit_names)))
|
||||||
|
->appendChild(
|
||||||
|
id(new AphrontFormSelectControl())
|
||||||
|
->setLabel(pht('Origin'))
|
||||||
|
->setName('manual')
|
||||||
|
->setValue($this->getBoolFromQuery($saved_query, 'manual'))
|
||||||
|
->setOptions(
|
||||||
|
array(
|
||||||
|
'' => pht('(All Origins)'),
|
||||||
|
'true' => pht('Manual Buildables'),
|
||||||
|
'false' => pht('Automatic Buildables'),
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getURI($path) {
|
protected function getURI($path) {
|
||||||
|
|
|
@ -102,6 +102,7 @@ final class WaitForPreviousBuildStepImplementation
|
||||||
$buildables = id(new HarbormasterBuildableQuery())
|
$buildables = id(new HarbormasterBuildableQuery())
|
||||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
->withBuildablePHIDs($build_objects)
|
->withBuildablePHIDs($build_objects)
|
||||||
|
->withManualBuildables(false)
|
||||||
->execute();
|
->execute();
|
||||||
$buildable_phids = mpull($buildables, 'getPHID');
|
$buildable_phids = mpull($buildables, 'getPHID');
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ final class HarbormasterBuildable extends HarbormasterDAO
|
||||||
protected $containerPHID;
|
protected $containerPHID;
|
||||||
protected $buildStatus;
|
protected $buildStatus;
|
||||||
protected $buildableStatus;
|
protected $buildableStatus;
|
||||||
|
protected $isManualBuildable;
|
||||||
|
|
||||||
private $buildableObject = self::ATTACHABLE;
|
private $buildableObject = self::ATTACHABLE;
|
||||||
private $containerObject = self::ATTACHABLE;
|
private $containerObject = self::ATTACHABLE;
|
||||||
|
@ -18,6 +19,7 @@ final class HarbormasterBuildable extends HarbormasterDAO
|
||||||
|
|
||||||
public static function initializeNewBuildable(PhabricatorUser $actor) {
|
public static function initializeNewBuildable(PhabricatorUser $actor) {
|
||||||
return id(new HarbormasterBuildable())
|
return id(new HarbormasterBuildable())
|
||||||
|
->setIsManualBuildable(0)
|
||||||
->setBuildStatus(self::STATUS_WHATEVER)
|
->setBuildStatus(self::STATUS_WHATEVER)
|
||||||
->setBuildableStatus(self::STATUS_WHATEVER);
|
->setBuildableStatus(self::STATUS_WHATEVER);
|
||||||
}
|
}
|
||||||
|
@ -34,6 +36,7 @@ final class HarbormasterBuildable extends HarbormasterDAO
|
||||||
$buildable = id(new HarbormasterBuildableQuery())
|
$buildable = id(new HarbormasterBuildableQuery())
|
||||||
->setViewer($actor)
|
->setViewer($actor)
|
||||||
->withBuildablePHIDs(array($buildable_object_phid))
|
->withBuildablePHIDs(array($buildable_object_phid))
|
||||||
|
->withManualBuildables(false)
|
||||||
->setLimit(1)
|
->setLimit(1)
|
||||||
->executeOne();
|
->executeOne();
|
||||||
if ($buildable) {
|
if ($buildable) {
|
||||||
|
|
|
@ -1848,6 +1848,10 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList {
|
||||||
'type' => 'sql',
|
'type' => 'sql',
|
||||||
'name' => $this->getPatchPath('20131219.pxdrop.sql'),
|
'name' => $this->getPatchPath('20131219.pxdrop.sql'),
|
||||||
),
|
),
|
||||||
|
'20131224.harbormanual.sql' => array(
|
||||||
|
'type' => 'sql',
|
||||||
|
'name' => $this->getPatchPath('20131224.harbormanual.sql'),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue