mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 14:52:41 +01:00
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
This commit is contained in:
parent
2aad7289fd
commit
53250d84df
17 changed files with 349 additions and 154 deletions
32
resources/sql/patches/20131205.buildtargets.sql
Normal file
32
resources/sql/patches/20131205.buildtargets.sql
Normal file
|
@ -0,0 +1,32 @@
|
|||
CREATE TABLE {$NAMESPACE}_harbormaster.harbormaster_buildtarget (
|
||||
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
phid VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||
buildPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||
buildStepPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
|
||||
className VARCHAR(255) NOT NULL COLLATE utf8_bin,
|
||||
details LONGTEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
|
||||
variables LONGTEXT CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
|
||||
dateCreated INT UNSIGNED NOT NULL,
|
||||
dateModified INT UNSIGNED NOT NULL,
|
||||
KEY `key_build` (buildPHID, buildStepPHID),
|
||||
UNIQUE KEY `key_phid` (phid)
|
||||
) ENGINE=InnoDB, COLLATE utf8_general_ci;
|
||||
|
||||
TRUNCATE TABLE {$NAMESPACE}_harbormaster.harbormaster_buildlog;
|
||||
TRUNCATE TABLE {$NAMESPACE}_harbormaster.harbormaster_buildlogchunk;
|
||||
TRUNCATE TABLE {$NAMESPACE}_harbormaster.harbormaster_buildartifact;
|
||||
|
||||
ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_buildlog
|
||||
DROP COLUMN buildPHID;
|
||||
|
||||
ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_buildlog
|
||||
DROP COLUMN buildStepPHID;
|
||||
|
||||
ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_buildartifact
|
||||
DROP COLUMN buildablePHID;
|
||||
|
||||
ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_buildlog
|
||||
ADD COLUMN buildTargetPHID VARCHAR(64) NOT NULL COLLATE utf8_bin;
|
||||
|
||||
ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_buildartifact
|
||||
ADD COLUMN buildTargetPHID VARCHAR(64) NOT NULL COLLATE utf8_bin;
|
|
@ -677,6 +677,7 @@ phutil_register_library_map(array(
|
|||
'FileReplyHandler' => 'applications/files/mail/FileReplyHandler.php',
|
||||
'HarbormasterBuild' => 'applications/harbormaster/storage/build/HarbormasterBuild.php',
|
||||
'HarbormasterBuildArtifact' => 'applications/harbormaster/storage/build/HarbormasterBuildArtifact.php',
|
||||
'HarbormasterBuildArtifactQuery' => 'applications/harbormaster/query/HarbormasterBuildArtifactQuery.php',
|
||||
'HarbormasterBuildCancelController' => 'applications/harbormaster/controller/HarbormasterBuildCancelController.php',
|
||||
'HarbormasterBuildItem' => 'applications/harbormaster/storage/build/HarbormasterBuildItem.php',
|
||||
'HarbormasterBuildItemQuery' => 'applications/harbormaster/query/HarbormasterBuildItemQuery.php',
|
||||
|
@ -698,7 +699,6 @@ phutil_register_library_map(array(
|
|||
'HarbormasterBuildWorker' => 'applications/harbormaster/worker/HarbormasterBuildWorker.php',
|
||||
'HarbormasterBuildable' => 'applications/harbormaster/storage/HarbormasterBuildable.php',
|
||||
'HarbormasterBuildableApplyController' => 'applications/harbormaster/controller/HarbormasterBuildableApplyController.php',
|
||||
'HarbormasterBuildableArtifactQuery' => 'applications/harbormaster/query/HarbormasterBuildableArtifactQuery.php',
|
||||
'HarbormasterBuildableEditController' => 'applications/harbormaster/controller/HarbormasterBuildableEditController.php',
|
||||
'HarbormasterBuildableListController' => 'applications/harbormaster/controller/HarbormasterBuildableListController.php',
|
||||
'HarbormasterBuildableQuery' => 'applications/harbormaster/query/HarbormasterBuildableQuery.php',
|
||||
|
@ -3023,6 +3023,7 @@ phutil_register_library_map(array(
|
|||
0 => 'HarbormasterDAO',
|
||||
1 => 'PhabricatorPolicyInterface',
|
||||
),
|
||||
'HarbormasterBuildArtifactQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'HarbormasterBuildCancelController' => 'HarbormasterController',
|
||||
'HarbormasterBuildItem' => 'HarbormasterDAO',
|
||||
'HarbormasterBuildItemQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
|
@ -3051,7 +3052,11 @@ phutil_register_library_map(array(
|
|||
1 => 'PhabricatorPolicyInterface',
|
||||
),
|
||||
'HarbormasterBuildStepQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'HarbormasterBuildTarget' => 'HarbormasterDAO',
|
||||
'HarbormasterBuildTarget' =>
|
||||
array(
|
||||
0 => 'HarbormasterDAO',
|
||||
1 => 'PhabricatorPolicyInterface',
|
||||
),
|
||||
'HarbormasterBuildTargetQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'HarbormasterBuildViewController' => 'HarbormasterController',
|
||||
'HarbormasterBuildWorker' => 'PhabricatorWorker',
|
||||
|
@ -3061,7 +3066,6 @@ phutil_register_library_map(array(
|
|||
1 => 'PhabricatorPolicyInterface',
|
||||
),
|
||||
'HarbormasterBuildableApplyController' => 'HarbormasterController',
|
||||
'HarbormasterBuildableArtifactQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||
'HarbormasterBuildableEditController' => 'HarbormasterController',
|
||||
'HarbormasterBuildableListController' =>
|
||||
array(
|
||||
|
|
|
@ -41,13 +41,47 @@ final class HarbormasterBuildViewController
|
|||
id(new PhabricatorCrumbView())
|
||||
->setName($title));
|
||||
|
||||
$logs = $this->buildLog($build);
|
||||
$build_targets = id(new HarbormasterBuildTargetQuery())
|
||||
->setViewer($viewer)
|
||||
->withBuildPHIDs(array($build->getPHID()))
|
||||
->execute();
|
||||
|
||||
$targets = array();
|
||||
foreach ($build_targets as $build_target) {
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Build Target %d', $build_target->getID()))
|
||||
->setUser($viewer);
|
||||
$properties = new PHUIPropertyListView();
|
||||
|
||||
$details = $build_target->getDetails();
|
||||
if ($details) {
|
||||
$properties->addSectionHeader(pht('Configuration Details'));
|
||||
foreach ($details as $key => $value) {
|
||||
$properties->addProperty($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
$variables = $build_target->getVariables();
|
||||
if ($variables) {
|
||||
$properties->addSectionHeader(pht('Variables'));
|
||||
foreach ($variables as $key => $value) {
|
||||
$properties->addProperty($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
$targets[] = id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->addPropertyList($properties);
|
||||
|
||||
$targets[] = $this->buildLog($build, $build_target);
|
||||
}
|
||||
|
||||
|
||||
return $this->buildApplicationPage(
|
||||
array(
|
||||
$crumbs,
|
||||
$box,
|
||||
$logs
|
||||
$targets
|
||||
),
|
||||
array(
|
||||
'title' => $title,
|
||||
|
@ -55,14 +89,17 @@ final class HarbormasterBuildViewController
|
|||
));
|
||||
}
|
||||
|
||||
private function buildLog(HarbormasterBuild $build) {
|
||||
private function buildLog(
|
||||
HarbormasterBuild $build,
|
||||
HarbormasterBuildTarget $build_target) {
|
||||
|
||||
$request = $this->getRequest();
|
||||
$viewer = $request->getUser();
|
||||
$limit = $request->getInt('l', 25);
|
||||
|
||||
$logs = id(new HarbormasterBuildLogQuery())
|
||||
->setViewer($viewer)
|
||||
->withBuildPHIDs(array($build->getPHID()))
|
||||
->withBuildTargetPHIDs(array($build_target->getPHID()))
|
||||
->execute();
|
||||
|
||||
$log_boxes = array();
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<?php
|
||||
|
||||
final class HarbormasterBuildableArtifactQuery
|
||||
final class HarbormasterBuildArtifactQuery
|
||||
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||
|
||||
private $ids;
|
||||
private $buildablePHIDs;
|
||||
private $buildTargetPHIDs;
|
||||
private $artifactTypes;
|
||||
private $artifactKeys;
|
||||
|
||||
|
@ -13,8 +13,8 @@ final class HarbormasterBuildableArtifactQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function withBuildablePHIDs(array $buildable_phids) {
|
||||
$this->buildablePHIDs = $buildable_phids;
|
||||
public function withBuildTargetPHIDs(array $build_target_phids) {
|
||||
$this->buildTargetPHIDs = $build_target_phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -44,25 +44,25 @@ final class HarbormasterBuildableArtifactQuery
|
|||
}
|
||||
|
||||
protected function willFilterPage(array $page) {
|
||||
$buildables = array();
|
||||
$build_targets = array();
|
||||
|
||||
$buildable_phids = array_filter(mpull($page, 'getBuildablePHID'));
|
||||
if ($buildable_phids) {
|
||||
$buildables = id(new PhabricatorObjectQuery())
|
||||
$build_target_phids = array_filter(mpull($page, 'getBuildTargetPHID'));
|
||||
if ($build_target_phids) {
|
||||
$build_targets = id(new HarbormasterBuildTargetQuery())
|
||||
->setViewer($this->getViewer())
|
||||
->withPHIDs($buildable_phids)
|
||||
->withPHIDs($build_target_phids)
|
||||
->setParentQuery($this)
|
||||
->execute();
|
||||
$buildables = mpull($buildables, null, 'getPHID');
|
||||
$build_targets = mpull($build_targets, null, 'getPHID');
|
||||
}
|
||||
|
||||
foreach ($page as $key => $artifact) {
|
||||
$buildable_phid = $artifact->getBuildablePHID();
|
||||
if (empty($buildables[$buildable_phid])) {
|
||||
foreach ($page as $key => $build_log) {
|
||||
$build_target_phid = $build_log->getBuildTargetPHID();
|
||||
if (empty($build_targets[$build_target_phid])) {
|
||||
unset($page[$key]);
|
||||
continue;
|
||||
}
|
||||
$artifact->attachBuildable($buildables[$buildable_phid]);
|
||||
$build_log->attachBuildTarget($build_targets[$build_target_phid]);
|
||||
}
|
||||
|
||||
return $page;
|
||||
|
@ -78,11 +78,11 @@ final class HarbormasterBuildableArtifactQuery
|
|||
$this->ids);
|
||||
}
|
||||
|
||||
if ($this->buildablePHIDs) {
|
||||
if ($this->buildTargetPHIDs) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
'buildablePHID IN (%Ls)',
|
||||
$this->buildablePHIDs);
|
||||
'buildTargetPHID IN (%Ls)',
|
||||
$this->buildTargetPHIDs);
|
||||
}
|
||||
|
||||
if ($this->artifactTypes) {
|
|
@ -17,8 +17,8 @@ final class HarbormasterBuildLogQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function withBuildPHIDs(array $build_phids) {
|
||||
$this->buildPHIDs = $build_phids;
|
||||
public function withBuildTargetPHIDs(array $build_target_phids) {
|
||||
$this->buildTargetPHIDs = $build_target_phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -38,25 +38,25 @@ final class HarbormasterBuildLogQuery
|
|||
}
|
||||
|
||||
protected function willFilterPage(array $page) {
|
||||
$builds = array();
|
||||
$build_targets = array();
|
||||
|
||||
$build_phids = array_filter(mpull($page, 'getBuildPHID'));
|
||||
if ($build_phids) {
|
||||
$builds = id(new HarbormasterBuildQuery())
|
||||
$build_target_phids = array_filter(mpull($page, 'getBuildTargetPHID'));
|
||||
if ($build_target_phids) {
|
||||
$build_targets = id(new HarbormasterBuildTargetQuery())
|
||||
->setViewer($this->getViewer())
|
||||
->withPHIDs($build_phids)
|
||||
->withPHIDs($build_target_phids)
|
||||
->setParentQuery($this)
|
||||
->execute();
|
||||
$builds = mpull($builds, null, 'getPHID');
|
||||
$build_targets = mpull($build_targets, null, 'getPHID');
|
||||
}
|
||||
|
||||
foreach ($page as $key => $build_log) {
|
||||
$build_phid = $build_log->getBuildPHID();
|
||||
if (empty($builds[$build_phid])) {
|
||||
$build_target_phid = $build_log->getBuildTargetPHID();
|
||||
if (empty($build_targets[$build_target_phid])) {
|
||||
unset($page[$key]);
|
||||
continue;
|
||||
}
|
||||
$build_log->attachBuild($builds[$build_phid]);
|
||||
$build_log->attachBuildTarget($build_targets[$build_target_phid]);
|
||||
}
|
||||
|
||||
return $page;
|
||||
|
@ -79,11 +79,11 @@ final class HarbormasterBuildLogQuery
|
|||
$this->phids);
|
||||
}
|
||||
|
||||
if ($this->buildPHIDs) {
|
||||
if ($this->buildTargetPHIDs) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
'buildPHID IN (%Ls)',
|
||||
$this->buildPHIDs);
|
||||
'buildTargetPHID IN (%Ls)',
|
||||
$this->buildTargetPHIDs);
|
||||
}
|
||||
|
||||
$where[] = $this->buildPagingClause($conn_r);
|
||||
|
|
|
@ -5,6 +5,7 @@ final class HarbormasterBuildTargetQuery
|
|||
|
||||
private $ids;
|
||||
private $phids;
|
||||
private $buildPHIDs;
|
||||
|
||||
public function withIDs(array $ids) {
|
||||
$this->ids = $ids;
|
||||
|
@ -16,6 +17,11 @@ final class HarbormasterBuildTargetQuery
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function withBuildPHIDs(array $build_phids) {
|
||||
$this->buildPHIDs = $build_phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function loadPage() {
|
||||
$table = new HarbormasterBuildTarget();
|
||||
$conn_r = $table->establishConnection('r');
|
||||
|
@ -48,11 +54,43 @@ final class HarbormasterBuildTargetQuery
|
|||
$this->phids);
|
||||
}
|
||||
|
||||
if ($this->buildPHIDs) {
|
||||
$where[] = qsprintf(
|
||||
$conn_r,
|
||||
'buildPHID in (%Ls)',
|
||||
$this->buildPHIDs);
|
||||
}
|
||||
|
||||
$where[] = $this->buildPagingClause($conn_r);
|
||||
|
||||
return $this->formatWhereClause($where);
|
||||
}
|
||||
|
||||
protected function willFilterPage(array $page) {
|
||||
$builds = array();
|
||||
|
||||
$build_phids = array_filter(mpull($page, 'getBuildPHID'));
|
||||
if ($build_phids) {
|
||||
$builds = id(new PhabricatorObjectQuery())
|
||||
->setViewer($this->getViewer())
|
||||
->withPHIDs($build_phids)
|
||||
->setParentQuery($this)
|
||||
->execute();
|
||||
$builds = mpull($builds, null, 'getPHID');
|
||||
}
|
||||
|
||||
foreach ($page as $key => $build_target) {
|
||||
$build_phid = $build_target->getBuildPHID();
|
||||
if (empty($builds[$build_phid])) {
|
||||
unset($page[$key]);
|
||||
continue;
|
||||
}
|
||||
$build_target->attachBuild($builds[$build_phid]);
|
||||
}
|
||||
|
||||
return $page;
|
||||
}
|
||||
|
||||
public function getQueryApplicationClass() {
|
||||
return 'PhabricatorApplicationHarbormaster';
|
||||
}
|
||||
|
|
|
@ -36,11 +36,11 @@ abstract class BuildStepImplementation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Run the build step against the specified build.
|
||||
* Run the build target against the specified build.
|
||||
*/
|
||||
abstract public function execute(
|
||||
HarbormasterBuild $build,
|
||||
HarbormasterBuildStep $build_step);
|
||||
HarbormasterBuildTarget $build_target);
|
||||
|
||||
/**
|
||||
* Gets the settings for this build step.
|
||||
|
@ -57,13 +57,13 @@ abstract class BuildStepImplementation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Loads the settings for this build step implementation from the build step.
|
||||
* Loads the settings for this build step implementation from a build target.
|
||||
*/
|
||||
public final function loadSettings(HarbormasterBuildStep $build_step) {
|
||||
public final function loadSettings(HarbormasterBuildTarget $build_target) {
|
||||
$this->settings = array();
|
||||
$this->validateSettingDefinitions();
|
||||
foreach ($this->getSettingDefinitions() as $name => $opt) {
|
||||
$this->settings[$name] = $build_step->getDetail($name);
|
||||
$this->settings[$name] = $build_target->getDetail($name);
|
||||
}
|
||||
return $this->settings;
|
||||
}
|
||||
|
|
|
@ -21,17 +21,17 @@ final class HarbormasterHTTPRequestBuildStepImplementation
|
|||
|
||||
public function execute(
|
||||
HarbormasterBuild $build,
|
||||
HarbormasterBuildStep $build_step) {
|
||||
HarbormasterBuildTarget $build_target) {
|
||||
|
||||
$settings = $this->getSettings();
|
||||
$variables = $this->retrieveVariablesFromBuild($build);
|
||||
$variables = $build_target->getVariables();
|
||||
|
||||
$uri = $this->mergeVariables(
|
||||
'vurisprintf',
|
||||
$settings['uri'],
|
||||
$variables);
|
||||
|
||||
$log_body = $build->createLog($build_step, $uri, 'http-body');
|
||||
$log_body = $build->createLog($build_target, $uri, 'http-body');
|
||||
$start = $log_body->start();
|
||||
|
||||
list($status, $body, $headers) = id(new HTTPSFuture($uri))
|
||||
|
|
|
@ -22,10 +22,10 @@ final class RemoteCommandBuildStepImplementation
|
|||
|
||||
public function execute(
|
||||
HarbormasterBuild $build,
|
||||
HarbormasterBuildStep $build_step) {
|
||||
HarbormasterBuildTarget $build_target) {
|
||||
|
||||
$settings = $this->getSettings();
|
||||
$variables = $this->retrieveVariablesFromBuild($build);
|
||||
$variables = $build_target->getVariables();
|
||||
|
||||
$command = $this->mergeVariables(
|
||||
'vcsprintf',
|
||||
|
@ -48,8 +48,8 @@ final class RemoteCommandBuildStepImplementation
|
|||
$command);
|
||||
}
|
||||
|
||||
$log_stdout = $build->createLog($build_step, "remote", "stdout");
|
||||
$log_stderr = $build->createLog($build_step, "remote", "stderr");
|
||||
$log_stdout = $build->createLog($build_target, "remote", "stdout");
|
||||
$log_stderr = $build->createLog($build_target, "remote", "stderr");
|
||||
|
||||
$start_stdout = $log_stdout->start();
|
||||
$start_stderr = $log_stderr->start();
|
||||
|
|
|
@ -18,7 +18,7 @@ final class SleepBuildStepImplementation extends BuildStepImplementation {
|
|||
|
||||
public function execute(
|
||||
HarbormasterBuild $build,
|
||||
HarbormasterBuildStep $build_step) {
|
||||
HarbormasterBuildTarget $build_target) {
|
||||
|
||||
$settings = $this->getSettings();
|
||||
|
||||
|
|
|
@ -2,41 +2,6 @@
|
|||
|
||||
abstract class VariableBuildStepImplementation extends BuildStepImplementation {
|
||||
|
||||
public function retrieveVariablesFromBuild(HarbormasterBuild $build) {
|
||||
$results = array(
|
||||
'buildable.diff' => null,
|
||||
'buildable.revision' => null,
|
||||
'buildable.commit' => null,
|
||||
'repository.callsign' => null,
|
||||
'repository.vcs' => null,
|
||||
'repository.uri' => null,
|
||||
'step.timestamp' => null,
|
||||
'build.id' => null);
|
||||
|
||||
$buildable = $build->getBuildable();
|
||||
$object = $buildable->getBuildableObject();
|
||||
|
||||
$repo = null;
|
||||
if ($object instanceof DifferentialDiff) {
|
||||
$results['buildable.diff'] = $object->getID();
|
||||
$revision = $object->getRevision();
|
||||
$results['buildable.revision'] = $revision->getID();
|
||||
$repo = $revision->getRepository();
|
||||
} else if ($object instanceof PhabricatorRepositoryCommit) {
|
||||
$results['buildable.commit'] = $object->getCommitIdentifier();
|
||||
$repo = $object->getRepository();
|
||||
}
|
||||
|
||||
$results['repository.callsign'] = $repo->getCallsign();
|
||||
$results['repository.vcs'] = $repo->getVersionControlSystem();
|
||||
$results['repository.uri'] = $repo->getPublicRemoteURI();
|
||||
$results['step.timestamp'] = time();
|
||||
$results['build.id'] = $build->getID();
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert a user-provided string with variables in it, like:
|
||||
*
|
||||
|
@ -71,24 +36,6 @@ abstract class VariableBuildStepImplementation extends BuildStepImplementation {
|
|||
return call_user_func($function, $pattern, $argv);
|
||||
}
|
||||
|
||||
|
||||
public function getAvailableVariables() {
|
||||
return array(
|
||||
'buildable.diff' =>
|
||||
pht('The differential diff ID, if applicable.'),
|
||||
'buildable.revision' =>
|
||||
pht('The differential revision ID, if applicable.'),
|
||||
'buildable.commit' => pht('The commit identifier, if applicable.'),
|
||||
'repository.callsign' =>
|
||||
pht('The callsign of the repository in Phabricator.'),
|
||||
'repository.vcs' =>
|
||||
pht('The version control system, either "svn", "hg" or "git".'),
|
||||
'repository.uri' =>
|
||||
pht('The URI to clone or checkout the repository from.'),
|
||||
'step.timestamp' => pht('The current UNIX timestamp.'),
|
||||
'build.id' => pht('The ID of the current build.'));
|
||||
}
|
||||
|
||||
public function getSettingRemarkupInstructions() {
|
||||
$text = '';
|
||||
$text .= pht('The following variables are available: ')."\n";
|
||||
|
|
|
@ -95,11 +95,11 @@ final class HarbormasterBuild extends HarbormasterDAO
|
|||
}
|
||||
|
||||
public function createLog(
|
||||
HarbormasterBuildStep $build_step,
|
||||
HarbormasterBuildTarget $build_target,
|
||||
$log_source,
|
||||
$log_type) {
|
||||
|
||||
$log = HarbormasterBuildLog::initializeNewBuildLog($this, $build_step);
|
||||
$log = HarbormasterBuildLog::initializeNewBuildLog($build_target);
|
||||
$log->setLogSource($log_source);
|
||||
$log->setLogType($log_type);
|
||||
$log->save();
|
||||
|
@ -125,6 +125,57 @@ final class HarbormasterBuild extends HarbormasterDAO
|
|||
return false;
|
||||
}
|
||||
|
||||
public function retrieveVariablesFromBuild() {
|
||||
$results = array(
|
||||
'buildable.diff' => null,
|
||||
'buildable.revision' => null,
|
||||
'buildable.commit' => null,
|
||||
'repository.callsign' => null,
|
||||
'repository.vcs' => null,
|
||||
'repository.uri' => null,
|
||||
'step.timestamp' => null,
|
||||
'build.id' => null);
|
||||
|
||||
$buildable = $this->getBuildable();
|
||||
$object = $buildable->getBuildableObject();
|
||||
|
||||
$repo = null;
|
||||
if ($object instanceof DifferentialDiff) {
|
||||
$results['buildable.diff'] = $object->getID();
|
||||
$revision = $object->getRevision();
|
||||
$results['buildable.revision'] = $revision->getID();
|
||||
$repo = $revision->getRepository();
|
||||
} else if ($object instanceof PhabricatorRepositoryCommit) {
|
||||
$results['buildable.commit'] = $object->getCommitIdentifier();
|
||||
$repo = $object->getRepository();
|
||||
}
|
||||
|
||||
$results['repository.callsign'] = $repo->getCallsign();
|
||||
$results['repository.vcs'] = $repo->getVersionControlSystem();
|
||||
$results['repository.uri'] = $repo->getPublicRemoteURI();
|
||||
$results['step.timestamp'] = time();
|
||||
$results['build.id'] = $this->getID();
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function getAvailableBuildVariables() {
|
||||
return array(
|
||||
'buildable.diff' =>
|
||||
pht('The differential diff ID, if applicable.'),
|
||||
'buildable.revision' =>
|
||||
pht('The differential revision ID, if applicable.'),
|
||||
'buildable.commit' => pht('The commit identifier, if applicable.'),
|
||||
'repository.callsign' =>
|
||||
pht('The callsign of the repository in Phabricator.'),
|
||||
'repository.vcs' =>
|
||||
pht('The version control system, either "svn", "hg" or "git".'),
|
||||
'repository.uri' =>
|
||||
pht('The URI to clone or checkout the repository from.'),
|
||||
'step.timestamp' => pht('The current UNIX timestamp.'),
|
||||
'build.id' => pht('The ID of the current build.'));
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||
|
||||
|
|
|
@ -3,15 +3,13 @@
|
|||
final class HarbormasterBuildLog extends HarbormasterDAO
|
||||
implements PhabricatorPolicyInterface {
|
||||
|
||||
protected $buildPHID;
|
||||
protected $buildStepPHID;
|
||||
protected $buildTargetPHID;
|
||||
protected $logSource;
|
||||
protected $logType;
|
||||
protected $duration;
|
||||
protected $live;
|
||||
|
||||
private $build = self::ATTACHABLE;
|
||||
private $buildStep = self::ATTACHABLE;
|
||||
private $buildTarget = self::ATTACHABLE;
|
||||
|
||||
const CHUNK_BYTE_LIMIT = 102400;
|
||||
|
||||
|
@ -21,12 +19,10 @@ final class HarbormasterBuildLog extends HarbormasterDAO
|
|||
const ENCODING_TEXT = 'text';
|
||||
|
||||
public static function initializeNewBuildLog(
|
||||
HarbormasterBuild $build,
|
||||
HarbormasterBuildStep $build_step) {
|
||||
HarbormasterBuildTarget $build_target) {
|
||||
|
||||
return id(new HarbormasterBuildLog())
|
||||
->setBuildPHID($build->getPHID())
|
||||
->setBuildStepPHID($build_step->getPHID())
|
||||
->setBuildTargetPHID($build_target->getPHID())
|
||||
->setDuration(null)
|
||||
->setLive(0);
|
||||
}
|
||||
|
@ -42,29 +38,19 @@ final class HarbormasterBuildLog extends HarbormasterDAO
|
|||
HarbormasterPHIDTypeBuildLog::TYPECONST);
|
||||
}
|
||||
|
||||
public function attachBuild(HarbormasterBuild $build) {
|
||||
$this->build = $build;
|
||||
public function attachBuildTarget(HarbormasterBuildTarget $build_target) {
|
||||
$this->buildTarget = $build_target;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBuild() {
|
||||
return $this->assertAttached($this->build);
|
||||
public function getBuildTarget() {
|
||||
return $this->assertAttached($this->buildTarget);
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return pht('Build Log');
|
||||
}
|
||||
|
||||
public function attachBuildStep(
|
||||
HarbormasterBuildStep $build_step = null) {
|
||||
$this->buildStep = $build_step;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBuildStep() {
|
||||
return $this->assertAttached($this->buildStep);
|
||||
}
|
||||
|
||||
public function start() {
|
||||
if ($this->getLive()) {
|
||||
throw new Exception("Live logging has already started for this log.");
|
||||
|
@ -189,18 +175,18 @@ final class HarbormasterBuildLog extends HarbormasterDAO
|
|||
}
|
||||
|
||||
public function getPolicy($capability) {
|
||||
return $this->getBuild()->getPolicy($capability);
|
||||
return $this->getBuildTarget()->getPolicy($capability);
|
||||
}
|
||||
|
||||
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
||||
return $this->getBuild()->hasAutomaticCapability(
|
||||
return $this->getBuildTarget()->hasAutomaticCapability(
|
||||
$capability,
|
||||
$viewer);
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return pht(
|
||||
'Users must be able to see a build to view it\'s build log.');
|
||||
'Users must be able to see a build target to view it\'s build log.');
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,10 +1,36 @@
|
|||
<?php
|
||||
|
||||
final class HarbormasterBuildTarget extends HarbormasterDAO {
|
||||
final class HarbormasterBuildTarget extends HarbormasterDAO
|
||||
implements PhabricatorPolicyInterface {
|
||||
|
||||
protected $buildPHID;
|
||||
protected $buildStepPHID;
|
||||
protected $className;
|
||||
protected $details;
|
||||
protected $variables;
|
||||
|
||||
private $build = self::ATTACHABLE;
|
||||
private $buildStep = self::ATTACHABLE;
|
||||
|
||||
public static function initializeNewBuildTarget(
|
||||
HarbormasterBuild $build,
|
||||
HarbormasterBuildStep $build_step,
|
||||
array $variables) {
|
||||
return id(new HarbormasterBuildTarget())
|
||||
->setBuildPHID($build->getPHID())
|
||||
->setBuildStepPHID($build_step->getPHID())
|
||||
->setClassName($build_step->getClassName())
|
||||
->setDetails($build_step->getDetails())
|
||||
->setVariables($variables);
|
||||
}
|
||||
|
||||
public function getConfiguration() {
|
||||
return array(
|
||||
self::CONFIG_AUX_PHID => true,
|
||||
self::CONFIG_SERIALIZATION => array(
|
||||
'details' => self::SERIALIZATION_JSON,
|
||||
'variables' => self::SERIALIZATION_JSON,
|
||||
)
|
||||
) + parent::getConfiguration();
|
||||
}
|
||||
|
||||
|
@ -13,4 +39,85 @@ final class HarbormasterBuildTarget extends HarbormasterDAO {
|
|||
HarbormasterPHIDTypeBuildTarget::TYPECONST);
|
||||
}
|
||||
|
||||
public function attachBuild(HarbormasterBuild $build) {
|
||||
$this->build = $build;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBuild() {
|
||||
return $this->assertAttached($this->build);
|
||||
}
|
||||
|
||||
public function attachBuildStep(HarbormasterBuildStep $step) {
|
||||
$this->buildStep = $step;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBuildStep() {
|
||||
return $this->assertAttached($this->buildStep);
|
||||
}
|
||||
|
||||
public function getDetail($key, $default = null) {
|
||||
return idx($this->details, $key, $default);
|
||||
}
|
||||
|
||||
public function setDetail($key, $value) {
|
||||
$this->details[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getVariable($key, $default = null) {
|
||||
return idx($this->variables, $key, $default);
|
||||
}
|
||||
|
||||
public function setVariable($key, $value) {
|
||||
$this->variables[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getImplementation() {
|
||||
if ($this->className === null) {
|
||||
throw new Exception("No implementation set for the given target.");
|
||||
}
|
||||
|
||||
static $implementations = null;
|
||||
if ($implementations === null) {
|
||||
$implementations = BuildStepImplementation::getImplementations();
|
||||
}
|
||||
|
||||
$class = $this->className;
|
||||
if (!in_array($class, $implementations)) {
|
||||
throw new Exception(
|
||||
"Class name '".$class."' does not extend BuildStepImplementation.");
|
||||
}
|
||||
$implementation = newv($class, array());
|
||||
$implementation->loadSettings($this);
|
||||
return $implementation;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||
|
||||
|
||||
public function getCapabilities() {
|
||||
return array(
|
||||
PhabricatorPolicyCapability::CAN_VIEW,
|
||||
);
|
||||
}
|
||||
|
||||
public function getPolicy($capability) {
|
||||
return $this->getBuild()->getPolicy($capability);
|
||||
}
|
||||
|
||||
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
||||
return $this->getBuild()->hasAutomaticCapability(
|
||||
$capability,
|
||||
$viewer);
|
||||
}
|
||||
|
||||
public function describeAutomaticCapability($capability) {
|
||||
return pht(
|
||||
'Users must be able to see a build to view its build targets.');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,26 +41,6 @@ final class HarbormasterBuildStep extends HarbormasterDAO
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getStepImplementation() {
|
||||
if ($this->className === null) {
|
||||
throw new Exception("No implementation set for the given step.");
|
||||
}
|
||||
|
||||
static $implementations = null;
|
||||
if ($implementations === null) {
|
||||
$implementations = BuildStepImplementation::getImplementations();
|
||||
}
|
||||
|
||||
$class = $this->className;
|
||||
if (!in_array($class, $implementations)) {
|
||||
throw new Exception(
|
||||
"Class name '".$class."' does not extend BuildStepImplementation.");
|
||||
}
|
||||
$implementation = newv($class, array());
|
||||
$implementation->loadSettings($this);
|
||||
return $implementation;
|
||||
}
|
||||
|
||||
|
||||
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||
|
||||
|
|
|
@ -45,12 +45,21 @@ final class HarbormasterBuildWorker extends PhabricatorWorker {
|
|||
|
||||
// Perform the build.
|
||||
foreach ($steps as $step) {
|
||||
$implementation = $step->getStepImplementation();
|
||||
|
||||
// Create the target at this step.
|
||||
// TODO: Support variable artifacts.
|
||||
$target = HarbormasterBuildTarget::initializeNewBuildTarget(
|
||||
$build,
|
||||
$step,
|
||||
$build->retrieveVariablesFromBuild());
|
||||
$target->save();
|
||||
|
||||
$implementation = $target->getImplementation();
|
||||
if (!$implementation->validateSettings()) {
|
||||
$build->setBuildStatus(HarbormasterBuild::STATUS_ERROR);
|
||||
break;
|
||||
}
|
||||
$implementation->execute($build, $step);
|
||||
$implementation->execute($build, $target);
|
||||
if ($build->getBuildStatus() !== HarbormasterBuild::STATUS_BUILDING) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1796,6 +1796,10 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList {
|
|||
'type' => 'sql',
|
||||
'name' => $this->getPatchPath('20131129.drydockresourceblueprint.sql'),
|
||||
),
|
||||
'20131205.buildtargets.sql' => array(
|
||||
'type' => 'sql',
|
||||
'name' => $this->getPatchPath('20131205.buildtargets.sql'),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue