@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.

Use tabs on build targets and allow build steps to have a description

Summary:
Ref T1049. This uses tabs on build targets to hide the configuration details and variables by default, instead promoting the target name, it's status and a description of the build step. The description is a new field on each build step.

The primary advantage of having a description on build steps is that DevOps can configure appropriate description information (including any troubleshooting information for build failures) on build steps, and developers who have builds fail against their code review can then look at this information.

Test Plan: Viewed a build plan and saw the appropriate information.

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: epriestley, Korvin

Maniphest Tasks: T1049

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

+157 -9
+2
resources/sql/autopatches/20140731.harbormasterstepdesc.sql
··· 1 + ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_buildstep 2 + ADD description LONGTEXT NOT NULL COLLATE utf8_bin;
+46 -9
src/applications/harbormaster/controller/HarbormasterBuildViewController.php
··· 52 52 53 53 $build_targets = id(new HarbormasterBuildTargetQuery()) 54 54 ->setViewer($viewer) 55 + ->needBuildSteps(true) 55 56 ->withBuildPHIDs(array($build->getPHID())) 56 57 ->execute(); 57 58 ··· 69 70 $targets = array(); 70 71 foreach ($build_targets as $build_target) { 71 72 $header = id(new PHUIHeaderView()) 72 - ->setHeader(pht( 73 - 'Build Target %d (%s)', 74 - $build_target->getID(), 75 - $build_target->getName())) 73 + ->setHeader($build_target->getName()) 76 74 ->setUser($viewer); 75 + 76 + $target_box = id(new PHUIObjectBoxView()) 77 + ->setHeader($header); 78 + 77 79 $properties = new PHUIPropertyListView(); 80 + $status_view = new PHUIStatusListView(); 81 + 82 + $item = new PHUIStatusItemView(); 83 + 84 + $status = $build_target->getTargetStatus(); 85 + $status_name = 86 + HarbormasterBuildTarget::getBuildTargetStatusName($status); 87 + $icon = HarbormasterBuildTarget::getBuildTargetStatusIcon($status); 88 + $color = HarbormasterBuildTarget::getBuildTargetStatusColor($status); 89 + 90 + $item->setTarget($status_name); 91 + $item->setIcon($icon, $color); 92 + $status_view->addItem($item); 93 + 94 + $properties->addProperty(pht('Name'), $build_target->getName()); 95 + $properties->addProperty(pht('Status'), $status_view); 96 + 97 + $target_box->addPropertyList($properties, pht('Overview')); 98 + 99 + $description = $build_target->getBuildStep()->getDescription(); 100 + if ($description) { 101 + $rendered = PhabricatorMarkupEngine::renderOneObject( 102 + id(new PhabricatorMarkupOneOff()) 103 + ->setContent($description) 104 + ->setPreserveLinebreaks(true), 105 + 'default', 106 + $viewer); 107 + 108 + $properties->addSectionHeader(pht('Description')); 109 + $properties->addTextContent($rendered); 110 + } 78 111 79 112 $details = $build_target->getDetails(); 80 113 if ($details) { 81 - $properties->addSectionHeader(pht('Configuration Details')); 114 + $properties = new PHUIPropertyListView(); 82 115 foreach ($details as $key => $value) { 83 116 $properties->addProperty($key, $value); 84 117 } 118 + $target_box->addPropertyList($properties, pht('Configuration')); 85 119 } 86 120 87 121 $variables = $build_target->getVariables(); 88 122 if ($variables) { 89 - $properties->addSectionHeader(pht('Variables')); 123 + $properties = new PHUIPropertyListView(); 90 124 foreach ($variables as $key => $value) { 91 125 $properties->addProperty($key, $value); 92 126 } 127 + $target_box->addPropertyList($properties, pht('Variables')); 93 128 } 94 129 95 - $targets[] = id(new PHUIObjectBoxView()) 96 - ->setHeader($header) 97 - ->addPropertyList($properties); 130 + $properties = new PHUIPropertyListView(); 131 + $properties->addProperty('Build Target ID', $build_target->getID()); 132 + $target_box->addPropertyList($properties, pht('Metadata')); 133 + 134 + $targets[] = $target_box; 98 135 99 136 $build_messages = idx($messages, $build_target->getPHID(), array()); 100 137 if ($build_messages) {
+18
src/applications/harbormaster/controller/HarbormasterStepEditController.php
··· 65 65 66 66 $e_name = true; 67 67 $v_name = $step->getName(); 68 + $e_description = true; 69 + $v_description = $step->getDescription(); 68 70 $e_depends_on = true; 69 71 $raw_depends_on = $step->getDetail('dependsOn', array()); 70 72 ··· 78 80 if ($request->isFormPost()) { 79 81 $e_name = null; 80 82 $v_name = $request->getStr('name'); 83 + $e_description = null; 84 + $v_description = $request->getStr('description'); 81 85 $e_depends_on = null; 82 86 $v_depends_on = $request->getArr('dependsOn'); 83 87 ··· 101 105 ->setNewValue($v_depends_on); 102 106 array_unshift($xactions, $depends_on_xaction); 103 107 108 + $description_xaction = id(new HarbormasterBuildStepTransaction()) 109 + ->setTransactionType( 110 + HarbormasterBuildStepTransaction::TYPE_DESCRIPTION) 111 + ->setNewValue($v_description); 112 + array_unshift($xactions, $description_xaction); 113 + 104 114 if ($is_new) { 105 115 // When creating a new step, make sure we have a create transaction 106 116 // so we'll apply the transactions even if the step has no ··· 141 151 ->setValue($v_depends_on)); 142 152 143 153 $field_list->appendFieldsToForm($form); 154 + 155 + $form 156 + ->appendChild( 157 + id(new PhabricatorRemarkupControl()) 158 + ->setName('description') 159 + ->setLabel(pht('Description')) 160 + ->setError($e_description) 161 + ->setValue($v_description)); 144 162 145 163 if ($is_new) { 146 164 $submit = pht('Create Build Step');
+10
src/applications/harbormaster/editor/HarbormasterBuildStepEditor.php
··· 9 9 $types[] = HarbormasterBuildStepTransaction::TYPE_CREATE; 10 10 $types[] = HarbormasterBuildStepTransaction::TYPE_NAME; 11 11 $types[] = HarbormasterBuildStepTransaction::TYPE_DEPENDS_ON; 12 + $types[] = HarbormasterBuildStepTransaction::TYPE_DESCRIPTION; 12 13 13 14 return $types; 14 15 } ··· 30 31 return null; 31 32 } 32 33 return $object->getDetail('dependsOn', array()); 34 + case HarbormasterBuildStepTransaction::TYPE_DESCRIPTION: 35 + if ($this->getIsNewObject()) { 36 + return null; 37 + } 38 + return $object->getDescription(); 33 39 } 34 40 35 41 return parent::getCustomTransactionOldValue($object, $xaction); ··· 44 50 return true; 45 51 case HarbormasterBuildStepTransaction::TYPE_NAME: 46 52 case HarbormasterBuildStepTransaction::TYPE_DEPENDS_ON: 53 + case HarbormasterBuildStepTransaction::TYPE_DESCRIPTION: 47 54 return $xaction->getNewValue(); 48 55 } 49 56 ··· 61 68 return $object->setName($xaction->getNewValue()); 62 69 case HarbormasterBuildStepTransaction::TYPE_DEPENDS_ON: 63 70 return $object->setDetail('dependsOn', $xaction->getNewValue()); 71 + case HarbormasterBuildStepTransaction::TYPE_DESCRIPTION: 72 + return $object->setDescription($xaction->getNewValue()); 64 73 } 65 74 66 75 return parent::applyCustomInternalTransaction($object, $xaction); ··· 74 83 case HarbormasterBuildStepTransaction::TYPE_CREATE: 75 84 case HarbormasterBuildStepTransaction::TYPE_NAME: 76 85 case HarbormasterBuildStepTransaction::TYPE_DEPENDS_ON: 86 + case HarbormasterBuildStepTransaction::TYPE_DESCRIPTION: 77 87 return; 78 88 } 79 89
+31
src/applications/harbormaster/query/HarbormasterBuildTargetQuery.php
··· 6 6 private $ids; 7 7 private $phids; 8 8 private $buildPHIDs; 9 + private $needBuildSteps; 9 10 10 11 public function withIDs(array $ids) { 11 12 $this->ids = $ids; ··· 19 20 20 21 public function withBuildPHIDs(array $build_phids) { 21 22 $this->buildPHIDs = $build_phids; 23 + return $this; 24 + } 25 + 26 + public function needBuildSteps($need_build_steps) { 27 + $this->needBuildSteps = $need_build_steps; 22 28 return $this; 23 29 } 24 30 ··· 64 70 $where[] = $this->buildPagingClause($conn_r); 65 71 66 72 return $this->formatWhereClause($where); 73 + } 74 + 75 + protected function didFilterPage(array $page) { 76 + if ($this->needBuildSteps) { 77 + $step_phids = array(); 78 + 79 + foreach ($page as $target) { 80 + $step_phids[] = $target->getBuildStepPHID(); 81 + } 82 + 83 + $steps = id(new HarbormasterBuildStepQuery()) 84 + ->setViewer($this->getViewer()) 85 + ->setParentQuery($this) 86 + ->withPHIDs($step_phids) 87 + ->execute(); 88 + 89 + $steps = mpull($steps, null, 'getPHID'); 90 + 91 + foreach ($page as $target) { 92 + $target->attachBuildStep( 93 + $steps[$target->getBuildStepPHID()]); 94 + } 95 + } 96 + 97 + return $page; 67 98 } 68 99 69 100 protected function willFilterPage(array $page) {
+48
src/applications/harbormaster/storage/build/HarbormasterBuildTarget.php
··· 21 21 private $buildStep = self::ATTACHABLE; 22 22 private $implementation; 23 23 24 + public static function getBuildTargetStatusName($status) { 25 + switch ($status) { 26 + case self::STATUS_PENDING: 27 + return pht('Pending'); 28 + case self::STATUS_BUILDING: 29 + return pht('Building'); 30 + case self::STATUS_WAITING: 31 + return pht('Waiting for Message'); 32 + case self::STATUS_PASSED: 33 + return pht('Passed'); 34 + case self::STATUS_FAILED: 35 + return pht('Failed'); 36 + default: 37 + return pht('Unknown'); 38 + } 39 + } 40 + 41 + public static function getBuildTargetStatusIcon($status) { 42 + switch ($status) { 43 + case self::STATUS_PENDING: 44 + return PHUIStatusItemView::ICON_OPEN; 45 + case self::STATUS_BUILDING: 46 + case self::STATUS_WAITING: 47 + return PHUIStatusItemView::ICON_RIGHT; 48 + case self::STATUS_PASSED: 49 + return PHUIStatusItemView::ICON_ACCEPT; 50 + case self::STATUS_FAILED: 51 + return PHUIStatusItemView::ICON_REJECT; 52 + default: 53 + return PHUIStatusItemView::ICON_QUESTION; 54 + } 55 + } 56 + 57 + public static function getBuildTargetStatusColor($status) { 58 + switch ($status) { 59 + case self::STATUS_PENDING: 60 + case self::STATUS_BUILDING: 61 + case self::STATUS_WAITING: 62 + return 'blue'; 63 + case self::STATUS_PASSED: 64 + return 'green'; 65 + case self::STATUS_FAILED: 66 + return 'red'; 67 + default: 68 + return 'bluegrey'; 69 + } 70 + } 71 + 24 72 public static function initializeNewBuildTarget( 25 73 HarbormasterBuild $build, 26 74 HarbormasterBuildStep $build_step,
+1
src/applications/harbormaster/storage/configuration/HarbormasterBuildStep.php
··· 6 6 PhabricatorCustomFieldInterface { 7 7 8 8 protected $name; 9 + protected $description; 9 10 protected $buildPlanPHID; 10 11 protected $className; 11 12 protected $details = array();
+1
src/applications/harbormaster/storage/configuration/HarbormasterBuildStepTransaction.php
··· 6 6 const TYPE_CREATE = 'harbormaster:step:create'; 7 7 const TYPE_NAME = 'harbormaster:step:name'; 8 8 const TYPE_DEPENDS_ON = 'harbormaster:step:depends'; 9 + const TYPE_DESCRIPTION = 'harbormaster:step:description'; 9 10 10 11 public function getApplicationName() { 11 12 return 'harbormaster';