Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14040187
D19279.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
11 KB
Referenced Files
None
Subscribers
None
D19279.diff
View Options
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1324,6 +1324,7 @@
'HarbormasterLogWorker' => 'applications/harbormaster/worker/HarbormasterLogWorker.php',
'HarbormasterManagementArchiveLogsWorkflow' => 'applications/harbormaster/management/HarbormasterManagementArchiveLogsWorkflow.php',
'HarbormasterManagementBuildWorkflow' => 'applications/harbormaster/management/HarbormasterManagementBuildWorkflow.php',
+ 'HarbormasterManagementPublishWorkflow' => 'applications/harbormaster/management/HarbormasterManagementPublishWorkflow.php',
'HarbormasterManagementRebuildLogWorkflow' => 'applications/harbormaster/management/HarbormasterManagementRebuildLogWorkflow.php',
'HarbormasterManagementRestartWorkflow' => 'applications/harbormaster/management/HarbormasterManagementRestartWorkflow.php',
'HarbormasterManagementUpdateWorkflow' => 'applications/harbormaster/management/HarbormasterManagementUpdateWorkflow.php',
@@ -6675,6 +6676,7 @@
'HarbormasterLogWorker' => 'HarbormasterWorker',
'HarbormasterManagementArchiveLogsWorkflow' => 'HarbormasterManagementWorkflow',
'HarbormasterManagementBuildWorkflow' => 'HarbormasterManagementWorkflow',
+ 'HarbormasterManagementPublishWorkflow' => 'HarbormasterManagementWorkflow',
'HarbormasterManagementRebuildLogWorkflow' => 'HarbormasterManagementWorkflow',
'HarbormasterManagementRestartWorkflow' => 'HarbormasterManagementWorkflow',
'HarbormasterManagementUpdateWorkflow' => 'HarbormasterManagementWorkflow',
diff --git a/src/applications/harbormaster/engine/HarbormasterBuildEngine.php b/src/applications/harbormaster/engine/HarbormasterBuildEngine.php
--- a/src/applications/harbormaster/engine/HarbormasterBuildEngine.php
+++ b/src/applications/harbormaster/engine/HarbormasterBuildEngine.php
@@ -489,6 +489,8 @@
}
}
+ $old = clone $buildable;
+
// Don't update the buildable status if we're still preparing builds: more
// builds may still be scheduled shortly, so even if every build we know
// about so far has passed, that doesn't mean the buildable has actually
@@ -515,8 +517,7 @@
$new_status = HarbormasterBuildableStatus::STATUS_BUILDING;
}
- $old_status = $buildable->getBuildableStatus();
- $did_update = ($old_status != $new_status);
+ $did_update = ($old->getBuildableStatus() !== $new_status);
if ($did_update) {
$buildable->setBuildableStatus($new_status);
$buildable->save();
@@ -530,81 +531,45 @@
return;
}
- // If we changed the buildable status, try to post a transaction to the
- // object about it. We can safely do this outside of the locked region.
+ $this->publishBuildable($old, $buildable);
+ }
- // NOTE: We only post transactions for automatic buildables, not for
- // manual ones: manual builds are test builds, whoever is doing tests
- // can look at the results themselves, and other users generally don't
- // care about the outcome.
+ public function publishBuildable(
+ HarbormasterBuildable $old,
+ HarbormasterBuildable $new) {
- $should_publish =
- ($did_update) &&
- ($new_status != HarbormasterBuildableStatus::STATUS_BUILDING) &&
- (!$buildable->getIsManualBuildable());
+ $viewer = $this->getViewer();
- if (!$should_publish) {
- return;
- }
+ // Publish the buildable. We publish buildables even if they haven't
+ // changed status in Harbormaster because applications may care about
+ // different things than Harbormaster does. For example, Differential
+ // does not care about local lint and unit tests when deciding whether
+ // a revision should move out of draft or not.
+
+ // NOTE: We're publishing both automatic and manual buildables. Buildable
+ // objects should generally ignore manual buildables, but it's up to them
+ // to decide.
$object = id(new PhabricatorObjectQuery())
->setViewer($viewer)
- ->withPHIDs(array($buildable->getBuildablePHID()))
+ ->withPHIDs(array($new->getBuildablePHID()))
->executeOne();
if (!$object) {
return;
}
- $publish_phid = $object->getHarbormasterPublishablePHID();
- if (!$publish_phid) {
- return;
- }
-
- if ($publish_phid === $object->getPHID()) {
- $publish = $object;
- } else {
- $publish = id(new PhabricatorObjectQuery())
- ->setViewer($viewer)
- ->withPHIDs(array($publish_phid))
- ->executeOne();
- if (!$publish) {
- return;
- }
- }
+ $engine = HarbormasterBuildableEngine::newForObject($object, $viewer);
- if (!($publish instanceof PhabricatorApplicationTransactionInterface)) {
- return;
- }
-
- $template = $publish->getApplicationTransactionTemplate();
- if (!$template) {
- return;
- }
-
- $template
- ->setTransactionType(PhabricatorTransactions::TYPE_BUILDABLE)
- ->setMetadataValue(
- 'harbormaster:buildablePHID',
- $buildable->getPHID())
- ->setOldValue($old_status)
- ->setNewValue($new_status);
+ $daemon_source = PhabricatorContentSource::newForSource(
+ PhabricatorDaemonContentSource::SOURCECONST);
$harbormaster_phid = id(new PhabricatorHarbormasterApplication())
->getPHID();
- $daemon_source = PhabricatorContentSource::newForSource(
- PhabricatorDaemonContentSource::SOURCECONST);
-
- $editor = $publish->getApplicationTransactionEditor()
- ->setActor($viewer)
+ $engine
->setActingAsPHID($harbormaster_phid)
->setContentSource($daemon_source)
- ->setContinueOnNoEffect(true)
- ->setContinueOnMissingFields(true);
-
- $editor->applyTransactions(
- $publish->getApplicationTransactionObject(),
- array($template));
+ ->publishBuildable($old, $new);
}
private function releaseAllArtifacts(HarbormasterBuild $build) {
diff --git a/src/applications/harbormaster/engine/HarbormasterBuildableEngine.php b/src/applications/harbormaster/engine/HarbormasterBuildableEngine.php
--- a/src/applications/harbormaster/engine/HarbormasterBuildableEngine.php
+++ b/src/applications/harbormaster/engine/HarbormasterBuildableEngine.php
@@ -1,4 +1,101 @@
<?php
abstract class HarbormasterBuildableEngine
- extends Phobject {}
+ extends Phobject {
+
+ private $viewer;
+ private $actingAsPHID;
+ private $contentSource;
+ private $object;
+
+ final public function setViewer(PhabricatorUser $viewer) {
+ $this->viewer = $viewer;
+ return $this;
+ }
+
+ final public function getViewer() {
+ return $this->viewer;
+ }
+
+ final public function setActingAsPHID($acting_as_phid) {
+ $this->actingAsPHID = $acting_as_phid;
+ return $this;
+ }
+
+ final public function getActingAsPHID() {
+ return $this->actingAsPHID;
+ }
+
+ final public function setContentSource(
+ PhabricatorContentSource $content_source) {
+ $this->contentSource = $content_source;
+ return $this;
+ }
+
+ final public function getContentSource() {
+ return $this->contentSource;
+ }
+
+ final public function setObject(HarbormasterBuildableInterface $object) {
+ $this->object = $object;
+ return $this;
+ }
+
+ final public function getObject() {
+ return $this->object;
+ }
+
+ final public function publishBuildable(
+ HarbormasterBuildable $old,
+ HarbormasterBuildable $new) {
+ return;
+ }
+
+ final public static function newForObject(
+ HarbormasterBuildableInterface $object,
+ PhabricatorUser $viewer) {
+ return $object->newBuildableEngine()
+ ->setViewer($viewer)
+ ->setObject($object);
+ }
+
+ final protected function newEditor() {
+ $publishable = $this->getObject();
+
+ $viewer = $this->getViewer();
+
+ $editor = $publishable->getApplicationTransactionEditor()
+ ->setActor($viewer)
+ ->setContinueOnNoEffect(true)
+ ->setContinueOnMissingFields(true);
+
+ $acting_as_phid = $this->getActingAsPHID();
+ if ($acting_as_phid !== null) {
+ $editor->setActingAsPHID($acting_as_phid);
+ }
+
+ $content_source = $this->getContentSource();
+ if ($content_source !== null) {
+ $editor->setContentSource($content_source);
+ }
+
+ return $editor;
+ }
+
+ final protected function newTransaction() {
+ $publishable = $this->getObject();
+
+ return $publishable->getApplicationTransactionTemplate();
+ }
+
+ final protected function applyTransactions(array $xactions) {
+ $publishable = $this->getObject();
+ $editor = $this->newEditor();
+
+ $editor->applyTransactions(
+ $publishable->getApplicationTransactionObject(),
+ $xactions);
+ }
+
+
+}
diff --git a/src/applications/harbormaster/management/HarbormasterManagementPublishWorkflow.php b/src/applications/harbormaster/management/HarbormasterManagementPublishWorkflow.php
new file mode 100644
--- /dev/null
+++ b/src/applications/harbormaster/management/HarbormasterManagementPublishWorkflow.php
@@ -0,0 +1,87 @@
+<?php
+
+final class HarbormasterManagementPublishWorkflow
+ extends HarbormasterManagementWorkflow {
+
+ protected function didConstruct() {
+ $this
+ ->setName('publish')
+ ->setExamples(pht('**publish** __buildable__ ...'))
+ ->setSynopsis(
+ pht(
+ 'Publish a buildable. This is primarily useful for developing '.
+ 'and debugging applications which have buildable objects.'))
+ ->setArguments(
+ array(
+ array(
+ 'name' => 'buildable',
+ 'wildcard' => true,
+ ),
+ ));
+ }
+
+ public function execute(PhutilArgumentParser $args) {
+ $viewer = $this->getViewer();
+
+ $buildable_names = $args->getArg('buildable');
+ if (!$buildable_names) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'Name one or more buildables to publish, like "B123".'));
+ }
+
+ $query = id(new PhabricatorObjectQuery())
+ ->setViewer($viewer)
+ ->withNames($buildable_names);
+
+ $query->execute();
+
+ $result_map = $query->getNamedResults();
+
+ foreach ($buildable_names as $name) {
+ if (!isset($result_map[$name])) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'Argument "%s" does not name a buildable. Provide one or more '.
+ 'valid buildable monograms or PHIDs.',
+ $name));
+ }
+ }
+
+ foreach ($result_map as $name => $result) {
+ if (!($result instanceof HarbormasterBuildable)) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'Object "%s" is not a HarbormasterBuildable (it is a "%s"). '.
+ 'Name one or more buildables to publish, like "B123".',
+ get_class($result)));
+ }
+ }
+
+ foreach ($result_map as $buildable) {
+ echo tsprintf(
+ "%s\n",
+ pht(
+ 'Publishing "%s"...',
+ $buildable->getMonogram()));
+
+ // Reload the buildable to pick up builds.
+ $buildable = id(new HarbormasterBuildableQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($buildable->getID()))
+ ->needBuilds(true)
+ ->executeOne();
+
+ $engine = id(new HarbormasterBuildEngine())
+ ->setViewer($viewer)
+ ->publishBuildable($buildable, $buildable);
+ }
+
+ echo tsprintf(
+ "%s\n",
+ pht('Done.'));
+
+ return 0;
+ }
+
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 12, 7:41 AM (5 d, 8 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6762234
Default Alt Text
D19279.diff (11 KB)
Attached To
Mode
D19279: Move structural build publishing logic to BuildEngine, provide "bin/harbormaster publish"
Attached
Detach File
Event Timeline
Log In to Comment