Summary: Ref T9614. Currently, a lot of Build Plan behavior is covered by a global "can manage" policy. One install in particular is experiencing difficulty with warring factions within engineering aborting one another's builds. As a first step to remedy this, and also generally make Harbormaster more flexible and bring it in line with other applications in terms of policy power: - Give Build Plans normal view/edit policies. - Require "Can Edit" to run a plan manually. Having "Can View" on plans may be a little weird in some cases (the status of a Buildable might be bad because of a build you can't see) but we can cross that bridge when we come to it. Next change here will require "Can Edit" to abort a build. This will reasonably allow installs to reserve pause/abort for administrators/adults. (I might let anyone restart a plan, though?) Test Plan: - Created a new build plan. - Verified defaults were inherited from application defaults (swapped them around, too). - Saved build plan. - Edited policies. - Verified autoplans get the right policies. - Verified old plans got migrated properly. - Tried to run a plan I couldn't edit (denied). - Ran a plan from CLI with `bin/harbormaster`. - Tried to create a plan with an unprivileged user. Reviewers: chad Reviewed By: chad Maniphest Tasks: T9614 Differential Revision: https://secure.phabricator.com/D14321
103 lines
2.7 KiB
PHP
103 lines
2.7 KiB
PHP
<?php
|
|
|
|
final class HarbormasterStepAddController extends HarbormasterController {
|
|
|
|
public function handleRequest(AphrontRequest $request) {
|
|
$viewer = $this->getViewer();
|
|
|
|
$plan = id(new HarbormasterBuildPlanQuery())
|
|
->setViewer($viewer)
|
|
->withIDs(array($request->getURIData('id')))
|
|
->requireCapabilities(
|
|
array(
|
|
PhabricatorPolicyCapability::CAN_VIEW,
|
|
PhabricatorPolicyCapability::CAN_EDIT,
|
|
))
|
|
->executeOne();
|
|
if (!$plan) {
|
|
return new Aphront404Response();
|
|
}
|
|
|
|
$plan_id = $plan->getID();
|
|
$cancel_uri = $this->getApplicationURI("plan/{$plan_id}/");
|
|
$plan_title = pht('Plan %d', $plan_id);
|
|
|
|
$all = HarbormasterBuildStepImplementation::getImplementations();
|
|
$all = msort($all, 'getName');
|
|
|
|
$all_groups = HarbormasterBuildStepGroup::getAllGroups();
|
|
foreach ($all as $impl) {
|
|
$group_key = $impl->getBuildStepGroupKey();
|
|
if (empty($all_groups[$group_key])) {
|
|
throw new Exception(
|
|
pht(
|
|
'Build step "%s" has step group key "%s", but no step group '.
|
|
'with that key exists.',
|
|
get_class($impl),
|
|
$group_key));
|
|
}
|
|
}
|
|
|
|
$groups = mgroup($all, 'getBuildStepGroupKey');
|
|
$lists = array();
|
|
|
|
$enabled_groups = HarbormasterBuildStepGroup::getAllEnabledGroups();
|
|
foreach ($enabled_groups as $group) {
|
|
$list = id(new PHUIObjectItemListView())
|
|
->setHeader($group->getGroupName())
|
|
->setNoDataString(
|
|
pht(
|
|
'This group has no available build steps.'));
|
|
|
|
$steps = idx($groups, $group->getGroupKey(), array());
|
|
|
|
foreach ($steps as $key => $impl) {
|
|
if ($impl->shouldRequireAutotargeting()) {
|
|
unset($steps[$key]);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (!$steps && !$group->shouldShowIfEmpty()) {
|
|
continue;
|
|
}
|
|
|
|
foreach ($steps as $key => $impl) {
|
|
$class = get_class($impl);
|
|
|
|
$new_uri = $this->getApplicationURI("step/new/{$plan_id}/{$class}/");
|
|
|
|
$item = id(new PHUIObjectItemView())
|
|
->setHeader($impl->getName())
|
|
->setHref($new_uri)
|
|
->addAttribute($impl->getGenericDescription());
|
|
|
|
$list->addItem($item);
|
|
}
|
|
|
|
$lists[] = $list;
|
|
}
|
|
|
|
$crumbs = $this->buildApplicationCrumbs()
|
|
->addTextCrumb($plan_title, $cancel_uri)
|
|
->addTextCrumb(pht('Add Build Step'));
|
|
|
|
$box = id(new PHUIObjectBoxView())
|
|
->setHeaderText(pht('Add Build Step'))
|
|
->appendChild($lists);
|
|
|
|
return $this->buildApplicationPage(
|
|
array(
|
|
$crumbs,
|
|
$box,
|
|
),
|
|
array(
|
|
'title' => array(
|
|
$plan_title,
|
|
pht('Add Build Step'),
|
|
),
|
|
));
|
|
}
|
|
|
|
}
|