@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 UI element for reviewing older generations of Harbormaster builds

Summary:
See PHI446. Ref T13088. Currently, there's no way to access older generations of a build unless you know the secret `?g=1` URI magic.

When a build has multiple generations, show a history table and let users click to see older run information.

This is currently very basic. It would be nice to show when each generation started, who started/restarted it, and what the build status was at the time the build was restarted. There's currently no convenient source for this information so just add a bare-bones, working version of this for now.

Test Plan:
Viewed pending, single-run and multi-restart builds. Saw table on builds with more than one generation. Clicked table entries to see different build data.

{F5471160}

Subscribers: PHID-OPKG-gm6ozazyms6q6i22gyam

Maniphest Tasks: T13088

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

+109 -18
+2 -1
src/applications/harbormaster/application/PhabricatorHarbormasterApplication.php
··· 71 71 ), 72 72 'build/' => array( 73 73 $this->getQueryRoutePattern() => 'HarbormasterBuildListController', 74 - '(?P<id>\d+)/' => 'HarbormasterBuildViewController', 74 + '(?P<id>\d+)/(?:(?P<generation>\d+)/)?' 75 + => 'HarbormasterBuildViewController', 75 76 '(?P<action>pause|resume|restart|abort)/'. 76 77 '(?P<id>\d+)/(?:(?P<via>[^/]+)/)?' 77 78 => 'HarbormasterBuildActionController',
+106 -16
src/applications/harbormaster/controller/HarbormasterBuildViewController.php
··· 8 8 $viewer = $request->getUser(); 9 9 10 10 $id = $request->getURIData('id'); 11 - $generation = $request->getInt('g'); 12 11 13 12 $build = id(new HarbormasterBuildQuery()) 14 13 ->setViewer($viewer) ··· 21 20 require_celerity_resource('harbormaster-css'); 22 21 23 22 $title = pht('Build %d', $id); 23 + $warnings = array(); 24 24 25 25 $page_header = id(new PHUIHeaderView()) 26 26 ->setHeader($title) ··· 28 28 ->setPolicyObject($build) 29 29 ->setHeaderIcon('fa-cubes'); 30 30 31 - if ($build->isRestarting()) { 31 + $is_restarting = $build->isRestarting(); 32 + 33 + if ($is_restarting) { 32 34 $page_header->setStatus( 33 35 'fa-exclamation-triangle', 'red', pht('Restarting')); 34 36 } else if ($build->isPausing()) { ··· 42 44 'fa-exclamation-triangle', 'red', pht('Aborting')); 43 45 } 44 46 47 + $max_generation = (int)$build->getBuildGeneration(); 48 + if ($max_generation === 0) { 49 + $min_generation = 0; 50 + } else { 51 + $min_generation = 1; 52 + } 53 + 54 + if ($is_restarting) { 55 + $max_generation = $max_generation + 1; 56 + } 57 + 58 + $generation = $request->getURIData('generation'); 59 + if ($generation === null) { 60 + $generation = $max_generation; 61 + } else { 62 + $generation = (int)$generation; 63 + } 64 + 65 + if ($generation < $min_generation || $generation > $max_generation) { 66 + return new Aphront404Response(); 67 + } 68 + 69 + if ($generation < $max_generation) { 70 + $warnings[] = pht( 71 + 'You are viewing an older run of this build. %s', 72 + phutil_tag( 73 + 'a', 74 + array( 75 + 'href' => $build->getURI(), 76 + ), 77 + pht('View Current Build'))); 78 + } 79 + 80 + 45 81 $curtain = $this->buildCurtainView($build); 46 82 $properties = $this->buildPropertyList($build); 83 + $history = $this->buildHistoryTable( 84 + $build, 85 + $generation, 86 + $min_generation, 87 + $max_generation); 47 88 48 89 $crumbs = $this->buildApplicationCrumbs(); 49 90 $this->addBuildableCrumb($crumbs, $build->getBuildable()); 50 91 $crumbs->addTextCrumb($title); 51 92 $crumbs->setBorder(true); 52 - 53 - if ($generation === null || $generation > $build->getBuildGeneration() || 54 - $generation < 0) { 55 - $generation = $build->getBuildGeneration(); 56 - } 57 93 58 94 $build_targets = id(new HarbormasterBuildTargetQuery()) 59 95 ->setViewer($viewer) ··· 264 300 new HarbormasterBuildTransactionQuery()); 265 301 $timeline->setShouldTerminate(true); 266 302 303 + if ($warnings) { 304 + $warnings = id(new PHUIInfoView()) 305 + ->setErrors($warnings) 306 + ->setSeverity(PHUIInfoView::SEVERITY_WARNING); 307 + } else { 308 + $warnings = null; 309 + } 310 + 267 311 $view = id(new PHUITwoColumnView()) 268 312 ->setHeader($page_header) 269 313 ->setCurtain($curtain) 270 - ->setMainColumn(array( 271 - $properties, 272 - $targets, 273 - $timeline, 274 - )); 314 + ->setMainColumn( 315 + array( 316 + $warnings, 317 + $properties, 318 + $history, 319 + $targets, 320 + $timeline, 321 + )); 275 322 276 323 return $this->newPage() 277 324 ->setTitle($title) ··· 562 609 $handles[$build->getBuildPlanPHID()]->renderLink()); 563 610 564 611 $properties->addProperty( 565 - pht('Restarts'), 566 - $build->getBuildGeneration()); 567 - 568 - $properties->addProperty( 569 612 pht('Status'), 570 613 $this->getStatus($build)); 571 614 ··· 575 618 ->appendChild($properties); 576 619 577 620 } 621 + 622 + private function buildHistoryTable( 623 + HarbormasterBuild $build, 624 + $generation, 625 + $min_generation, 626 + $max_generation) { 627 + 628 + if ($max_generation === $min_generation) { 629 + return null; 630 + } 631 + 632 + $viewer = $this->getViewer(); 633 + 634 + $uri = $build->getURI(); 635 + 636 + $rows = array(); 637 + $rowc = array(); 638 + for ($ii = $max_generation; $ii >= $min_generation; $ii--) { 639 + if ($generation == $ii) { 640 + $rowc[] = 'highlighted'; 641 + } else { 642 + $rowc[] = null; 643 + } 644 + 645 + $rows[] = array( 646 + phutil_tag( 647 + 'a', 648 + array( 649 + 'href' => $uri.$ii.'/', 650 + ), 651 + pht('Run %d', $ii)), 652 + ); 653 + } 654 + 655 + $table = id(new AphrontTableView($rows)) 656 + ->setColumnClasses( 657 + array( 658 + 'pri wide', 659 + )) 660 + ->setRowClasses($rowc); 661 + 662 + return id(new PHUIObjectBoxView()) 663 + ->setHeaderText(pht('History')) 664 + ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 665 + ->setTable($table); 666 + } 667 + 578 668 579 669 private function getStatus(HarbormasterBuild $build) { 580 670 $status_view = new PHUIStatusListView();
+1 -1
src/applications/harbormaster/engine/HarbormasterBuildEngine.php
··· 147 147 // If it is different, they will automatically stop what they're doing 148 148 // and abort. 149 149 150 - // Previously we used to delete targets, logs and artifacts here. Instead 150 + // Previously we used to delete targets, logs and artifacts here. Instead, 151 151 // leave them around so users can view previous generations of this build. 152 152 } 153 153