Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F90139
D7745.id17526.diff
All Users
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
8 KB
Referenced Files
None
Subscribers
None
D7745.id17526.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
@@ -2366,6 +2366,7 @@
'SlowvoteRemarkupRule' => 'applications/slowvote/remarkup/SlowvoteRemarkupRule.php',
'UploadArtifactBuildStepImplementation' => 'applications/harbormaster/step/UploadArtifactBuildStepImplementation.php',
'VariableBuildStepImplementation' => 'applications/harbormaster/step/VariableBuildStepImplementation.php',
+ 'WaitForPreviousBuildStepImplementation' => 'applications/harbormaster/step/WaitForPreviousBuildStepImplementation.php',
),
'function' =>
array(
@@ -5056,5 +5057,6 @@
'SlowvoteRemarkupRule' => 'PhabricatorRemarkupRuleObject',
'UploadArtifactBuildStepImplementation' => 'VariableBuildStepImplementation',
'VariableBuildStepImplementation' => 'BuildStepImplementation',
+ 'WaitForPreviousBuildStepImplementation' => 'BuildStepImplementation',
),
));
diff --git a/src/applications/harbormaster/controller/HarbormasterBuildViewController.php b/src/applications/harbormaster/controller/HarbormasterBuildViewController.php
--- a/src/applications/harbormaster/controller/HarbormasterBuildViewController.php
+++ b/src/applications/harbormaster/controller/HarbormasterBuildViewController.php
@@ -49,7 +49,10 @@
$targets = array();
foreach ($build_targets as $build_target) {
$header = id(new PHUIHeaderView())
- ->setHeader(pht('Build Target %d', $build_target->getID()))
+ ->setHeader(pht(
+ 'Build Target %d (%s)',
+ $build_target->getID(),
+ $build_target->getImplementation()->getName()))
->setUser($viewer);
$properties = new PHUIPropertyListView();
@@ -280,7 +283,7 @@
case HarbormasterBuild::STATUS_PENDING:
return pht('Pending');
case HarbormasterBuild::STATUS_WAITING:
- return pht('Waiting on Resource');
+ return pht('Waiting');
case HarbormasterBuild::STATUS_BUILDING:
return pht('Building');
case HarbormasterBuild::STATUS_PASSED:
diff --git a/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php b/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
--- a/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
+++ b/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
@@ -52,8 +52,8 @@
$item->addAttribute(pht('Pending'));
break;
case HarbormasterBuild::STATUS_WAITING:
- $item->setBarColor('blue');
- $item->addAttribute(pht('Waiting on Resource'));
+ $item->setBarColor('violet');
+ $item->addAttribute(pht('Waiting'));
break;
case HarbormasterBuild::STATUS_BUILDING:
$item->setBarColor('yellow');
diff --git a/src/applications/harbormaster/query/HarbormasterBuildQuery.php b/src/applications/harbormaster/query/HarbormasterBuildQuery.php
--- a/src/applications/harbormaster/query/HarbormasterBuildQuery.php
+++ b/src/applications/harbormaster/query/HarbormasterBuildQuery.php
@@ -8,6 +8,7 @@
private $buildStatuses;
private $buildablePHIDs;
private $buildPlanPHIDs;
+ private $idLessThan;
public function withIDs(array $ids) {
$this->ids = $ids;
@@ -34,6 +35,11 @@
return $this;
}
+ public function withIDLessThan($id) {
+ $this->idLessThan = $id;
+ return $this;
+ }
+
protected function loadPage() {
$table = new HarbormasterBuild();
$conn_r = $table->establishConnection('r');
@@ -133,6 +139,15 @@
$this->buildPlanPHIDs);
}
+ // This is probably susceptable to the odd / even ID situation. The
+ // only way to fix this would be to add a sequence column to build table.
+ if ($this->idLessThan) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'id < %d',
+ $this->idLessThan);
+ }
+
$where[] = $this->buildPagingClause($conn_r);
return $this->formatWhereClause($where);
diff --git a/src/applications/harbormaster/step/BuildStepImplementation.php b/src/applications/harbormaster/step/BuildStepImplementation.php
--- a/src/applications/harbormaster/step/BuildStepImplementation.php
+++ b/src/applications/harbormaster/step/BuildStepImplementation.php
@@ -53,7 +53,7 @@
/**
* Validate the current settings of this build step.
*/
- public function validate() {
+ public function validateSettings() {
return true;
}
diff --git a/src/applications/harbormaster/step/WaitForPreviousBuildStepImplementation.php b/src/applications/harbormaster/step/WaitForPreviousBuildStepImplementation.php
new file mode 100644
--- /dev/null
+++ b/src/applications/harbormaster/step/WaitForPreviousBuildStepImplementation.php
@@ -0,0 +1,127 @@
+<?php
+
+final class WaitForPreviousBuildStepImplementation
+ extends BuildStepImplementation {
+
+ public function getName() {
+ return pht('Wait for Previous Commits to Build');
+ }
+
+ public function getGenericDescription() {
+ return pht(
+ 'Wait for previous commits to finish building '.
+ 'before continuing.');
+ }
+
+ public function getDescription() {
+ return pht(
+ 'Wait for previous commits to finish building '.
+ 'before continuing.');
+ }
+
+ public function execute(
+ HarbormasterBuild $build,
+ HarbormasterBuildTarget $build_target) {
+
+ // We can only wait when building against commits.
+ $buildable = $build->getBuildable();
+ $object = $buildable->getBuildableObject();
+ if (!($object instanceof PhabricatorRepositoryCommit)) {
+ return;
+ }
+
+ // We are blocked until all previous builds finish.
+ $build->setBuildStatus(HarbormasterBuild::STATUS_WAITING);
+ $build->save();
+
+ // Block until all previous builds of the same build plan have
+ // finished.
+ $plan = $build->getBuildPlan();
+
+ $log = null;
+ $log_start = null;
+ $blockers = $this->getBlockers($object, $plan, $build);
+ while (count($blockers) > 0) {
+ if ($build->checkForCancellation()) {
+ if ($log !== null) {
+ $log->finalize($log_start);
+ }
+ return;
+ }
+
+ if ($log === null) {
+ $log = $build->createLog($build_target, "waiting", "blockers");
+ $log_start = $log->start();
+ }
+
+ $log->append("Blocked by: ".implode(",", $blockers)."\n");
+
+ sleep(1);
+ $blockers = $this->getBlockers($object, $plan, $build);
+ }
+ if ($log !== null) {
+ $log->finalize($log_start);
+ }
+
+ // Move back into building status.
+ $build->setBuildStatus(HarbormasterBuild::STATUS_BUILDING);
+ $build->save();
+ }
+
+ private function getBlockers(
+ PhabricatorRepositoryCommit $commit,
+ HarbormasterBuildPlan $plan,
+ HarbormasterBuild $source) {
+
+ $call = new ConduitCall(
+ 'diffusion.commitparentsquery',
+ array(
+ 'commit' => $commit->getCommitIdentifier(),
+ 'callsign' => $commit->getRepository()->getCallsign()
+ ));
+ $call->setUser(PhabricatorUser::getOmnipotentUser());
+ $parents = $call->execute();
+
+ $hashes = array();
+ foreach ($parents as $parent => $obj) {
+ $hashes[] = $parent;
+ }
+
+ $parents = id(new DiffusionCommitQuery())
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withRepository($commit->getRepository())
+ ->withIdentifiers($hashes)
+ ->execute();
+
+ $blockers = array();
+
+ $build_objects = array();
+ foreach ($parents as $parent) {
+ if (!$parent->isImported()) {
+ $blockers[] = pht('Commit %s', $parent->getCommitIdentifier());
+ } else {
+ $build_objects[] = $parent->getPHID();
+ }
+ }
+
+ $buildables = id(new HarbormasterBuildableQuery())
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withBuildablePHIDs($build_objects)
+ ->execute();
+ $buildable_phids = mpull($buildables, 'getPHID');
+
+ $builds = id(new HarbormasterBuildQuery())
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withBuildablePHIDs($buildable_phids)
+ ->withBuildPlanPHIDs(array($plan->getPHID()))
+ ->execute();
+
+ foreach ($builds as $build) {
+ if ($build->isBuilding()) {
+ $blockers[] = pht('Build %d', $build->getID());
+ }
+ }
+
+ return $blockers;
+ }
+}
diff --git a/src/applications/harbormaster/storage/build/HarbormasterBuild.php b/src/applications/harbormaster/storage/build/HarbormasterBuild.php
--- a/src/applications/harbormaster/storage/build/HarbormasterBuild.php
+++ b/src/applications/harbormaster/storage/build/HarbormasterBuild.php
@@ -94,6 +94,13 @@
return $this->assertAttached($this->buildPlan);
}
+ public function isBuilding() {
+ return $this->getBuildStatus() === self::STATUS_PENDING ||
+ $this->getBuildStatus() === self::STATUS_WAITING ||
+ $this->getBuildStatus() === self::STATUS_BUILDING ||
+ $this->getCancelRequested();
+ }
+
public function createLog(
HarbormasterBuildTarget $build_target,
$log_source,
File Metadata
Details
Attached
Mime Type
text/x-diff
Storage Engine
amazon-s3
Storage Format
Raw Data
Storage Handle
phabricator/p3/be/nprygwnnlbjp6nvm
Default Alt Text
D7745.id17526.diff (8 KB)
Attached To
Mode
D7745: Implement "Wait for Previous Builds" build step
Attached
Detach File
Event Timeline
Log In to Comment