@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add a warning to revision timelines when changes land with ongoing or failed builds

Summary:
Ref T13258. The general idea here is "if arc land prompted you and you hit 'y', you get a warning about it on the timeline".

This is similar to the existing warning about landing revisions in the wrong state and hitting "y" to get through that. See D18808, previously.

These warnings make it easier to catch process issues at a glance, especially because the overall build status is now more complicated (and may legally include some failures on tests which are marked as unimportant).

The transaction stores which builds had problems, but I'm not doing anything to render that for now. I think you can usually figure it out from the UI already; if not, we could refine this.

Test Plan:
- Used `bin/differential attach-commit` to trigger extraction/attachment.
- Attached a commit to a revision with various build states, and various build plan "Warn When Landing" flags.
- Got sensible warnings and non-warnings based on "Warn When Landing" setting.

{F6251631}

Reviewers: amckinley

Reviewed By: amckinley

Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam

Maniphest Tasks: T13258

Differential Revision: https://secure.phabricator.com/D20239

+149 -6
+2
src/__phutil_library_map__.php
··· 653 653 'DifferentialRevisionUpdateTransaction' => 'applications/differential/xaction/DifferentialRevisionUpdateTransaction.php', 654 654 'DifferentialRevisionViewController' => 'applications/differential/controller/DifferentialRevisionViewController.php', 655 655 'DifferentialRevisionVoidTransaction' => 'applications/differential/xaction/DifferentialRevisionVoidTransaction.php', 656 + 'DifferentialRevisionWrongBuildsTransaction' => 'applications/differential/xaction/DifferentialRevisionWrongBuildsTransaction.php', 656 657 'DifferentialRevisionWrongStateTransaction' => 'applications/differential/xaction/DifferentialRevisionWrongStateTransaction.php', 657 658 'DifferentialSchemaSpec' => 'applications/differential/storage/DifferentialSchemaSpec.php', 658 659 'DifferentialSetDiffPropertyConduitAPIMethod' => 'applications/differential/conduit/DifferentialSetDiffPropertyConduitAPIMethod.php', ··· 6181 6182 'DifferentialRevisionUpdateTransaction' => 'DifferentialRevisionTransactionType', 6182 6183 'DifferentialRevisionViewController' => 'DifferentialController', 6183 6184 'DifferentialRevisionVoidTransaction' => 'DifferentialRevisionTransactionType', 6185 + 'DifferentialRevisionWrongBuildsTransaction' => 'DifferentialRevisionTransactionType', 6184 6186 'DifferentialRevisionWrongStateTransaction' => 'DifferentialRevisionTransactionType', 6185 6187 'DifferentialSchemaSpec' => 'PhabricatorConfigSchemaSpec', 6186 6188 'DifferentialSetDiffPropertyConduitAPIMethod' => 'DifferentialConduitAPIMethod',
+95
src/applications/differential/engine/DifferentialDiffExtractionEngine.php
··· 285 285 ->setNewValue($revision->getModernRevisionStatus()); 286 286 } 287 287 288 + $concerning_builds = $this->loadConcerningBuilds($revision); 289 + if ($concerning_builds) { 290 + $build_list = array(); 291 + foreach ($concerning_builds as $build) { 292 + $build_list[] = array( 293 + 'phid' => $build->getPHID(), 294 + 'status' => $build->getBuildStatus(), 295 + ); 296 + } 297 + 298 + $wrong_builds = 299 + DifferentialRevisionWrongBuildsTransaction::TRANSACTIONTYPE; 300 + 301 + $xactions[] = id(new DifferentialTransaction()) 302 + ->setTransactionType($wrong_builds) 303 + ->setNewValue($build_list); 304 + } 305 + 288 306 $type_update = DifferentialRevisionUpdateTransaction::TRANSACTIONTYPE; 289 307 290 308 $xactions[] = id(new DifferentialTransaction()) ··· 320 338 } 321 339 322 340 return $result_data; 341 + } 342 + 343 + private function loadConcerningBuilds(DifferentialRevision $revision) { 344 + $viewer = $this->getViewer(); 345 + $diff = $revision->getActiveDiff(); 346 + 347 + $buildables = id(new HarbormasterBuildableQuery()) 348 + ->setViewer($viewer) 349 + ->withBuildablePHIDs(array($diff->getPHID())) 350 + ->needBuilds(true) 351 + ->withManualBuildables(false) 352 + ->execute(); 353 + if (!$buildables) { 354 + return array(); 355 + } 356 + 357 + 358 + $land_key = HarbormasterBuildPlanBehavior::BEHAVIOR_LANDWARNING; 359 + $behavior = HarbormasterBuildPlanBehavior::getBehavior($land_key); 360 + 361 + $key_never = HarbormasterBuildPlanBehavior::LANDWARNING_NEVER; 362 + $key_building = HarbormasterBuildPlanBehavior::LANDWARNING_IF_BUILDING; 363 + $key_complete = HarbormasterBuildPlanBehavior::LANDWARNING_IF_COMPLETE; 364 + 365 + $concerning_builds = array(); 366 + foreach ($buildables as $buildable) { 367 + $builds = $buildable->getBuilds(); 368 + foreach ($builds as $build) { 369 + $plan = $build->getBuildPlan(); 370 + $option = $behavior->getPlanOption($plan); 371 + $behavior_value = $option->getKey(); 372 + 373 + $if_never = ($behavior_value === $key_never); 374 + if ($if_never) { 375 + continue; 376 + } 377 + 378 + $if_building = ($behavior_value === $key_building); 379 + if ($if_building && $build->isComplete()) { 380 + continue; 381 + } 382 + 383 + $if_complete = ($behavior_value === $key_complete); 384 + if ($if_complete) { 385 + if (!$build->isComplete()) { 386 + continue; 387 + } 388 + 389 + // TODO: If you "arc land" and a build with "Warn: If Complete" 390 + // is still running, you may not see a warning, and push the revision 391 + // in good faith. The build may then complete before we get here, so 392 + // we now see a completed, failed build. 393 + 394 + // For now, just err on the side of caution and assume these builds 395 + // were in a good state when we prompted the user, even if they're in 396 + // a bad state now. 397 + 398 + // We could refine this with a rule like "if the build finished 399 + // within a couple of minutes before the push happened, assume it was 400 + // in good faith", but we don't currently have an especially 401 + // convenient way to check when the build finished or when the commit 402 + // was pushed or discovered, and this would create some issues in 403 + // cases where the repository is observed and the fetch pipeline 404 + // stalls for a while. 405 + 406 + continue; 407 + } 408 + 409 + if ($build->isPassed()) { 410 + continue; 411 + } 412 + 413 + $concerning_builds[] = $build; 414 + } 415 + } 416 + 417 + return $concerning_builds; 323 418 } 324 419 325 420 }
+37
src/applications/differential/xaction/DifferentialRevisionWrongBuildsTransaction.php
··· 1 + <?php 2 + 3 + final class DifferentialRevisionWrongBuildsTransaction 4 + extends DifferentialRevisionTransactionType { 5 + 6 + const TRANSACTIONTYPE = 'differential.builds.wrong'; 7 + 8 + public function generateOldValue($object) { 9 + return null; 10 + } 11 + 12 + public function generateNewValue($object, $value) { 13 + return $value; 14 + } 15 + 16 + public function getIcon() { 17 + return 'fa-exclamation'; 18 + } 19 + 20 + public function getColor() { 21 + return 'pink'; 22 + } 23 + 24 + public function getActionStrength() { 25 + return 4; 26 + } 27 + 28 + public function getTitle() { 29 + return pht( 30 + 'This revision was landed with ongoing or failed builds.'); 31 + } 32 + 33 + public function shouldHideForFeed() { 34 + return true; 35 + } 36 + 37 + }
+15 -6
src/applications/harbormaster/plan/HarbormasterBuildPlanBehavior.php
··· 27 27 const BUILDABLE_IF_BUILDING = 'building'; 28 28 const BUILDABLE_NEVER = 'never'; 29 29 30 + const BEHAVIOR_LANDWARNING = 'arc-land'; 31 + const LANDWARNING_ALWAYS = 'always'; 32 + const LANDWARNING_IF_BUILDING = 'building'; 33 + const LANDWARNING_IF_COMPLETE = 'complete'; 34 + const LANDWARNING_NEVER = 'never'; 35 + 30 36 public function setKey($key) { 31 37 $this->key = $key; 32 38 return $this; ··· 176 182 177 183 $land_options = array( 178 184 id(new HarbormasterBuildPlanBehaviorOption()) 179 - ->setKey('always') 185 + ->setKey(self::LANDWARNING_ALWAYS) 180 186 ->setIcon('fa-check-circle-o green') 181 187 ->setName(pht('Always')) 182 188 ->setIsDefault(true) ··· 185 191 '"arc land" warns if the build is still running or has '. 186 192 'failed.')), 187 193 id(new HarbormasterBuildPlanBehaviorOption()) 188 - ->setKey('building') 194 + ->setKey(self::LANDWARNING_IF_BUILDING) 189 195 ->setIcon('fa-pause-circle-o yellow') 190 196 ->setName(pht('If Building')) 191 197 ->setDescription( ··· 193 199 '"arc land" warns if the build is still running, but ignores '. 194 200 'the build if it has failed.')), 195 201 id(new HarbormasterBuildPlanBehaviorOption()) 196 - ->setKey('complete') 202 + ->setKey(self::LANDWARNING_IF_COMPLETE) 197 203 ->setIcon('fa-dot-circle-o yellow') 198 204 ->setName(pht('If Complete')) 199 205 ->setDescription( ··· 201 207 '"arc land" warns if the build has failed, but ignores the '. 202 208 'build if it is still running.')), 203 209 id(new HarbormasterBuildPlanBehaviorOption()) 204 - ->setKey('never') 210 + ->setKey(self::LANDWARNING_NEVER) 205 211 ->setIcon('fa-circle-o red') 206 212 ->setName(pht('Never')) 207 213 ->setDescription( ··· 296 302 'revision, even if builds have failed or are still in progress.')) 297 303 ->setOptions($draft_options), 298 304 id(new self()) 299 - ->setKey('arc-land') 305 + ->setKey(self::BEHAVIOR_LANDWARNING) 300 306 ->setName(pht('Warn When Landing')) 301 307 ->setEditInstructions( 302 308 pht( ··· 312 318 'for it) or the outcome is not important.'. 313 319 "\n\n". 314 320 'This warning is only advisory. Users may always elect to ignore '. 315 - 'this warning and continue, even if builds have failed.')) 321 + 'this warning and continue, even if builds have failed.'. 322 + "\n\n". 323 + 'This setting also affects the warning that is published to '. 324 + 'revisions when commits land with ongoing or failed builds.')) 316 325 ->setOptions($land_options), 317 326 id(new self()) 318 327 ->setKey(self::BEHAVIOR_BUILDABLE)