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

Introduce HarbormasterBuildTarget to snapshot build steps through a build

Summary: This implements build targets as outlined in D7582. Build targets represent an instance of a build step particular to the build. Logs and artifacts have been adjusted to attach to build targets instead of build / build step pairs.

Test Plan: Ran builds and clicked around the interface. Everything seemed to work.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley

CC: Korvin, epriestley, aran

Maniphest Tasks: T4111, T1049

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

+349 -154
+32
resources/sql/patches/20131205.buildtargets.sql
··· 1 + CREATE TABLE {$NAMESPACE}_harbormaster.harbormaster_buildtarget ( 2 + id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 3 + phid VARCHAR(64) NOT NULL COLLATE utf8_bin, 4 + buildPHID VARCHAR(64) NOT NULL COLLATE utf8_bin, 5 + buildStepPHID VARCHAR(64) NOT NULL COLLATE utf8_bin, 6 + className VARCHAR(255) NOT NULL COLLATE utf8_bin, 7 + details LONGTEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, 8 + variables LONGTEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, 9 + dateCreated INT UNSIGNED NOT NULL, 10 + dateModified INT UNSIGNED NOT NULL, 11 + KEY `key_build` (buildPHID, buildStepPHID), 12 + UNIQUE KEY `key_phid` (phid) 13 + ) ENGINE=InnoDB, COLLATE utf8_general_ci; 14 + 15 + TRUNCATE TABLE {$NAMESPACE}_harbormaster.harbormaster_buildlog; 16 + TRUNCATE TABLE {$NAMESPACE}_harbormaster.harbormaster_buildlogchunk; 17 + TRUNCATE TABLE {$NAMESPACE}_harbormaster.harbormaster_buildartifact; 18 + 19 + ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_buildlog 20 + DROP COLUMN buildPHID; 21 + 22 + ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_buildlog 23 + DROP COLUMN buildStepPHID; 24 + 25 + ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_buildartifact 26 + DROP COLUMN buildablePHID; 27 + 28 + ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_buildlog 29 + ADD COLUMN buildTargetPHID VARCHAR(64) NOT NULL COLLATE utf8_bin; 30 + 31 + ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_buildartifact 32 + ADD COLUMN buildTargetPHID VARCHAR(64) NOT NULL COLLATE utf8_bin;
+7 -3
src/__phutil_library_map__.php
··· 677 677 'FileReplyHandler' => 'applications/files/mail/FileReplyHandler.php', 678 678 'HarbormasterBuild' => 'applications/harbormaster/storage/build/HarbormasterBuild.php', 679 679 'HarbormasterBuildArtifact' => 'applications/harbormaster/storage/build/HarbormasterBuildArtifact.php', 680 + 'HarbormasterBuildArtifactQuery' => 'applications/harbormaster/query/HarbormasterBuildArtifactQuery.php', 680 681 'HarbormasterBuildCancelController' => 'applications/harbormaster/controller/HarbormasterBuildCancelController.php', 681 682 'HarbormasterBuildItem' => 'applications/harbormaster/storage/build/HarbormasterBuildItem.php', 682 683 'HarbormasterBuildItemQuery' => 'applications/harbormaster/query/HarbormasterBuildItemQuery.php', ··· 698 699 'HarbormasterBuildWorker' => 'applications/harbormaster/worker/HarbormasterBuildWorker.php', 699 700 'HarbormasterBuildable' => 'applications/harbormaster/storage/HarbormasterBuildable.php', 700 701 'HarbormasterBuildableApplyController' => 'applications/harbormaster/controller/HarbormasterBuildableApplyController.php', 701 - 'HarbormasterBuildableArtifactQuery' => 'applications/harbormaster/query/HarbormasterBuildableArtifactQuery.php', 702 702 'HarbormasterBuildableEditController' => 'applications/harbormaster/controller/HarbormasterBuildableEditController.php', 703 703 'HarbormasterBuildableListController' => 'applications/harbormaster/controller/HarbormasterBuildableListController.php', 704 704 'HarbormasterBuildableQuery' => 'applications/harbormaster/query/HarbormasterBuildableQuery.php', ··· 3023 3023 0 => 'HarbormasterDAO', 3024 3024 1 => 'PhabricatorPolicyInterface', 3025 3025 ), 3026 + 'HarbormasterBuildArtifactQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 3026 3027 'HarbormasterBuildCancelController' => 'HarbormasterController', 3027 3028 'HarbormasterBuildItem' => 'HarbormasterDAO', 3028 3029 'HarbormasterBuildItemQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', ··· 3051 3052 1 => 'PhabricatorPolicyInterface', 3052 3053 ), 3053 3054 'HarbormasterBuildStepQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 3054 - 'HarbormasterBuildTarget' => 'HarbormasterDAO', 3055 + 'HarbormasterBuildTarget' => 3056 + array( 3057 + 0 => 'HarbormasterDAO', 3058 + 1 => 'PhabricatorPolicyInterface', 3059 + ), 3055 3060 'HarbormasterBuildTargetQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 3056 3061 'HarbormasterBuildViewController' => 'HarbormasterController', 3057 3062 'HarbormasterBuildWorker' => 'PhabricatorWorker', ··· 3061 3066 1 => 'PhabricatorPolicyInterface', 3062 3067 ), 3063 3068 'HarbormasterBuildableApplyController' => 'HarbormasterController', 3064 - 'HarbormasterBuildableArtifactQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 3065 3069 'HarbormasterBuildableEditController' => 'HarbormasterController', 3066 3070 'HarbormasterBuildableListController' => 3067 3071 array(
+41 -4
src/applications/harbormaster/controller/HarbormasterBuildViewController.php
··· 41 41 id(new PhabricatorCrumbView()) 42 42 ->setName($title)); 43 43 44 - $logs = $this->buildLog($build); 44 + $build_targets = id(new HarbormasterBuildTargetQuery()) 45 + ->setViewer($viewer) 46 + ->withBuildPHIDs(array($build->getPHID())) 47 + ->execute(); 48 + 49 + $targets = array(); 50 + foreach ($build_targets as $build_target) { 51 + $header = id(new PHUIHeaderView()) 52 + ->setHeader(pht('Build Target %d', $build_target->getID())) 53 + ->setUser($viewer); 54 + $properties = new PHUIPropertyListView(); 55 + 56 + $details = $build_target->getDetails(); 57 + if ($details) { 58 + $properties->addSectionHeader(pht('Configuration Details')); 59 + foreach ($details as $key => $value) { 60 + $properties->addProperty($key, $value); 61 + } 62 + } 63 + 64 + $variables = $build_target->getVariables(); 65 + if ($variables) { 66 + $properties->addSectionHeader(pht('Variables')); 67 + foreach ($variables as $key => $value) { 68 + $properties->addProperty($key, $value); 69 + } 70 + } 71 + 72 + $targets[] = id(new PHUIObjectBoxView()) 73 + ->setHeader($header) 74 + ->addPropertyList($properties); 75 + 76 + $targets[] = $this->buildLog($build, $build_target); 77 + } 78 + 45 79 46 80 return $this->buildApplicationPage( 47 81 array( 48 82 $crumbs, 49 83 $box, 50 - $logs 84 + $targets 51 85 ), 52 86 array( 53 87 'title' => $title, ··· 55 89 )); 56 90 } 57 91 58 - private function buildLog(HarbormasterBuild $build) { 92 + private function buildLog( 93 + HarbormasterBuild $build, 94 + HarbormasterBuildTarget $build_target) { 95 + 59 96 $request = $this->getRequest(); 60 97 $viewer = $request->getUser(); 61 98 $limit = $request->getInt('l', 25); 62 99 63 100 $logs = id(new HarbormasterBuildLogQuery()) 64 101 ->setViewer($viewer) 65 - ->withBuildPHIDs(array($build->getPHID())) 102 + ->withBuildTargetPHIDs(array($build_target->getPHID())) 66 103 ->execute(); 67 104 68 105 $log_boxes = array();
+14 -14
src/applications/harbormaster/query/HarbormasterBuildLogQuery.php
··· 17 17 return $this; 18 18 } 19 19 20 - public function withBuildPHIDs(array $build_phids) { 21 - $this->buildPHIDs = $build_phids; 20 + public function withBuildTargetPHIDs(array $build_target_phids) { 21 + $this->buildTargetPHIDs = $build_target_phids; 22 22 return $this; 23 23 } 24 24 ··· 38 38 } 39 39 40 40 protected function willFilterPage(array $page) { 41 - $builds = array(); 41 + $build_targets = array(); 42 42 43 - $build_phids = array_filter(mpull($page, 'getBuildPHID')); 44 - if ($build_phids) { 45 - $builds = id(new HarbormasterBuildQuery()) 43 + $build_target_phids = array_filter(mpull($page, 'getBuildTargetPHID')); 44 + if ($build_target_phids) { 45 + $build_targets = id(new HarbormasterBuildTargetQuery()) 46 46 ->setViewer($this->getViewer()) 47 - ->withPHIDs($build_phids) 47 + ->withPHIDs($build_target_phids) 48 48 ->setParentQuery($this) 49 49 ->execute(); 50 - $builds = mpull($builds, null, 'getPHID'); 50 + $build_targets = mpull($build_targets, null, 'getPHID'); 51 51 } 52 52 53 53 foreach ($page as $key => $build_log) { 54 - $build_phid = $build_log->getBuildPHID(); 55 - if (empty($builds[$build_phid])) { 54 + $build_target_phid = $build_log->getBuildTargetPHID(); 55 + if (empty($build_targets[$build_target_phid])) { 56 56 unset($page[$key]); 57 57 continue; 58 58 } 59 - $build_log->attachBuild($builds[$build_phid]); 59 + $build_log->attachBuildTarget($build_targets[$build_target_phid]); 60 60 } 61 61 62 62 return $page; ··· 79 79 $this->phids); 80 80 } 81 81 82 - if ($this->buildPHIDs) { 82 + if ($this->buildTargetPHIDs) { 83 83 $where[] = qsprintf( 84 84 $conn_r, 85 - 'buildPHID IN (%Ls)', 86 - $this->buildPHIDs); 85 + 'buildTargetPHID IN (%Ls)', 86 + $this->buildTargetPHIDs); 87 87 } 88 88 89 89 $where[] = $this->buildPagingClause($conn_r);
+38
src/applications/harbormaster/query/HarbormasterBuildTargetQuery.php
··· 5 5 6 6 private $ids; 7 7 private $phids; 8 + private $buildPHIDs; 8 9 9 10 public function withIDs(array $ids) { 10 11 $this->ids = $ids; ··· 13 14 14 15 public function withPHIDs(array $phids) { 15 16 $this->phids = $phids; 17 + return $this; 18 + } 19 + 20 + public function withBuildPHIDs(array $build_phids) { 21 + $this->buildPHIDs = $build_phids; 16 22 return $this; 17 23 } 18 24 ··· 48 54 $this->phids); 49 55 } 50 56 57 + if ($this->buildPHIDs) { 58 + $where[] = qsprintf( 59 + $conn_r, 60 + 'buildPHID in (%Ls)', 61 + $this->buildPHIDs); 62 + } 63 + 51 64 $where[] = $this->buildPagingClause($conn_r); 52 65 53 66 return $this->formatWhereClause($where); 67 + } 68 + 69 + protected function willFilterPage(array $page) { 70 + $builds = array(); 71 + 72 + $build_phids = array_filter(mpull($page, 'getBuildPHID')); 73 + if ($build_phids) { 74 + $builds = id(new PhabricatorObjectQuery()) 75 + ->setViewer($this->getViewer()) 76 + ->withPHIDs($build_phids) 77 + ->setParentQuery($this) 78 + ->execute(); 79 + $builds = mpull($builds, null, 'getPHID'); 80 + } 81 + 82 + foreach ($page as $key => $build_target) { 83 + $build_phid = $build_target->getBuildPHID(); 84 + if (empty($builds[$build_phid])) { 85 + unset($page[$key]); 86 + continue; 87 + } 88 + $build_target->attachBuild($builds[$build_phid]); 89 + } 90 + 91 + return $page; 54 92 } 55 93 56 94 public function getQueryApplicationClass() {
+17 -17
src/applications/harbormaster/query/HarbormasterBuildableArtifactQuery.php src/applications/harbormaster/query/HarbormasterBuildArtifactQuery.php
··· 1 1 <?php 2 2 3 - final class HarbormasterBuildableArtifactQuery 3 + final class HarbormasterBuildArtifactQuery 4 4 extends PhabricatorCursorPagedPolicyAwareQuery { 5 5 6 6 private $ids; 7 - private $buildablePHIDs; 7 + private $buildTargetPHIDs; 8 8 private $artifactTypes; 9 9 private $artifactKeys; 10 10 ··· 13 13 return $this; 14 14 } 15 15 16 - public function withBuildablePHIDs(array $buildable_phids) { 17 - $this->buildablePHIDs = $buildable_phids; 16 + public function withBuildTargetPHIDs(array $build_target_phids) { 17 + $this->buildTargetPHIDs = $build_target_phids; 18 18 return $this; 19 19 } 20 20 ··· 44 44 } 45 45 46 46 protected function willFilterPage(array $page) { 47 - $buildables = array(); 47 + $build_targets = array(); 48 48 49 - $buildable_phids = array_filter(mpull($page, 'getBuildablePHID')); 50 - if ($buildable_phids) { 51 - $buildables = id(new PhabricatorObjectQuery()) 49 + $build_target_phids = array_filter(mpull($page, 'getBuildTargetPHID')); 50 + if ($build_target_phids) { 51 + $build_targets = id(new HarbormasterBuildTargetQuery()) 52 52 ->setViewer($this->getViewer()) 53 - ->withPHIDs($buildable_phids) 53 + ->withPHIDs($build_target_phids) 54 54 ->setParentQuery($this) 55 55 ->execute(); 56 - $buildables = mpull($buildables, null, 'getPHID'); 56 + $build_targets = mpull($build_targets, null, 'getPHID'); 57 57 } 58 58 59 - foreach ($page as $key => $artifact) { 60 - $buildable_phid = $artifact->getBuildablePHID(); 61 - if (empty($buildables[$buildable_phid])) { 59 + foreach ($page as $key => $build_log) { 60 + $build_target_phid = $build_log->getBuildTargetPHID(); 61 + if (empty($build_targets[$build_target_phid])) { 62 62 unset($page[$key]); 63 63 continue; 64 64 } 65 - $artifact->attachBuildable($buildables[$buildable_phid]); 65 + $build_log->attachBuildTarget($build_targets[$build_target_phid]); 66 66 } 67 67 68 68 return $page; ··· 78 78 $this->ids); 79 79 } 80 80 81 - if ($this->buildablePHIDs) { 81 + if ($this->buildTargetPHIDs) { 82 82 $where[] = qsprintf( 83 83 $conn_r, 84 - 'buildablePHID IN (%Ls)', 85 - $this->buildablePHIDs); 84 + 'buildTargetPHID IN (%Ls)', 85 + $this->buildTargetPHIDs); 86 86 } 87 87 88 88 if ($this->artifactTypes) {
+5 -5
src/applications/harbormaster/step/BuildStepImplementation.php
··· 36 36 } 37 37 38 38 /** 39 - * Run the build step against the specified build. 39 + * Run the build target against the specified build. 40 40 */ 41 41 abstract public function execute( 42 42 HarbormasterBuild $build, 43 - HarbormasterBuildStep $build_step); 43 + HarbormasterBuildTarget $build_target); 44 44 45 45 /** 46 46 * Gets the settings for this build step. ··· 57 57 } 58 58 59 59 /** 60 - * Loads the settings for this build step implementation from the build step. 60 + * Loads the settings for this build step implementation from a build target. 61 61 */ 62 - public final function loadSettings(HarbormasterBuildStep $build_step) { 62 + public final function loadSettings(HarbormasterBuildTarget $build_target) { 63 63 $this->settings = array(); 64 64 $this->validateSettingDefinitions(); 65 65 foreach ($this->getSettingDefinitions() as $name => $opt) { 66 - $this->settings[$name] = $build_step->getDetail($name); 66 + $this->settings[$name] = $build_target->getDetail($name); 67 67 } 68 68 return $this->settings; 69 69 }
+3 -3
src/applications/harbormaster/step/HarbormasterHTTPRequestBuildStepImplementation.php
··· 21 21 22 22 public function execute( 23 23 HarbormasterBuild $build, 24 - HarbormasterBuildStep $build_step) { 24 + HarbormasterBuildTarget $build_target) { 25 25 26 26 $settings = $this->getSettings(); 27 - $variables = $this->retrieveVariablesFromBuild($build); 27 + $variables = $build_target->getVariables(); 28 28 29 29 $uri = $this->mergeVariables( 30 30 'vurisprintf', 31 31 $settings['uri'], 32 32 $variables); 33 33 34 - $log_body = $build->createLog($build_step, $uri, 'http-body'); 34 + $log_body = $build->createLog($build_target, $uri, 'http-body'); 35 35 $start = $log_body->start(); 36 36 37 37 list($status, $body, $headers) = id(new HTTPSFuture($uri))
+4 -4
src/applications/harbormaster/step/RemoteCommandBuildStepImplementation.php
··· 22 22 23 23 public function execute( 24 24 HarbormasterBuild $build, 25 - HarbormasterBuildStep $build_step) { 25 + HarbormasterBuildTarget $build_target) { 26 26 27 27 $settings = $this->getSettings(); 28 - $variables = $this->retrieveVariablesFromBuild($build); 28 + $variables = $build_target->getVariables(); 29 29 30 30 $command = $this->mergeVariables( 31 31 'vcsprintf', ··· 48 48 $command); 49 49 } 50 50 51 - $log_stdout = $build->createLog($build_step, "remote", "stdout"); 52 - $log_stderr = $build->createLog($build_step, "remote", "stderr"); 51 + $log_stdout = $build->createLog($build_target, "remote", "stdout"); 52 + $log_stderr = $build->createLog($build_target, "remote", "stderr"); 53 53 54 54 $start_stdout = $log_stdout->start(); 55 55 $start_stderr = $log_stderr->start();
+1 -1
src/applications/harbormaster/step/SleepBuildStepImplementation.php
··· 18 18 19 19 public function execute( 20 20 HarbormasterBuild $build, 21 - HarbormasterBuildStep $build_step) { 21 + HarbormasterBuildTarget $build_target) { 22 22 23 23 $settings = $this->getSettings(); 24 24
-53
src/applications/harbormaster/step/VariableBuildStepImplementation.php
··· 2 2 3 3 abstract class VariableBuildStepImplementation extends BuildStepImplementation { 4 4 5 - public function retrieveVariablesFromBuild(HarbormasterBuild $build) { 6 - $results = array( 7 - 'buildable.diff' => null, 8 - 'buildable.revision' => null, 9 - 'buildable.commit' => null, 10 - 'repository.callsign' => null, 11 - 'repository.vcs' => null, 12 - 'repository.uri' => null, 13 - 'step.timestamp' => null, 14 - 'build.id' => null); 15 - 16 - $buildable = $build->getBuildable(); 17 - $object = $buildable->getBuildableObject(); 18 - 19 - $repo = null; 20 - if ($object instanceof DifferentialDiff) { 21 - $results['buildable.diff'] = $object->getID(); 22 - $revision = $object->getRevision(); 23 - $results['buildable.revision'] = $revision->getID(); 24 - $repo = $revision->getRepository(); 25 - } else if ($object instanceof PhabricatorRepositoryCommit) { 26 - $results['buildable.commit'] = $object->getCommitIdentifier(); 27 - $repo = $object->getRepository(); 28 - } 29 - 30 - $results['repository.callsign'] = $repo->getCallsign(); 31 - $results['repository.vcs'] = $repo->getVersionControlSystem(); 32 - $results['repository.uri'] = $repo->getPublicRemoteURI(); 33 - $results['step.timestamp'] = time(); 34 - $results['build.id'] = $build->getID(); 35 - 36 - return $results; 37 - } 38 - 39 - 40 5 /** 41 6 * Convert a user-provided string with variables in it, like: 42 7 * ··· 69 34 $pattern = preg_replace($regexp, '%s', $pattern); 70 35 71 36 return call_user_func($function, $pattern, $argv); 72 - } 73 - 74 - 75 - public function getAvailableVariables() { 76 - return array( 77 - 'buildable.diff' => 78 - pht('The differential diff ID, if applicable.'), 79 - 'buildable.revision' => 80 - pht('The differential revision ID, if applicable.'), 81 - 'buildable.commit' => pht('The commit identifier, if applicable.'), 82 - 'repository.callsign' => 83 - pht('The callsign of the repository in Phabricator.'), 84 - 'repository.vcs' => 85 - pht('The version control system, either "svn", "hg" or "git".'), 86 - 'repository.uri' => 87 - pht('The URI to clone or checkout the repository from.'), 88 - 'step.timestamp' => pht('The current UNIX timestamp.'), 89 - 'build.id' => pht('The ID of the current build.')); 90 37 } 91 38 92 39 public function getSettingRemarkupInstructions() {
+53 -2
src/applications/harbormaster/storage/build/HarbormasterBuild.php
··· 95 95 } 96 96 97 97 public function createLog( 98 - HarbormasterBuildStep $build_step, 98 + HarbormasterBuildTarget $build_target, 99 99 $log_source, 100 100 $log_type) { 101 101 102 - $log = HarbormasterBuildLog::initializeNewBuildLog($this, $build_step); 102 + $log = HarbormasterBuildLog::initializeNewBuildLog($build_target); 103 103 $log->setLogSource($log_source); 104 104 $log->setLogType($log_type); 105 105 $log->save(); ··· 123 123 return true; 124 124 } 125 125 return false; 126 + } 127 + 128 + public function retrieveVariablesFromBuild() { 129 + $results = array( 130 + 'buildable.diff' => null, 131 + 'buildable.revision' => null, 132 + 'buildable.commit' => null, 133 + 'repository.callsign' => null, 134 + 'repository.vcs' => null, 135 + 'repository.uri' => null, 136 + 'step.timestamp' => null, 137 + 'build.id' => null); 138 + 139 + $buildable = $this->getBuildable(); 140 + $object = $buildable->getBuildableObject(); 141 + 142 + $repo = null; 143 + if ($object instanceof DifferentialDiff) { 144 + $results['buildable.diff'] = $object->getID(); 145 + $revision = $object->getRevision(); 146 + $results['buildable.revision'] = $revision->getID(); 147 + $repo = $revision->getRepository(); 148 + } else if ($object instanceof PhabricatorRepositoryCommit) { 149 + $results['buildable.commit'] = $object->getCommitIdentifier(); 150 + $repo = $object->getRepository(); 151 + } 152 + 153 + $results['repository.callsign'] = $repo->getCallsign(); 154 + $results['repository.vcs'] = $repo->getVersionControlSystem(); 155 + $results['repository.uri'] = $repo->getPublicRemoteURI(); 156 + $results['step.timestamp'] = time(); 157 + $results['build.id'] = $this->getID(); 158 + 159 + return $results; 160 + } 161 + 162 + public function getAvailableBuildVariables() { 163 + return array( 164 + 'buildable.diff' => 165 + pht('The differential diff ID, if applicable.'), 166 + 'buildable.revision' => 167 + pht('The differential revision ID, if applicable.'), 168 + 'buildable.commit' => pht('The commit identifier, if applicable.'), 169 + 'repository.callsign' => 170 + pht('The callsign of the repository in Phabricator.'), 171 + 'repository.vcs' => 172 + pht('The version control system, either "svn", "hg" or "git".'), 173 + 'repository.uri' => 174 + pht('The URI to clone or checkout the repository from.'), 175 + 'step.timestamp' => pht('The current UNIX timestamp.'), 176 + 'build.id' => pht('The ID of the current build.')); 126 177 } 127 178 128 179
+11 -25
src/applications/harbormaster/storage/build/HarbormasterBuildLog.php
··· 3 3 final class HarbormasterBuildLog extends HarbormasterDAO 4 4 implements PhabricatorPolicyInterface { 5 5 6 - protected $buildPHID; 7 - protected $buildStepPHID; 6 + protected $buildTargetPHID; 8 7 protected $logSource; 9 8 protected $logType; 10 9 protected $duration; 11 10 protected $live; 12 11 13 - private $build = self::ATTACHABLE; 14 - private $buildStep = self::ATTACHABLE; 12 + private $buildTarget = self::ATTACHABLE; 15 13 16 14 const CHUNK_BYTE_LIMIT = 102400; 17 15 ··· 21 19 const ENCODING_TEXT = 'text'; 22 20 23 21 public static function initializeNewBuildLog( 24 - HarbormasterBuild $build, 25 - HarbormasterBuildStep $build_step) { 22 + HarbormasterBuildTarget $build_target) { 26 23 27 24 return id(new HarbormasterBuildLog()) 28 - ->setBuildPHID($build->getPHID()) 29 - ->setBuildStepPHID($build_step->getPHID()) 25 + ->setBuildTargetPHID($build_target->getPHID()) 30 26 ->setDuration(null) 31 27 ->setLive(0); 32 28 } ··· 42 38 HarbormasterPHIDTypeBuildLog::TYPECONST); 43 39 } 44 40 45 - public function attachBuild(HarbormasterBuild $build) { 46 - $this->build = $build; 41 + public function attachBuildTarget(HarbormasterBuildTarget $build_target) { 42 + $this->buildTarget = $build_target; 47 43 return $this; 48 44 } 49 45 50 - public function getBuild() { 51 - return $this->assertAttached($this->build); 46 + public function getBuildTarget() { 47 + return $this->assertAttached($this->buildTarget); 52 48 } 53 49 54 50 public function getName() { 55 51 return pht('Build Log'); 56 - } 57 - 58 - public function attachBuildStep( 59 - HarbormasterBuildStep $build_step = null) { 60 - $this->buildStep = $build_step; 61 - return $this; 62 - } 63 - 64 - public function getBuildStep() { 65 - return $this->assertAttached($this->buildStep); 66 52 } 67 53 68 54 public function start() { ··· 189 175 } 190 176 191 177 public function getPolicy($capability) { 192 - return $this->getBuild()->getPolicy($capability); 178 + return $this->getBuildTarget()->getPolicy($capability); 193 179 } 194 180 195 181 public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { 196 - return $this->getBuild()->hasAutomaticCapability( 182 + return $this->getBuildTarget()->hasAutomaticCapability( 197 183 $capability, 198 184 $viewer); 199 185 } 200 186 201 187 public function describeAutomaticCapability($capability) { 202 188 return pht( 203 - 'Users must be able to see a build to view it\'s build log.'); 189 + 'Users must be able to see a build target to view it\'s build log.'); 204 190 } 205 191 206 192
+108 -1
src/applications/harbormaster/storage/build/HarbormasterBuildTarget.php
··· 1 1 <?php 2 2 3 - final class HarbormasterBuildTarget extends HarbormasterDAO { 3 + final class HarbormasterBuildTarget extends HarbormasterDAO 4 + implements PhabricatorPolicyInterface { 5 + 6 + protected $buildPHID; 7 + protected $buildStepPHID; 8 + protected $className; 9 + protected $details; 10 + protected $variables; 11 + 12 + private $build = self::ATTACHABLE; 13 + private $buildStep = self::ATTACHABLE; 14 + 15 + public static function initializeNewBuildTarget( 16 + HarbormasterBuild $build, 17 + HarbormasterBuildStep $build_step, 18 + array $variables) { 19 + return id(new HarbormasterBuildTarget()) 20 + ->setBuildPHID($build->getPHID()) 21 + ->setBuildStepPHID($build_step->getPHID()) 22 + ->setClassName($build_step->getClassName()) 23 + ->setDetails($build_step->getDetails()) 24 + ->setVariables($variables); 25 + } 4 26 5 27 public function getConfiguration() { 6 28 return array( 7 29 self::CONFIG_AUX_PHID => true, 30 + self::CONFIG_SERIALIZATION => array( 31 + 'details' => self::SERIALIZATION_JSON, 32 + 'variables' => self::SERIALIZATION_JSON, 33 + ) 8 34 ) + parent::getConfiguration(); 9 35 } 10 36 11 37 public function generatePHID() { 12 38 return PhabricatorPHID::generateNewPHID( 13 39 HarbormasterPHIDTypeBuildTarget::TYPECONST); 40 + } 41 + 42 + public function attachBuild(HarbormasterBuild $build) { 43 + $this->build = $build; 44 + return $this; 45 + } 46 + 47 + public function getBuild() { 48 + return $this->assertAttached($this->build); 49 + } 50 + 51 + public function attachBuildStep(HarbormasterBuildStep $step) { 52 + $this->buildStep = $step; 53 + return $this; 54 + } 55 + 56 + public function getBuildStep() { 57 + return $this->assertAttached($this->buildStep); 58 + } 59 + 60 + public function getDetail($key, $default = null) { 61 + return idx($this->details, $key, $default); 62 + } 63 + 64 + public function setDetail($key, $value) { 65 + $this->details[$key] = $value; 66 + return $this; 67 + } 68 + 69 + public function getVariable($key, $default = null) { 70 + return idx($this->variables, $key, $default); 71 + } 72 + 73 + public function setVariable($key, $value) { 74 + $this->variables[$key] = $value; 75 + return $this; 76 + } 77 + 78 + public function getImplementation() { 79 + if ($this->className === null) { 80 + throw new Exception("No implementation set for the given target."); 81 + } 82 + 83 + static $implementations = null; 84 + if ($implementations === null) { 85 + $implementations = BuildStepImplementation::getImplementations(); 86 + } 87 + 88 + $class = $this->className; 89 + if (!in_array($class, $implementations)) { 90 + throw new Exception( 91 + "Class name '".$class."' does not extend BuildStepImplementation."); 92 + } 93 + $implementation = newv($class, array()); 94 + $implementation->loadSettings($this); 95 + return $implementation; 96 + } 97 + 98 + 99 + /* -( PhabricatorPolicyInterface )----------------------------------------- */ 100 + 101 + 102 + public function getCapabilities() { 103 + return array( 104 + PhabricatorPolicyCapability::CAN_VIEW, 105 + ); 106 + } 107 + 108 + public function getPolicy($capability) { 109 + return $this->getBuild()->getPolicy($capability); 110 + } 111 + 112 + public function hasAutomaticCapability($capability, PhabricatorUser $viewer) { 113 + return $this->getBuild()->hasAutomaticCapability( 114 + $capability, 115 + $viewer); 116 + } 117 + 118 + public function describeAutomaticCapability($capability) { 119 + return pht( 120 + 'Users must be able to see a build to view its build targets.'); 14 121 } 15 122 16 123 }
-20
src/applications/harbormaster/storage/configuration/HarbormasterBuildStep.php
··· 41 41 return $this; 42 42 } 43 43 44 - public function getStepImplementation() { 45 - if ($this->className === null) { 46 - throw new Exception("No implementation set for the given step."); 47 - } 48 - 49 - static $implementations = null; 50 - if ($implementations === null) { 51 - $implementations = BuildStepImplementation::getImplementations(); 52 - } 53 - 54 - $class = $this->className; 55 - if (!in_array($class, $implementations)) { 56 - throw new Exception( 57 - "Class name '".$class."' does not extend BuildStepImplementation."); 58 - } 59 - $implementation = newv($class, array()); 60 - $implementation->loadSettings($this); 61 - return $implementation; 62 - } 63 - 64 44 65 45 /* -( PhabricatorPolicyInterface )----------------------------------------- */ 66 46
+11 -2
src/applications/harbormaster/worker/HarbormasterBuildWorker.php
··· 45 45 46 46 // Perform the build. 47 47 foreach ($steps as $step) { 48 - $implementation = $step->getStepImplementation(); 48 + 49 + // Create the target at this step. 50 + // TODO: Support variable artifacts. 51 + $target = HarbormasterBuildTarget::initializeNewBuildTarget( 52 + $build, 53 + $step, 54 + $build->retrieveVariablesFromBuild()); 55 + $target->save(); 56 + 57 + $implementation = $target->getImplementation(); 49 58 if (!$implementation->validateSettings()) { 50 59 $build->setBuildStatus(HarbormasterBuild::STATUS_ERROR); 51 60 break; 52 61 } 53 - $implementation->execute($build, $step); 62 + $implementation->execute($build, $target); 54 63 if ($build->getBuildStatus() !== HarbormasterBuild::STATUS_BUILDING) { 55 64 break; 56 65 }
+4
src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
··· 1796 1796 'type' => 'sql', 1797 1797 'name' => $this->getPatchPath('20131129.drydockresourceblueprint.sql'), 1798 1798 ), 1799 + '20131205.buildtargets.sql' => array( 1800 + 'type' => 'sql', 1801 + 'name' => $this->getPatchPath('20131205.buildtargets.sql'), 1802 + ), 1799 1803 ); 1800 1804 } 1801 1805 }