Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14079913
D7825.id17702.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
17 KB
Referenced Files
None
Subscribers
None
D7825.id17702.diff
View Options
Index: bin/harbormaster
===================================================================
--- /dev/null
+++ bin/harbormaster
@@ -0,0 +1 @@
+../scripts/setup/manage_harbormaster.php
\ No newline at end of file
Index: scripts/setup/manage_harbormaster.php
===================================================================
--- /dev/null
+++ scripts/setup/manage_harbormaster.php
@@ -0,0 +1,22 @@
+#!/usr/bin/env php
+<?php
+
+$root = dirname(dirname(dirname(__FILE__)));
+require_once $root.'/scripts/__init_script__.php';
+
+$args = new PhutilArgumentParser($argv);
+$args->setTagline('manage Harbormaster');
+$args->setSynopsis(<<<EOSYNOPSIS
+**harbormaster** __command__ [__options__]
+ Manage and debug Harbormaster.
+
+EOSYNOPSIS
+ );
+$args->parseStandardArguments();
+
+$workflows = id(new PhutilSymbolLoader())
+ ->setAncestorClass('HarbormasterManagementWorkflow')
+ ->loadObjects();
+$workflows[] = new PhutilHelpArgumentWorkflow();
+
+$args->parseWorkflows($workflows);
Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -707,6 +707,7 @@
'HarbormasterBuildViewController' => 'applications/harbormaster/controller/HarbormasterBuildViewController.php',
'HarbormasterBuildWorker' => 'applications/harbormaster/worker/HarbormasterBuildWorker.php',
'HarbormasterBuildable' => 'applications/harbormaster/storage/HarbormasterBuildable.php',
+ 'HarbormasterBuildableInterface' => 'applications/harbormaster/interface/HarbormasterBuildableInterface.php',
'HarbormasterBuildableListController' => 'applications/harbormaster/controller/HarbormasterBuildableListController.php',
'HarbormasterBuildableQuery' => 'applications/harbormaster/query/HarbormasterBuildableQuery.php',
'HarbormasterBuildableSearchEngine' => 'applications/harbormaster/query/HarbormasterBuildableSearchEngine.php',
@@ -715,6 +716,8 @@
'HarbormasterController' => 'applications/harbormaster/controller/HarbormasterController.php',
'HarbormasterDAO' => 'applications/harbormaster/storage/HarbormasterDAO.php',
'HarbormasterHTTPRequestBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterHTTPRequestBuildStepImplementation.php',
+ 'HarbormasterManagementBuildWorkflow' => 'applications/harbormaster/management/HarbormasterManagementBuildWorkflow.php',
+ 'HarbormasterManagementWorkflow' => 'applications/harbormaster/management/HarbormasterManagementWorkflow.php',
'HarbormasterObject' => 'applications/harbormaster/storage/HarbormasterObject.php',
'HarbormasterPHIDTypeBuild' => 'applications/harbormaster/phid/HarbormasterPHIDTypeBuild.php',
'HarbormasterPHIDTypeBuildItem' => 'applications/harbormaster/phid/HarbormasterPHIDTypeBuildItem.php',
@@ -2747,6 +2750,7 @@
array(
0 => 'DifferentialDAO',
1 => 'PhabricatorPolicyInterface',
+ 2 => 'HarbormasterBuildableInterface',
),
'DifferentialDiffContentMail' => 'DifferentialMail',
'DifferentialDiffCreateController' => 'DifferentialController',
@@ -2814,6 +2818,7 @@
2 => 'PhabricatorPolicyInterface',
3 => 'PhabricatorFlaggableInterface',
4 => 'PhrequentTrackableInterface',
+ 5 => 'HarbormasterBuildableInterface',
),
'DifferentialRevisionCommentListView' => 'AphrontView',
'DifferentialRevisionCommentView' => 'AphrontView',
@@ -3131,6 +3136,7 @@
array(
0 => 'HarbormasterDAO',
1 => 'PhabricatorPolicyInterface',
+ 2 => 'HarbormasterBuildableInterface',
),
'HarbormasterBuildableListController' =>
array(
@@ -3144,6 +3150,8 @@
'HarbormasterController' => 'PhabricatorController',
'HarbormasterDAO' => 'PhabricatorLiskDAO',
'HarbormasterHTTPRequestBuildStepImplementation' => 'VariableBuildStepImplementation',
+ 'HarbormasterManagementBuildWorkflow' => 'HarbormasterManagementWorkflow',
+ 'HarbormasterManagementWorkflow' => 'PhutilArgumentWorkflow',
'HarbormasterObject' => 'HarbormasterDAO',
'HarbormasterPHIDTypeBuild' => 'PhabricatorPHIDType',
'HarbormasterPHIDTypeBuildItem' => 'PhabricatorPHIDType',
@@ -4342,6 +4350,7 @@
1 => 'PhabricatorPolicyInterface',
2 => 'PhabricatorFlaggableInterface',
3 => 'PhabricatorTokenReceiverInterface',
+ 4 => 'HarbormasterBuildableInterface',
),
'PhabricatorRepositoryCommitChangeParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
'PhabricatorRepositoryCommitData' => 'PhabricatorRepositoryDAO',
Index: src/applications/differential/storage/DifferentialDiff.php
===================================================================
--- src/applications/differential/storage/DifferentialDiff.php
+++ src/applications/differential/storage/DifferentialDiff.php
@@ -2,7 +2,9 @@
final class DifferentialDiff
extends DifferentialDAO
- implements PhabricatorPolicyInterface {
+ implements
+ PhabricatorPolicyInterface,
+ HarbormasterBuildableInterface {
protected $revisionID;
protected $authorPHID;
@@ -339,4 +341,24 @@
return null;
}
+
+
+/* -( HarbormasterBuildableInterface )------------------------------------- */
+
+
+ public function getHarbormasterBuildablePHID() {
+ return $this->getPHID();
+ }
+
+ public function getHarbormasterContainerPHID() {
+ if ($this->getRevisionID()) {
+ $revision = id(new DifferentialRevision())->load($this->getRevisionID());
+ if ($revision) {
+ return $revision->getPHID();
+ }
+ }
+
+ return null;
+ }
+
}
Index: src/applications/differential/storage/DifferentialRevision.php
===================================================================
--- src/applications/differential/storage/DifferentialRevision.php
+++ src/applications/differential/storage/DifferentialRevision.php
@@ -5,7 +5,8 @@
PhabricatorTokenReceiverInterface,
PhabricatorPolicyInterface,
PhabricatorFlaggableInterface,
- PhrequentTrackableInterface {
+ PhrequentTrackableInterface,
+ HarbormasterBuildableInterface {
protected $title = '';
protected $originalTitle;
@@ -412,4 +413,16 @@
return DifferentialRevisionStatus::isClosedStatus($this->getStatus());
}
+
+/* -( HarbormasterBuildableInterface )------------------------------------- */
+
+
+ public function getHarbormasterBuildablePHID() {
+ return $this->loadActiveDiff()->getPHID();
+ }
+
+ public function getHarbormasterContainerPHID() {
+ return $this->getPHID();
+ }
+
}
Index: src/applications/harbormaster/controller/HarbormasterPlanRunController.php
===================================================================
--- src/applications/harbormaster/controller/HarbormasterPlanRunController.php
+++ src/applications/harbormaster/controller/HarbormasterPlanRunController.php
@@ -41,16 +41,10 @@
->withNames(array($v_name))
->executeOne();
- if ($object instanceof DifferentialRevision) {
- $revision = $object;
- $object = $object->loadActiveDiff();
+ if ($object instanceof HarbormasterBuildableInterface) {
$buildable
- ->setBuildablePHID($object->getPHID())
- ->setContainerPHID($revision->getPHID());
- } else if ($object instanceof PhabricatorRepositoryCommit) {
- $buildable
- ->setBuildablePHID($object->getPHID())
- ->setContainerPHID($object->getRepository()->getPHID());
+ ->setBuildablePHID($object->getHarbormasterBuildablePHID())
+ ->setContainerPHID($object->getHarbormasterContainerPHID());
} else {
$e_name = pht('Invalid');
$errors[] = pht('Enter the name of a revision or commit.');
@@ -62,6 +56,7 @@
if (!$errors) {
$buildable->save();
+ $buildable->applyPlan($plan);
$buildable_uri = '/B'.$buildable->getID();
return id(new AphrontRedirectResponse())->setURI($buildable_uri);
@@ -80,8 +75,12 @@
->setUser($viewer)
->appendRemarkupInstructions(
pht(
- "Enter the name of a commit or revision to run this plan on.\n\n".
- "For example: `rX123456` or `D123`"))
+ "Enter the name of a commit or revision to run this plan on (for ".
+ "example, `rX123456` or `D123`).\n\n".
+ "For more detailed output, you can also run manual builds from ".
+ "the command line:\n\n".
+ " phabricator/ $ ./bin/harbormaster build <object> --plan %s",
+ $plan->getID()))
->appendChild(
id(new AphrontFormTextControl())
->setLabel('Buildable Name')
@@ -90,7 +89,7 @@
->setValue($v_name));
$dialog = id(new AphrontDialogView())
- ->setWidth(AphrontDialogView::WIDTH_FORM)
+ ->setWidth(AphrontDialogView::WIDTH_FULL)
->setUser($viewer)
->setTitle($title)
->appendChild($form)
Index: src/applications/harbormaster/event/HarbormasterUIEventListener.php
===================================================================
--- src/applications/harbormaster/event/HarbormasterUIEventListener.php
+++ src/applications/harbormaster/event/HarbormasterUIEventListener.php
@@ -24,12 +24,19 @@
return;
}
- $target = null;
- if ($object instanceof PhabricatorRepositoryCommit) {
- $target = $object;
- } elseif ($object instanceof DifferentialRevision) {
- $target = $object->loadActiveDiff();
- } else {
+ if ($object instanceof HarbormasterBuildable) {
+ // Although HarbormasterBuildable implements the correct interface, it
+ // does not make sense to show a build's build status. In the best case
+ // it is meaningless, and in the worst case it's confusing.
+ return;
+ }
+
+ if (!($object instanceof HarbormasterBuildableInterface)) {
+ return;
+ }
+
+ $buildable_phid = $object->getBuildablePHID();
+ if (!$buildable_phid) {
return;
}
@@ -39,7 +46,8 @@
$buildables = id(new HarbormasterBuildableQuery())
->setViewer($user)
- ->withBuildablePHIDs(array($target->getPHID()))
+ ->withManualBuildables(false)
+ ->withBuildablePHIDs(array($buildable_phid))
->execute();
if (!$buildables) {
return;
@@ -62,8 +70,7 @@
foreach ($builds as $build) {
$item = new PHUIStatusItemView();
- $item->setTarget(
- $build_handles[$build->getPHID()]->renderLink());
+ $item->setTarget($build_handles[$build->getPHID()]->renderLink());
switch ($build->getBuildStatus()) {
case HarbormasterBuild::STATUS_INACTIVE:
Index: src/applications/harbormaster/interface/HarbormasterBuildableInterface.php
===================================================================
--- /dev/null
+++ src/applications/harbormaster/interface/HarbormasterBuildableInterface.php
@@ -0,0 +1,8 @@
+<?php
+
+interface HarbormasterBuildableInterface {
+
+ public function getHarbormasterBuildablePHID();
+ public function getHarbormasterContainerPHID();
+
+}
Index: src/applications/harbormaster/management/HarbormasterManagementBuildWorkflow.php
===================================================================
--- /dev/null
+++ src/applications/harbormaster/management/HarbormasterManagementBuildWorkflow.php
@@ -0,0 +1,92 @@
+<?php
+
+final class HarbormasterManagementBuildWorkflow
+ extends HarbormasterManagementWorkflow {
+
+ public function didConstruct() {
+ $this
+ ->setName('build')
+ ->setExamples('**build** [__options__] __buildable__ --plan __id__')
+ ->setSynopsis(pht('Run plan __id__ on __buildable__.'))
+ ->setArguments(
+ array(
+ array(
+ 'name' => 'plan',
+ 'param' => 'id',
+ 'help' => pht('ID of build plan to run.'),
+ ),
+ array(
+ 'name' => 'buildable',
+ 'wildcard' => true,
+ ),
+ ));
+ }
+
+ public function execute(PhutilArgumentParser $args) {
+ $viewer = PhabricatorUser::getOmnipotentUser();
+
+ $names = $args->getArg('buildable');
+ if (count($names) != 1) {
+ throw new PhutilArgumentUsageException(
+ pht('Specify exactly one buildable, by object name.'));
+ }
+
+ $name = head($names);
+
+ $buildable = id(new PhabricatorObjectQuery())
+ ->setViewer($viewer)
+ ->withNames($names)
+ ->executeOne();
+ if (!$buildable) {
+ throw new PhutilArgumentUsageException(
+ pht('No such buildable "%s"!', $name));
+ }
+
+ if (!($buildable instanceof HarbormasterBuildableInterface)) {
+ throw new PhutilArgumentUsageException(
+ pht('Object "%s" is not a buildable!', $name));
+ }
+
+ $plan_id = $args->getArg('plan');
+ if (!$plan_id) {
+ throw new PhutilArgumentUsageException(
+ pht('Use --plan to specify a build plan to run.'));
+ }
+
+ $plan = id(new HarbormasterBuildPlanQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($plan_id))
+ ->executeOne();
+ if (!$plan) {
+ throw new PhutilArgumentUsageException(
+ pht('Build plan "%s" does not exist.', $plan_id));
+ }
+
+ $console = PhutilConsole::getConsole();
+
+ $buildable = HarbormasterBuildable::initializeNewBuildable($viewer)
+ ->setIsManualBuildable(true)
+ ->setBuildablePHID($buildable->getHarbormasterBuildablePHID())
+ ->setContainerPHID($buildable->getHarbormasterContainerPHID())
+ ->save();
+
+ $console->writeOut(
+ "%s\n",
+ pht(
+ 'Applying plan %s to new buildable %s...',
+ $plan->getID(),
+ 'B'.$buildable->getID()));
+
+ $console->writeOut(
+ "\n %s\n\n",
+ PhabricatorEnv::getProductionURI('/B'.$buildable->getID()));
+
+ PhabricatorWorker::setRunAllTasksInProcess(true);
+ $buildable->applyPlan($plan);
+
+ $console->writeOut("%s\n", pht('Done.'));
+
+ return 0;
+ }
+
+}
Index: src/applications/harbormaster/management/HarbormasterManagementWorkflow.php
===================================================================
--- /dev/null
+++ src/applications/harbormaster/management/HarbormasterManagementWorkflow.php
@@ -0,0 +1,10 @@
+<?php
+
+abstract class HarbormasterManagementWorkflow
+ extends PhutilArgumentWorkflow {
+
+ public function isExecutable() {
+ return true;
+ }
+
+}
Index: src/applications/harbormaster/storage/HarbormasterBuildable.php
===================================================================
--- src/applications/harbormaster/storage/HarbormasterBuildable.php
+++ src/applications/harbormaster/storage/HarbormasterBuildable.php
@@ -1,7 +1,9 @@
<?php
final class HarbormasterBuildable extends HarbormasterDAO
- implements PhabricatorPolicyInterface {
+ implements
+ PhabricatorPolicyInterface,
+ HarbormasterBuildableInterface {
protected $buildablePHID;
protected $containerPHID;
@@ -86,21 +88,27 @@
continue;
}
- $build = HarbormasterBuild::initializeNewBuild(
- PhabricatorUser::getOmnipotentUser());
- $build->setBuildablePHID($buildable->getPHID());
- $build->setBuildPlanPHID($plan->getPHID());
- $build->setBuildStatus(HarbormasterBuild::STATUS_PENDING);
- $build->save();
-
- PhabricatorWorker::scheduleTask(
- 'HarbormasterBuildWorker',
- array(
- 'buildID' => $build->getID()
- ));
+ $buildable->applyPlan($plan);
}
}
+ public function applyPlan(HarbormasterBuildPlan $plan) {
+ $viewer = PhabricatorUser::getOmnipotentUser();
+ $build = HarbormasterBuild::initializeNewBuild($viewer)
+ ->setBuildablePHID($this->getPHID())
+ ->setBuildPlanPHID($plan->getPHID())
+ ->setBuildStatus(HarbormasterBuild::STATUS_PENDING)
+ ->save();
+
+ PhabricatorWorker::scheduleTask(
+ 'HarbormasterBuildWorker',
+ array(
+ 'buildID' => $build->getID()
+ ));
+
+ return $this;
+ }
+
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
@@ -184,4 +192,21 @@
'buildable.');
}
+
+
+/* -( HarbormasterBuildableInterface )------------------------------------- */
+
+
+ public function getHarbormasterBuildablePHID() {
+ // NOTE: This is essentially just for convenience, as it allows you create
+ // a copy of a buildable by specifying `B123` without bothering to go
+ // look up the underlying object.
+ return $this->getBuildablePHID();
+ }
+
+ public function getHarbormasterContainerPHID() {
+ return $this->getContainerPHID();
+ }
+
+
}
Index: src/applications/repository/storage/PhabricatorRepositoryCommit.php
===================================================================
--- src/applications/repository/storage/PhabricatorRepositoryCommit.php
+++ src/applications/repository/storage/PhabricatorRepositoryCommit.php
@@ -5,7 +5,8 @@
implements
PhabricatorPolicyInterface,
PhabricatorFlaggableInterface,
- PhabricatorTokenReceiverInterface {
+ PhabricatorTokenReceiverInterface,
+ HarbormasterBuildableInterface {
protected $repositoryID;
protected $phid;
@@ -231,4 +232,17 @@
return id(new PhabricatorRepositoryCommit())
->loadFromArray($dict);
}
+
+
+/* -( HarbormasterBuildableInterface )------------------------------------- */
+
+
+ public function getHarbormasterBuildablePHID() {
+ return $this->getPHID();
+ }
+
+ public function getHarbormasterContainerPHID() {
+ return $this->getRepository()->getPHID();
+ }
+
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 23, 10:25 AM (16 h, 14 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6777224
Default Alt Text
D7825.id17702.diff (17 KB)
Attached To
Mode
D7825: Add `bin/harbormaster` to make builds easier to debug
Attached
Detach File
Event Timeline
Log In to Comment