mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 05:50:55 +01:00
Implement basic Harbormaster daemon and start builds.
Summary: This implements a basic Harbormaster daemon that takes pending builds and builds them (currently just sleeps 15 seconds before moving to passed state). It also implements an interface to apply a build plan to a buildable, so that users can kick off builds for a buildable. Test Plan: Ran `bin/phd debug PhabricatorHarbormasterBuildDaemon` and used the interface to start some builds by applying a build plan. Observed them move from 'pending' to 'building' to 'passed'. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley CC: Korvin, epriestley, aran Maniphest Tasks: T1049 Differential Revision: https://secure.phabricator.com/D7498
This commit is contained in:
parent
5cc26f065d
commit
ca5400d14b
12 changed files with 221 additions and 158 deletions
|
@ -656,7 +656,9 @@ phutil_register_library_map(array(
|
||||||
'HarbormasterBuildStepQuery' => 'applications/harbormaster/query/HarbormasterBuildStepQuery.php',
|
'HarbormasterBuildStepQuery' => 'applications/harbormaster/query/HarbormasterBuildStepQuery.php',
|
||||||
'HarbormasterBuildTarget' => 'applications/harbormaster/storage/build/HarbormasterBuildTarget.php',
|
'HarbormasterBuildTarget' => 'applications/harbormaster/storage/build/HarbormasterBuildTarget.php',
|
||||||
'HarbormasterBuildTargetQuery' => 'applications/harbormaster/query/HarbormasterBuildTargetQuery.php',
|
'HarbormasterBuildTargetQuery' => 'applications/harbormaster/query/HarbormasterBuildTargetQuery.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',
|
||||||
'HarbormasterBuildableArtifactQuery' => 'applications/harbormaster/query/HarbormasterBuildableArtifactQuery.php',
|
'HarbormasterBuildableArtifactQuery' => 'applications/harbormaster/query/HarbormasterBuildableArtifactQuery.php',
|
||||||
'HarbormasterBuildableEditController' => 'applications/harbormaster/controller/HarbormasterBuildableEditController.php',
|
'HarbormasterBuildableEditController' => 'applications/harbormaster/controller/HarbormasterBuildableEditController.php',
|
||||||
'HarbormasterBuildableListController' => 'applications/harbormaster/controller/HarbormasterBuildableListController.php',
|
'HarbormasterBuildableListController' => 'applications/harbormaster/controller/HarbormasterBuildableListController.php',
|
||||||
|
@ -675,11 +677,9 @@ phutil_register_library_map(array(
|
||||||
'HarbormasterPHIDTypeBuildable' => 'applications/harbormaster/phid/HarbormasterPHIDTypeBuildable.php',
|
'HarbormasterPHIDTypeBuildable' => 'applications/harbormaster/phid/HarbormasterPHIDTypeBuildable.php',
|
||||||
'HarbormasterPlanController' => 'applications/harbormaster/controller/HarbormasterPlanController.php',
|
'HarbormasterPlanController' => 'applications/harbormaster/controller/HarbormasterPlanController.php',
|
||||||
'HarbormasterPlanEditController' => 'applications/harbormaster/controller/HarbormasterPlanEditController.php',
|
'HarbormasterPlanEditController' => 'applications/harbormaster/controller/HarbormasterPlanEditController.php',
|
||||||
'HarbormasterPlanExecuteController' => 'applications/harbormaster/controller/HarbormasterPlanExecuteController.php',
|
|
||||||
'HarbormasterPlanListController' => 'applications/harbormaster/controller/HarbormasterPlanListController.php',
|
'HarbormasterPlanListController' => 'applications/harbormaster/controller/HarbormasterPlanListController.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',
|
||||||
'HarbormasterRunnerWorker' => 'applications/harbormaster/worker/HarbormasterRunnerWorker.php',
|
|
||||||
'HarbormasterScratchTable' => 'applications/harbormaster/storage/HarbormasterScratchTable.php',
|
'HarbormasterScratchTable' => 'applications/harbormaster/storage/HarbormasterScratchTable.php',
|
||||||
'HeraldAction' => 'applications/herald/storage/HeraldAction.php',
|
'HeraldAction' => 'applications/herald/storage/HeraldAction.php',
|
||||||
'HeraldAdapter' => 'applications/herald/adapter/HeraldAdapter.php',
|
'HeraldAdapter' => 'applications/herald/adapter/HeraldAdapter.php',
|
||||||
|
@ -2868,11 +2868,13 @@ phutil_register_library_map(array(
|
||||||
'HarbormasterBuildStepQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'HarbormasterBuildStepQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'HarbormasterBuildTarget' => 'HarbormasterDAO',
|
'HarbormasterBuildTarget' => 'HarbormasterDAO',
|
||||||
'HarbormasterBuildTargetQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'HarbormasterBuildTargetQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'HarbormasterBuildWorker' => 'PhabricatorWorker',
|
||||||
'HarbormasterBuildable' =>
|
'HarbormasterBuildable' =>
|
||||||
array(
|
array(
|
||||||
0 => 'HarbormasterDAO',
|
0 => 'HarbormasterDAO',
|
||||||
1 => 'PhabricatorPolicyInterface',
|
1 => 'PhabricatorPolicyInterface',
|
||||||
),
|
),
|
||||||
|
'HarbormasterBuildableApplyController' => 'HarbormasterController',
|
||||||
'HarbormasterBuildableArtifactQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'HarbormasterBuildableArtifactQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'HarbormasterBuildableEditController' => 'HarbormasterController',
|
'HarbormasterBuildableEditController' => 'HarbormasterController',
|
||||||
'HarbormasterBuildableListController' =>
|
'HarbormasterBuildableListController' =>
|
||||||
|
@ -2895,7 +2897,6 @@ phutil_register_library_map(array(
|
||||||
'HarbormasterPHIDTypeBuildable' => 'PhabricatorPHIDType',
|
'HarbormasterPHIDTypeBuildable' => 'PhabricatorPHIDType',
|
||||||
'HarbormasterPlanController' => 'PhabricatorController',
|
'HarbormasterPlanController' => 'PhabricatorController',
|
||||||
'HarbormasterPlanEditController' => 'HarbormasterPlanController',
|
'HarbormasterPlanEditController' => 'HarbormasterPlanController',
|
||||||
'HarbormasterPlanExecuteController' => 'HarbormasterPlanController',
|
|
||||||
'HarbormasterPlanListController' =>
|
'HarbormasterPlanListController' =>
|
||||||
array(
|
array(
|
||||||
0 => 'HarbormasterPlanController',
|
0 => 'HarbormasterPlanController',
|
||||||
|
@ -2903,7 +2904,6 @@ phutil_register_library_map(array(
|
||||||
),
|
),
|
||||||
'HarbormasterPlanViewController' => 'HarbormasterPlanController',
|
'HarbormasterPlanViewController' => 'HarbormasterPlanController',
|
||||||
'HarbormasterRemarkupRule' => 'PhabricatorRemarkupRuleObject',
|
'HarbormasterRemarkupRule' => 'PhabricatorRemarkupRuleObject',
|
||||||
'HarbormasterRunnerWorker' => 'PhabricatorWorker',
|
|
||||||
'HarbormasterScratchTable' => 'HarbormasterDAO',
|
'HarbormasterScratchTable' => 'HarbormasterDAO',
|
||||||
'HeraldAction' => 'HeraldDAO',
|
'HeraldAction' => 'HeraldDAO',
|
||||||
'HeraldApplyTranscript' => 'HeraldDAO',
|
'HeraldApplyTranscript' => 'HeraldDAO',
|
||||||
|
|
|
@ -44,13 +44,13 @@ final class PhabricatorApplicationHarbormaster extends PhabricatorApplication {
|
||||||
=> 'HarbormasterBuildableListController',
|
=> 'HarbormasterBuildableListController',
|
||||||
'buildable/' => array(
|
'buildable/' => array(
|
||||||
'edit/(?:(?P<id>\d+)/)?' => 'HarbormasterBuildableEditController',
|
'edit/(?:(?P<id>\d+)/)?' => 'HarbormasterBuildableEditController',
|
||||||
|
'apply/(?:(?P<id>\d+)/)?' => 'HarbormasterBuildableApplyController',
|
||||||
),
|
),
|
||||||
'plan/' => array(
|
'plan/' => array(
|
||||||
'(?:query/(?P<queryKey>[^/]+)/)?'
|
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||||
=> 'HarbormasterPlanListController',
|
=> 'HarbormasterPlanListController',
|
||||||
'edit/(?:(?P<id>\d+)/)?' => 'HarbormasterPlanEditController',
|
'edit/(?:(?P<id>\d+)/)?' => 'HarbormasterPlanEditController',
|
||||||
'(?P<id>\d+)/' => 'HarbormasterPlanViewController',
|
'(?P<id>\d+)/' => 'HarbormasterPlanViewController',
|
||||||
'execute/(?P<id>\d+)/' => 'HarbormasterPlanExecuteController',
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?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();
|
||||||
|
|
||||||
|
$build = HarbormasterBuild::initializeNewBuild($viewer);
|
||||||
|
$build->setBuildablePHID($buildable->getPHID());
|
||||||
|
$build->setBuildPlanPHID($plan->getPHID());
|
||||||
|
$build->setBuildStatus(HarbormasterBuild::STATUS_PENDING);
|
||||||
|
$build->save();
|
||||||
|
|
||||||
|
PhabricatorWorker::scheduleTask(
|
||||||
|
'HarbormasterBuildWorker',
|
||||||
|
array(
|
||||||
|
'buildID' => $build->getID()
|
||||||
|
));
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -36,7 +36,7 @@ final class HarbormasterBuildableListController
|
||||||
$id = $buildable->getID();
|
$id = $buildable->getID();
|
||||||
|
|
||||||
$item = id(new PHUIObjectItemView())
|
$item = id(new PHUIObjectItemView())
|
||||||
->setHeader(pht('Build %d', $buildable->getID()));
|
->setHeader(pht('Buildable %d', $buildable->getID()));
|
||||||
|
|
||||||
if ($id) {
|
if ($id) {
|
||||||
$item->setHref("/B{$id}");
|
$item->setHref("/B{$id}");
|
||||||
|
|
|
@ -37,6 +37,32 @@ final class HarbormasterBuildableViewController
|
||||||
$item = id(new PHUIObjectItemView())
|
$item = id(new PHUIObjectItemView())
|
||||||
->setObjectName(pht('Build %d', $build->getID()))
|
->setObjectName(pht('Build %d', $build->getID()))
|
||||||
->setHeader($build->getName());
|
->setHeader($build->getName());
|
||||||
|
switch ($build->getBuildStatus()) {
|
||||||
|
case HarbormasterBuild::STATUS_INACTIVE:
|
||||||
|
$item->setBarColor('grey');
|
||||||
|
$item->addAttribute(pht('Inactive'));
|
||||||
|
break;
|
||||||
|
case HarbormasterBuild::STATUS_PENDING:
|
||||||
|
$item->setBarColor('blue');
|
||||||
|
$item->addAttribute(pht('Pending'));
|
||||||
|
break;
|
||||||
|
case HarbormasterBuild::STATUS_WAITING:
|
||||||
|
$item->setBarColor('blue');
|
||||||
|
$item->addAttribute(pht('Waiting on Resource'));
|
||||||
|
break;
|
||||||
|
case HarbormasterBuild::STATUS_BUILDING:
|
||||||
|
$item->setBarColor('yellow');
|
||||||
|
$item->addAttribute(pht('Building'));
|
||||||
|
break;
|
||||||
|
case HarbormasterBuild::STATUS_PASSED:
|
||||||
|
$item->setBarColor('green');
|
||||||
|
$item->addAttribute(pht('Passed'));
|
||||||
|
break;
|
||||||
|
case HarbormasterBuild::STATUS_FAILED:
|
||||||
|
$item->setBarColor('red');
|
||||||
|
$item->addAttribute(pht('Failed'));
|
||||||
|
break;
|
||||||
|
}
|
||||||
$build_list->addItem($item);
|
$build_list->addItem($item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +106,15 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class HarbormasterPlanExecuteController
|
|
||||||
extends HarbormasterPlanController {
|
|
||||||
|
|
||||||
private $id;
|
|
||||||
|
|
||||||
public function willProcessRequest(array $data) {
|
|
||||||
$this->id = $data['id'];
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processRequest() {
|
|
||||||
$request = $this->getRequest();
|
|
||||||
$viewer = $request->getUser();
|
|
||||||
|
|
||||||
$this->requireApplicationCapability(
|
|
||||||
HarbormasterCapabilityManagePlans::CAPABILITY);
|
|
||||||
|
|
||||||
$id = $this->id;
|
|
||||||
|
|
||||||
$plan = id(new HarbormasterBuildPlanQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->withIDs(array($id))
|
|
||||||
->executeOne();
|
|
||||||
if (!$plan) {
|
|
||||||
return new Aphront404Response();
|
|
||||||
}
|
|
||||||
|
|
||||||
$cancel_uri = $this->getApplicationURI("plan/{$id}/");
|
|
||||||
|
|
||||||
$v_buildable = null;
|
|
||||||
$e_buildable = null;
|
|
||||||
|
|
||||||
$errors = array();
|
|
||||||
if ($request->isFormPost()) {
|
|
||||||
$v_buildable = $request->getStr('buildable');
|
|
||||||
|
|
||||||
if ($v_buildable) {
|
|
||||||
$buildable = id(new HarbormasterBuildableQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->withIDs(array(trim($v_buildable, 'B')))
|
|
||||||
->executeOne();
|
|
||||||
if (!$buildable) {
|
|
||||||
$e_buildable = pht('Invalid');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$e_buildable = pht('Required');
|
|
||||||
$errors[] = pht('You must provide a buildable.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$errors) {
|
|
||||||
$build_plan = HarbormasterBuild::initializeNewBuild($viewer)
|
|
||||||
->setBuildablePHID($buildable->getPHID())
|
|
||||||
->setBuildPlanPHID($plan->getPHID())
|
|
||||||
->save();
|
|
||||||
|
|
||||||
$buildable_id = $buildable->getID();
|
|
||||||
|
|
||||||
return id(new AphrontRedirectResponse())
|
|
||||||
->setURI("/B{$buildable_id}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($errors) {
|
|
||||||
$errors = id(new AphrontErrorView())->setErrors($errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
$form = id(new PHUIFormLayoutView())
|
|
||||||
->appendChild(
|
|
||||||
id(new AphrontFormTextControl())
|
|
||||||
->setLabel(pht('Buildable'))
|
|
||||||
->setName('buildable')
|
|
||||||
->setValue($v_buildable)
|
|
||||||
->setError($e_buildable));
|
|
||||||
|
|
||||||
$dialog = id(new AphrontDialogView())
|
|
||||||
->setUser($viewer)
|
|
||||||
->setTitle(pht('Execute Build Plan'))
|
|
||||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
|
||||||
->appendChild($errors)
|
|
||||||
->appendChild($form)
|
|
||||||
->addSubmitButton(pht('Execute Build Plan'))
|
|
||||||
->addCancelButton($cancel_uri);
|
|
||||||
|
|
||||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -88,14 +88,6 @@ final class HarbormasterPlanViewController
|
||||||
->setDisabled(!$can_edit)
|
->setDisabled(!$can_edit)
|
||||||
->setIcon('edit'));
|
->setIcon('edit'));
|
||||||
|
|
||||||
$list->addAction(
|
|
||||||
id(new PhabricatorActionView())
|
|
||||||
->setName(pht('Manually Execute Plan'))
|
|
||||||
->setHref($this->getApplicationURI("plan/execute/{$id}/"))
|
|
||||||
->setWorkflow(true)
|
|
||||||
->setDisabled(!$can_edit)
|
|
||||||
->setIcon('arrow_right'));
|
|
||||||
|
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ final class HarbormasterBuildQuery
|
||||||
|
|
||||||
private $ids;
|
private $ids;
|
||||||
private $phids;
|
private $phids;
|
||||||
|
private $buildStatuses;
|
||||||
private $buildablePHIDs;
|
private $buildablePHIDs;
|
||||||
private $buildPlanPHIDs;
|
private $buildPlanPHIDs;
|
||||||
|
|
||||||
|
@ -20,6 +21,11 @@ final class HarbormasterBuildQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withBuildStatuses(array $build_statuses) {
|
||||||
|
$this->buildStatuses = $build_statuses;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function withBuildablePHIDs(array $buildable_phids) {
|
public function withBuildablePHIDs(array $buildable_phids) {
|
||||||
$this->buildablePHIDs = $buildable_phids;
|
$this->buildablePHIDs = $buildable_phids;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -115,6 +121,13 @@ final class HarbormasterBuildQuery
|
||||||
$this->phids);
|
$this->phids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->buildStatuses) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'buildStatus in (%Ls)',
|
||||||
|
$this->buildStatuses);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->buildablePHIDs) {
|
if ($this->buildablePHIDs) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn_r,
|
||||||
|
|
|
@ -12,10 +12,12 @@ final class HarbormasterBuildable extends HarbormasterDAO
|
||||||
private $containerObject = self::ATTACHABLE;
|
private $containerObject = self::ATTACHABLE;
|
||||||
private $buildableHandle = self::ATTACHABLE;
|
private $buildableHandle = self::ATTACHABLE;
|
||||||
|
|
||||||
|
const STATUS_WHATEVER = 'whatever';
|
||||||
|
|
||||||
public static function initializeNewBuildable(PhabricatorUser $actor) {
|
public static function initializeNewBuildable(PhabricatorUser $actor) {
|
||||||
return id(new HarbormasterBuildable())
|
return id(new HarbormasterBuildable())
|
||||||
->setBuildStatus('new') // TODO: Define these.
|
->setBuildStatus(self::STATUS_WHATEVER)
|
||||||
->setBuildableStatus('active'); // TODO: Define these, too.
|
->setBuildableStatus(self::STATUS_WHATEVER);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getConfiguration() {
|
public function getConfiguration() {
|
||||||
|
|
|
@ -10,9 +10,39 @@ final class HarbormasterBuild extends HarbormasterDAO
|
||||||
private $buildable = self::ATTACHABLE;
|
private $buildable = self::ATTACHABLE;
|
||||||
private $buildPlan = self::ATTACHABLE;
|
private $buildPlan = self::ATTACHABLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Not currently being built.
|
||||||
|
*/
|
||||||
|
const STATUS_INACTIVE = 'inactive';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pending pick up by the Harbormaster daemon.
|
||||||
|
*/
|
||||||
|
const STATUS_PENDING = 'pending';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Waiting for a resource to be allocated (not yet relevant).
|
||||||
|
*/
|
||||||
|
const STATUS_WAITING = 'waiting';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current building the buildable.
|
||||||
|
*/
|
||||||
|
const STATUS_BUILDING = 'building';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The build has passed.
|
||||||
|
*/
|
||||||
|
const STATUS_PASSED = 'passed';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The build has failed.
|
||||||
|
*/
|
||||||
|
const STATUS_FAILED = 'failed';
|
||||||
|
|
||||||
public static function initializeNewBuild(PhabricatorUser $actor) {
|
public static function initializeNewBuild(PhabricatorUser $actor) {
|
||||||
return id(new HarbormasterBuild())
|
return id(new HarbormasterBuild())
|
||||||
->setBuildStatus('building'); // TODO: Sort this.
|
->setBuildStatus(self::STATUS_INACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getConfiguration() {
|
public function getConfiguration() {
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run builds
|
||||||
|
*/
|
||||||
|
final class HarbormasterBuildWorker extends PhabricatorWorker {
|
||||||
|
|
||||||
|
public function getRequiredLeaseTime() {
|
||||||
|
return 60 * 60 * 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function doWork() {
|
||||||
|
$data = $this->getTaskData();
|
||||||
|
$id = idx($data, 'buildID');
|
||||||
|
|
||||||
|
// Get a reference to the build.
|
||||||
|
$build = id(new HarbormasterBuildQuery())
|
||||||
|
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||||
|
->withBuildStatuses(array(HarbormasterBuild::STATUS_PENDING))
|
||||||
|
->withIDs(array($id))
|
||||||
|
->needBuildPlans(true)
|
||||||
|
->executeOne();
|
||||||
|
if (!$build) {
|
||||||
|
throw new PhabricatorWorkerPermanentFailureException(
|
||||||
|
pht('Invalid build ID "%s".', $id));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$build->setBuildStatus(HarbormasterBuild::STATUS_BUILDING);
|
||||||
|
$build->save();
|
||||||
|
|
||||||
|
$buildable = $build->getBuildable();
|
||||||
|
$plan = $build->getBuildPlan();
|
||||||
|
|
||||||
|
// TODO: Do the actual build here.
|
||||||
|
sleep(15);
|
||||||
|
|
||||||
|
// If we get to here, then the build has passed.
|
||||||
|
$build->setBuildStatus(HarbormasterBuild::STATUS_PASSED);
|
||||||
|
$build->save();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// If any exception is raised, the build is marked as a failure and
|
||||||
|
// the exception is re-thrown (this ensures we don't leave builds
|
||||||
|
// in an inconsistent state).
|
||||||
|
$build->setBuildStatus(HarbormasterBuild::STATUS_FAILED);
|
||||||
|
$build->save();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,53 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class HarbormasterRunnerWorker extends PhabricatorWorker {
|
|
||||||
|
|
||||||
public function getRequiredLeaseTime() {
|
|
||||||
return 60 * 60 * 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function doWork() {
|
|
||||||
$data = $this->getTaskData();
|
|
||||||
$id = idx($data, 'commitID');
|
|
||||||
|
|
||||||
$commit = id(new PhabricatorRepositoryCommit())->loadOneWhere(
|
|
||||||
'id = %d',
|
|
||||||
$id);
|
|
||||||
|
|
||||||
if (!$commit) {
|
|
||||||
throw new PhabricatorWorkerPermanentFailureException(
|
|
||||||
"Commit '{$id}' does not exist!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: (T603) Policy interaction?
|
|
||||||
$repository = id(new PhabricatorRepository())->loadOneWhere(
|
|
||||||
'id = %d',
|
|
||||||
$commit->getRepositoryID());
|
|
||||||
|
|
||||||
if (!$repository) {
|
|
||||||
throw new PhabricatorWorkerPermanentFailureException(
|
|
||||||
"Unable to load repository for commit '{$id}'!");
|
|
||||||
}
|
|
||||||
|
|
||||||
$lease = id(new DrydockLease())
|
|
||||||
->setResourceType('working-copy')
|
|
||||||
->setAttributes(
|
|
||||||
array(
|
|
||||||
'repositoryID' => $repository->getID(),
|
|
||||||
'commit' => $commit->getCommitIdentifier(),
|
|
||||||
))
|
|
||||||
->releaseOnDestruction()
|
|
||||||
->waitUntilActive();
|
|
||||||
|
|
||||||
$cmd = $lease->getInterface('command');
|
|
||||||
list($json) = $cmd
|
|
||||||
->setWorkingDirectory($lease->getResource()->getAttribute('path'))
|
|
||||||
->execx('arc unit --everything --json');
|
|
||||||
$lease->release();
|
|
||||||
|
|
||||||
// TODO: Do something actually useful with this. Requires Harbormaster
|
|
||||||
// buildout.
|
|
||||||
echo $json;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue