1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-09 22:31:03 +01:00

Simply how Differential drafts ignore Harbormaster autobuilds

Summary:
Ref T2543. When a revision is created, we check if any builds are waiting/failed, and submit it for review immediately if we aren't waiting for anything.

In doing this, we ignore builds with only autotargets, since these are client-side and failures from local `arc lint` / `arc unit` should not count (the user has already chosen to ignore/skip them).

The way we do this has some issues:

  - Herald may have started builds, but they may still be PENDING and not have any targets yet. In this case, we'll see "no non-autotargets" and ignore the build, which is wrong.
  - We have to load targets but don't really care about them, which is more work than we really need to do.
  - And it's kind of complex, too.

Instead, just let `BuildQuery` filter out "autobuilds" (builds generated from autoplans) with a JOIN.

Test Plan: Ran `arc diff` with builds configured, got a clean "Draft" state instead of an incorrect promotion directly to "Needs Review".

Reviewers: amckinley

Reviewed By: amckinley

Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam

Maniphest Tasks: T2543

Differential Revision: https://secure.phabricator.com/D18721
This commit is contained in:
epriestley 2017-10-20 11:20:02 -07:00
parent 672247eff3
commit 63e6b2553e
2 changed files with 51 additions and 29 deletions

View file

@ -721,9 +721,10 @@ final class DifferentialRevision extends DifferentialDAO
return array(); return array();
} }
$builds = id(new HarbormasterBuildQuery()) return id(new HarbormasterBuildQuery())
->setViewer($viewer) ->setViewer($viewer)
->withBuildablePHIDs(mpull($buildables, 'getPHID')) ->withBuildablePHIDs(mpull($buildables, 'getPHID'))
->withAutobuilds(false)
->withBuildStatuses( ->withBuildStatuses(
array( array(
HarbormasterBuildStatus::STATUS_INACTIVE, HarbormasterBuildStatus::STATUS_INACTIVE,
@ -735,29 +736,7 @@ final class DifferentialRevision extends DifferentialDAO
HarbormasterBuildStatus::STATUS_PAUSED, HarbormasterBuildStatus::STATUS_PAUSED,
HarbormasterBuildStatus::STATUS_DEADLOCKED, HarbormasterBuildStatus::STATUS_DEADLOCKED,
)) ))
->needBuildTargets(true)
->execute(); ->execute();
if (!$builds) {
return array();
}
$active = array();
foreach ($builds as $key => $build) {
foreach ($build->getBuildTargets() as $target) {
if ($target->isAutotarget()) {
// Ignore autotargets when looking for active of failed builds. If
// local tests fail and you continue anyway, you don't need to
// double-confirm them.
continue;
}
// This build has at least one real target that's doing something.
$active[$key] = $build;
break;
}
}
return $active;
} }

View file

@ -10,6 +10,7 @@ final class HarbormasterBuildQuery
private $buildPlanPHIDs; private $buildPlanPHIDs;
private $initiatorPHIDs; private $initiatorPHIDs;
private $needBuildTargets; private $needBuildTargets;
private $autobuilds;
public function withIDs(array $ids) { public function withIDs(array $ids) {
$this->ids = $ids; $this->ids = $ids;
@ -41,6 +42,11 @@ final class HarbormasterBuildQuery
return $this; return $this;
} }
public function withAutobuilds($with_autobuilds) {
$this->autobuilds = $with_autobuilds;
return $this;
}
public function needBuildTargets($need_targets) { public function needBuildTargets($need_targets) {
$this->needBuildTargets = $need_targets; $this->needBuildTargets = $need_targets;
return $this; return $this;
@ -141,50 +147,87 @@ final class HarbormasterBuildQuery
if ($this->ids !== null) { if ($this->ids !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn, $conn,
'id IN (%Ld)', 'b.id IN (%Ld)',
$this->ids); $this->ids);
} }
if ($this->phids !== null) { if ($this->phids !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn, $conn,
'phid in (%Ls)', 'b.phid in (%Ls)',
$this->phids); $this->phids);
} }
if ($this->buildStatuses !== null) { if ($this->buildStatuses !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn, $conn,
'buildStatus in (%Ls)', 'b.buildStatus in (%Ls)',
$this->buildStatuses); $this->buildStatuses);
} }
if ($this->buildablePHIDs !== null) { if ($this->buildablePHIDs !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn, $conn,
'buildablePHID IN (%Ls)', 'b.buildablePHID IN (%Ls)',
$this->buildablePHIDs); $this->buildablePHIDs);
} }
if ($this->buildPlanPHIDs !== null) { if ($this->buildPlanPHIDs !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn, $conn,
'buildPlanPHID IN (%Ls)', 'b.buildPlanPHID IN (%Ls)',
$this->buildPlanPHIDs); $this->buildPlanPHIDs);
} }
if ($this->initiatorPHIDs !== null) { if ($this->initiatorPHIDs !== null) {
$where[] = qsprintf( $where[] = qsprintf(
$conn, $conn,
'initiatorPHID IN (%Ls)', 'b.initiatorPHID IN (%Ls)',
$this->initiatorPHIDs); $this->initiatorPHIDs);
} }
if ($this->autobuilds !== null) {
if ($this->autobuilds) {
$where[] = qsprintf(
$conn,
'p.planAutoKey IS NOT NULL');
} else {
$where[] = qsprintf(
$conn,
'p.planAutoKey IS NULL');
}
}
return $where; return $where;
} }
protected function buildJoinClauseParts(AphrontDatabaseConnection $conn) {
$joins = parent::buildJoinClauseParts($conn);
if ($this->shouldJoinPlanTable()) {
$joins[] = qsprintf(
$conn,
'JOIN %T p ON b.buildPlanPHID = p.phid',
id(new HarbormasterBuildPlan())->getTableName());
}
return $joins;
}
private function shouldJoinPlanTable() {
if ($this->autobuilds !== null) {
return true;
}
return false;
}
public function getQueryApplicationClass() { public function getQueryApplicationClass() {
return 'PhabricatorHarbormasterApplication'; return 'PhabricatorHarbormasterApplication';
} }
protected function getPrimaryTableAlias() {
return 'b';
}
} }