1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-09-22 18:28:47 +02:00
phorge-phorge/src/applications/harbormaster/step/WaitForPreviousBuildStepImplementation.php
epriestley 996930da2a Improve several exception behaviors for Harbormaster workers
Summary:
Ref T2015. Several fixes:

  - `checkForCancellation()` no longer exists, and isn't relevant for resumable stops. Throw it away for now.
  - Fix an issue where a build could pass even if the final step failed.
  - `phlog()` exceptions so they show up in `bin/harbormaster` and the daemon logs.
  - Write an exception log if a step fails.
  - Add a "throw an exception" step to debug this stuff more easily.

Test Plan:
  - Grepped for `checkForCancellation()`.
  - Ran a failing build where the final step caused the failure.
  - Observed `phlog()` in `bin/harbormaster` output.
  - Observed log in web UI:

{F101168}

Reviewers: btrahan, hach-que

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2015

Differential Revision: https://secure.phabricator.com/D7935
2014-01-13 12:21:49 -08:00

110 lines
3.1 KiB
PHP

<?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 the current plan '.
'before continuing.');
}
public function getDescription() {
return pht(
'Wait for previous commits to finish building the current plan '.
'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;
}
// 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 ($log === null) {
$log = $build->createLog($build_target, "waiting", "blockers");
$log_start = $log->start();
}
$log->append("Blocked by: ".implode(",", $blockers)."\n");
// TODO: This should fail temporarily instead after setting the target to
// waiting, and thereby push the build into a waiting status.
sleep(1);
$blockers = $this->getBlockers($object, $plan, $build);
}
if ($log !== null) {
$log->finalize($log_start);
}
}
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();
$parents = id(new DiffusionCommitQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withRepository($commit->getRepository())
->withIdentifiers($parents)
->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)
->withManualBuildables(false)
->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->isComplete()) {
$blockers[] = pht('Build %d', $build->getID());
}
}
return $blockers;
}
}