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:
		| @@ -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; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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'; | ||||||
|  |   } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 epriestley
					epriestley