mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42: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',
|
'FileReplyHandler' => 'applications/files/mail/FileReplyHandler.php',
|
||||||
'HarbormasterBuild' => 'applications/harbormaster/storage/build/HarbormasterBuild.php',
|
'HarbormasterBuild' => 'applications/harbormaster/storage/build/HarbormasterBuild.php',
|
||||||
'HarbormasterBuildArtifact' => 'applications/harbormaster/storage/build/HarbormasterBuildArtifact.php',
|
'HarbormasterBuildArtifact' => 'applications/harbormaster/storage/build/HarbormasterBuildArtifact.php',
|
||||||
|
'HarbormasterBuildArtifactQuery' => 'applications/harbormaster/query/HarbormasterBuildArtifactQuery.php',
|
||||||
'HarbormasterBuildCancelController' => 'applications/harbormaster/controller/HarbormasterBuildCancelController.php',
|
'HarbormasterBuildCancelController' => 'applications/harbormaster/controller/HarbormasterBuildCancelController.php',
|
||||||
'HarbormasterBuildItem' => 'applications/harbormaster/storage/build/HarbormasterBuildItem.php',
|
'HarbormasterBuildItem' => 'applications/harbormaster/storage/build/HarbormasterBuildItem.php',
|
||||||
'HarbormasterBuildItemQuery' => 'applications/harbormaster/query/HarbormasterBuildItemQuery.php',
|
'HarbormasterBuildItemQuery' => 'applications/harbormaster/query/HarbormasterBuildItemQuery.php',
|
||||||
|
@ -698,7 +699,6 @@ phutil_register_library_map(array(
|
||||||
'HarbormasterBuildWorker' => 'applications/harbormaster/worker/HarbormasterBuildWorker.php',
|
'HarbormasterBuildWorker' => 'applications/harbormaster/worker/HarbormasterBuildWorker.php',
|
||||||
'HarbormasterBuildable' => 'applications/harbormaster/storage/HarbormasterBuildable.php',
|
'HarbormasterBuildable' => 'applications/harbormaster/storage/HarbormasterBuildable.php',
|
||||||
'HarbormasterBuildableApplyController' => 'applications/harbormaster/controller/HarbormasterBuildableApplyController.php',
|
'HarbormasterBuildableApplyController' => 'applications/harbormaster/controller/HarbormasterBuildableApplyController.php',
|
||||||
'HarbormasterBuildableArtifactQuery' => 'applications/harbormaster/query/HarbormasterBuildableArtifactQuery.php',
|
|
||||||
'HarbormasterBuildableEditController' => 'applications/harbormaster/controller/HarbormasterBuildableEditController.php',
|
'HarbormasterBuildableEditController' => 'applications/harbormaster/controller/HarbormasterBuildableEditController.php',
|
||||||
'HarbormasterBuildableListController' => 'applications/harbormaster/controller/HarbormasterBuildableListController.php',
|
'HarbormasterBuildableListController' => 'applications/harbormaster/controller/HarbormasterBuildableListController.php',
|
||||||
'HarbormasterBuildableQuery' => 'applications/harbormaster/query/HarbormasterBuildableQuery.php',
|
'HarbormasterBuildableQuery' => 'applications/harbormaster/query/HarbormasterBuildableQuery.php',
|
||||||
|
@ -3023,6 +3023,7 @@ phutil_register_library_map(array(
|
||||||
0 => 'HarbormasterDAO',
|
0 => 'HarbormasterDAO',
|
||||||
1 => 'PhabricatorPolicyInterface',
|
1 => 'PhabricatorPolicyInterface',
|
||||||
),
|
),
|
||||||
|
'HarbormasterBuildArtifactQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'HarbormasterBuildCancelController' => 'HarbormasterController',
|
'HarbormasterBuildCancelController' => 'HarbormasterController',
|
||||||
'HarbormasterBuildItem' => 'HarbormasterDAO',
|
'HarbormasterBuildItem' => 'HarbormasterDAO',
|
||||||
'HarbormasterBuildItemQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'HarbormasterBuildItemQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
@ -3051,7 +3052,11 @@ phutil_register_library_map(array(
|
||||||
1 => 'PhabricatorPolicyInterface',
|
1 => 'PhabricatorPolicyInterface',
|
||||||
),
|
),
|
||||||
'HarbormasterBuildStepQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'HarbormasterBuildStepQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'HarbormasterBuildTarget' => 'HarbormasterDAO',
|
'HarbormasterBuildTarget' =>
|
||||||
|
array(
|
||||||
|
0 => 'HarbormasterDAO',
|
||||||
|
1 => 'PhabricatorPolicyInterface',
|
||||||
|
),
|
||||||
'HarbormasterBuildTargetQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'HarbormasterBuildTargetQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
'HarbormasterBuildViewController' => 'HarbormasterController',
|
'HarbormasterBuildViewController' => 'HarbormasterController',
|
||||||
'HarbormasterBuildWorker' => 'PhabricatorWorker',
|
'HarbormasterBuildWorker' => 'PhabricatorWorker',
|
||||||
|
@ -3061,7 +3066,6 @@ phutil_register_library_map(array(
|
||||||
1 => 'PhabricatorPolicyInterface',
|
1 => 'PhabricatorPolicyInterface',
|
||||||
),
|
),
|
||||||
'HarbormasterBuildableApplyController' => 'HarbormasterController',
|
'HarbormasterBuildableApplyController' => 'HarbormasterController',
|
||||||
'HarbormasterBuildableArtifactQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
|
||||||
'HarbormasterBuildableEditController' => 'HarbormasterController',
|
'HarbormasterBuildableEditController' => 'HarbormasterController',
|
||||||
'HarbormasterBuildableListController' =>
|
'HarbormasterBuildableListController' =>
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -41,13 +41,47 @@ final class HarbormasterBuildViewController
|
||||||
id(new PhabricatorCrumbView())
|
id(new PhabricatorCrumbView())
|
||||||
->setName($title));
|
->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(
|
return $this->buildApplicationPage(
|
||||||
array(
|
array(
|
||||||
$crumbs,
|
$crumbs,
|
||||||
$box,
|
$box,
|
||||||
$logs
|
$targets
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'title' => $title,
|
'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();
|
$request = $this->getRequest();
|
||||||
$viewer = $request->getUser();
|
$viewer = $request->getUser();
|
||||||
$limit = $request->getInt('l', 25);
|
$limit = $request->getInt('l', 25);
|
||||||
|
|
||||||
$logs = id(new HarbormasterBuildLogQuery())
|
$logs = id(new HarbormasterBuildLogQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->withBuildPHIDs(array($build->getPHID()))
|
->withBuildTargetPHIDs(array($build_target->getPHID()))
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
$log_boxes = array();
|
$log_boxes = array();
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
final class HarbormasterBuildableArtifactQuery
|
final class HarbormasterBuildArtifactQuery
|
||||||
extends PhabricatorCursorPagedPolicyAwareQuery {
|
extends PhabricatorCursorPagedPolicyAwareQuery {
|
||||||
|
|
||||||
private $ids;
|
private $ids;
|
||||||
private $buildablePHIDs;
|
private $buildTargetPHIDs;
|
||||||
private $artifactTypes;
|
private $artifactTypes;
|
||||||
private $artifactKeys;
|
private $artifactKeys;
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ final class HarbormasterBuildableArtifactQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function withBuildablePHIDs(array $buildable_phids) {
|
public function withBuildTargetPHIDs(array $build_target_phids) {
|
||||||
$this->buildablePHIDs = $buildable_phids;
|
$this->buildTargetPHIDs = $build_target_phids;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,25 +44,25 @@ final class HarbormasterBuildableArtifactQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function willFilterPage(array $page) {
|
protected function willFilterPage(array $page) {
|
||||||
$buildables = array();
|
$build_targets = array();
|
||||||
|
|
||||||
$buildable_phids = array_filter(mpull($page, 'getBuildablePHID'));
|
$build_target_phids = array_filter(mpull($page, 'getBuildTargetPHID'));
|
||||||
if ($buildable_phids) {
|
if ($build_target_phids) {
|
||||||
$buildables = id(new PhabricatorObjectQuery())
|
$build_targets = id(new HarbormasterBuildTargetQuery())
|
||||||
->setViewer($this->getViewer())
|
->setViewer($this->getViewer())
|
||||||
->withPHIDs($buildable_phids)
|
->withPHIDs($build_target_phids)
|
||||||
->setParentQuery($this)
|
->setParentQuery($this)
|
||||||
->execute();
|
->execute();
|
||||||
$buildables = mpull($buildables, null, 'getPHID');
|
$build_targets = mpull($build_targets, null, 'getPHID');
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($page as $key => $artifact) {
|
foreach ($page as $key => $build_log) {
|
||||||
$buildable_phid = $artifact->getBuildablePHID();
|
$build_target_phid = $build_log->getBuildTargetPHID();
|
||||||
if (empty($buildables[$buildable_phid])) {
|
if (empty($build_targets[$build_target_phid])) {
|
||||||
unset($page[$key]);
|
unset($page[$key]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$artifact->attachBuildable($buildables[$buildable_phid]);
|
$build_log->attachBuildTarget($build_targets[$build_target_phid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $page;
|
return $page;
|
||||||
|
@ -78,11 +78,11 @@ final class HarbormasterBuildableArtifactQuery
|
||||||
$this->ids);
|
$this->ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->buildablePHIDs) {
|
if ($this->buildTargetPHIDs) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn_r,
|
||||||
'buildablePHID IN (%Ls)',
|
'buildTargetPHID IN (%Ls)',
|
||||||
$this->buildablePHIDs);
|
$this->buildTargetPHIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->artifactTypes) {
|
if ($this->artifactTypes) {
|
|
@ -17,8 +17,8 @@ final class HarbormasterBuildLogQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function withBuildPHIDs(array $build_phids) {
|
public function withBuildTargetPHIDs(array $build_target_phids) {
|
||||||
$this->buildPHIDs = $build_phids;
|
$this->buildTargetPHIDs = $build_target_phids;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,25 +38,25 @@ final class HarbormasterBuildLogQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function willFilterPage(array $page) {
|
protected function willFilterPage(array $page) {
|
||||||
$builds = array();
|
$build_targets = array();
|
||||||
|
|
||||||
$build_phids = array_filter(mpull($page, 'getBuildPHID'));
|
$build_target_phids = array_filter(mpull($page, 'getBuildTargetPHID'));
|
||||||
if ($build_phids) {
|
if ($build_target_phids) {
|
||||||
$builds = id(new HarbormasterBuildQuery())
|
$build_targets = id(new HarbormasterBuildTargetQuery())
|
||||||
->setViewer($this->getViewer())
|
->setViewer($this->getViewer())
|
||||||
->withPHIDs($build_phids)
|
->withPHIDs($build_target_phids)
|
||||||
->setParentQuery($this)
|
->setParentQuery($this)
|
||||||
->execute();
|
->execute();
|
||||||
$builds = mpull($builds, null, 'getPHID');
|
$build_targets = mpull($build_targets, null, 'getPHID');
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($page as $key => $build_log) {
|
foreach ($page as $key => $build_log) {
|
||||||
$build_phid = $build_log->getBuildPHID();
|
$build_target_phid = $build_log->getBuildTargetPHID();
|
||||||
if (empty($builds[$build_phid])) {
|
if (empty($build_targets[$build_target_phid])) {
|
||||||
unset($page[$key]);
|
unset($page[$key]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$build_log->attachBuild($builds[$build_phid]);
|
$build_log->attachBuildTarget($build_targets[$build_target_phid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $page;
|
return $page;
|
||||||
|
@ -79,11 +79,11 @@ final class HarbormasterBuildLogQuery
|
||||||
$this->phids);
|
$this->phids);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->buildPHIDs) {
|
if ($this->buildTargetPHIDs) {
|
||||||
$where[] = qsprintf(
|
$where[] = qsprintf(
|
||||||
$conn_r,
|
$conn_r,
|
||||||
'buildPHID IN (%Ls)',
|
'buildTargetPHID IN (%Ls)',
|
||||||
$this->buildPHIDs);
|
$this->buildTargetPHIDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
$where[] = $this->buildPagingClause($conn_r);
|
$where[] = $this->buildPagingClause($conn_r);
|
||||||
|
|
|
@ -5,6 +5,7 @@ final class HarbormasterBuildTargetQuery
|
||||||
|
|
||||||
private $ids;
|
private $ids;
|
||||||
private $phids;
|
private $phids;
|
||||||
|
private $buildPHIDs;
|
||||||
|
|
||||||
public function withIDs(array $ids) {
|
public function withIDs(array $ids) {
|
||||||
$this->ids = $ids;
|
$this->ids = $ids;
|
||||||
|
@ -16,6 +17,11 @@ final class HarbormasterBuildTargetQuery
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withBuildPHIDs(array $build_phids) {
|
||||||
|
$this->buildPHIDs = $build_phids;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
protected function loadPage() {
|
protected function loadPage() {
|
||||||
$table = new HarbormasterBuildTarget();
|
$table = new HarbormasterBuildTarget();
|
||||||
$conn_r = $table->establishConnection('r');
|
$conn_r = $table->establishConnection('r');
|
||||||
|
@ -48,11 +54,43 @@ final class HarbormasterBuildTargetQuery
|
||||||
$this->phids);
|
$this->phids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->buildPHIDs) {
|
||||||
|
$where[] = qsprintf(
|
||||||
|
$conn_r,
|
||||||
|
'buildPHID in (%Ls)',
|
||||||
|
$this->buildPHIDs);
|
||||||
|
}
|
||||||
|
|
||||||
$where[] = $this->buildPagingClause($conn_r);
|
$where[] = $this->buildPagingClause($conn_r);
|
||||||
|
|
||||||
return $this->formatWhereClause($where);
|
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() {
|
public function getQueryApplicationClass() {
|
||||||
return 'PhabricatorApplicationHarbormaster';
|
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(
|
abstract public function execute(
|
||||||
HarbormasterBuild $build,
|
HarbormasterBuild $build,
|
||||||
HarbormasterBuildStep $build_step);
|
HarbormasterBuildTarget $build_target);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the settings for this build step.
|
* 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->settings = array();
|
||||||
$this->validateSettingDefinitions();
|
$this->validateSettingDefinitions();
|
||||||
foreach ($this->getSettingDefinitions() as $name => $opt) {
|
foreach ($this->getSettingDefinitions() as $name => $opt) {
|
||||||
$this->settings[$name] = $build_step->getDetail($name);
|
$this->settings[$name] = $build_target->getDetail($name);
|
||||||
}
|
}
|
||||||
return $this->settings;
|
return $this->settings;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,17 +21,17 @@ final class HarbormasterHTTPRequestBuildStepImplementation
|
||||||
|
|
||||||
public function execute(
|
public function execute(
|
||||||
HarbormasterBuild $build,
|
HarbormasterBuild $build,
|
||||||
HarbormasterBuildStep $build_step) {
|
HarbormasterBuildTarget $build_target) {
|
||||||
|
|
||||||
$settings = $this->getSettings();
|
$settings = $this->getSettings();
|
||||||
$variables = $this->retrieveVariablesFromBuild($build);
|
$variables = $build_target->getVariables();
|
||||||
|
|
||||||
$uri = $this->mergeVariables(
|
$uri = $this->mergeVariables(
|
||||||
'vurisprintf',
|
'vurisprintf',
|
||||||
$settings['uri'],
|
$settings['uri'],
|
||||||
$variables);
|
$variables);
|
||||||
|
|
||||||
$log_body = $build->createLog($build_step, $uri, 'http-body');
|
$log_body = $build->createLog($build_target, $uri, 'http-body');
|
||||||
$start = $log_body->start();
|
$start = $log_body->start();
|
||||||
|
|
||||||
list($status, $body, $headers) = id(new HTTPSFuture($uri))
|
list($status, $body, $headers) = id(new HTTPSFuture($uri))
|
||||||
|
|
|
@ -22,10 +22,10 @@ final class RemoteCommandBuildStepImplementation
|
||||||
|
|
||||||
public function execute(
|
public function execute(
|
||||||
HarbormasterBuild $build,
|
HarbormasterBuild $build,
|
||||||
HarbormasterBuildStep $build_step) {
|
HarbormasterBuildTarget $build_target) {
|
||||||
|
|
||||||
$settings = $this->getSettings();
|
$settings = $this->getSettings();
|
||||||
$variables = $this->retrieveVariablesFromBuild($build);
|
$variables = $build_target->getVariables();
|
||||||
|
|
||||||
$command = $this->mergeVariables(
|
$command = $this->mergeVariables(
|
||||||
'vcsprintf',
|
'vcsprintf',
|
||||||
|
@ -48,8 +48,8 @@ final class RemoteCommandBuildStepImplementation
|
||||||
$command);
|
$command);
|
||||||
}
|
}
|
||||||
|
|
||||||
$log_stdout = $build->createLog($build_step, "remote", "stdout");
|
$log_stdout = $build->createLog($build_target, "remote", "stdout");
|
||||||
$log_stderr = $build->createLog($build_step, "remote", "stderr");
|
$log_stderr = $build->createLog($build_target, "remote", "stderr");
|
||||||
|
|
||||||
$start_stdout = $log_stdout->start();
|
$start_stdout = $log_stdout->start();
|
||||||
$start_stderr = $log_stderr->start();
|
$start_stderr = $log_stderr->start();
|
||||||
|
|
|
@ -18,7 +18,7 @@ final class SleepBuildStepImplementation extends BuildStepImplementation {
|
||||||
|
|
||||||
public function execute(
|
public function execute(
|
||||||
HarbormasterBuild $build,
|
HarbormasterBuild $build,
|
||||||
HarbormasterBuildStep $build_step) {
|
HarbormasterBuildTarget $build_target) {
|
||||||
|
|
||||||
$settings = $this->getSettings();
|
$settings = $this->getSettings();
|
||||||
|
|
||||||
|
|
|
@ -2,41 +2,6 @@
|
||||||
|
|
||||||
abstract class VariableBuildStepImplementation extends BuildStepImplementation {
|
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:
|
* 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);
|
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() {
|
public function getSettingRemarkupInstructions() {
|
||||||
$text = '';
|
$text = '';
|
||||||
$text .= pht('The following variables are available: ')."\n";
|
$text .= pht('The following variables are available: ')."\n";
|
||||||
|
|
|
@ -95,11 +95,11 @@ final class HarbormasterBuild extends HarbormasterDAO
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createLog(
|
public function createLog(
|
||||||
HarbormasterBuildStep $build_step,
|
HarbormasterBuildTarget $build_target,
|
||||||
$log_source,
|
$log_source,
|
||||||
$log_type) {
|
$log_type) {
|
||||||
|
|
||||||
$log = HarbormasterBuildLog::initializeNewBuildLog($this, $build_step);
|
$log = HarbormasterBuildLog::initializeNewBuildLog($build_target);
|
||||||
$log->setLogSource($log_source);
|
$log->setLogSource($log_source);
|
||||||
$log->setLogType($log_type);
|
$log->setLogType($log_type);
|
||||||
$log->save();
|
$log->save();
|
||||||
|
@ -125,6 +125,57 @@ final class HarbormasterBuild extends HarbormasterDAO
|
||||||
return false;
|
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 )----------------------------------------- */
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,13 @@
|
||||||
final class HarbormasterBuildLog extends HarbormasterDAO
|
final class HarbormasterBuildLog extends HarbormasterDAO
|
||||||
implements PhabricatorPolicyInterface {
|
implements PhabricatorPolicyInterface {
|
||||||
|
|
||||||
protected $buildPHID;
|
protected $buildTargetPHID;
|
||||||
protected $buildStepPHID;
|
|
||||||
protected $logSource;
|
protected $logSource;
|
||||||
protected $logType;
|
protected $logType;
|
||||||
protected $duration;
|
protected $duration;
|
||||||
protected $live;
|
protected $live;
|
||||||
|
|
||||||
private $build = self::ATTACHABLE;
|
private $buildTarget = self::ATTACHABLE;
|
||||||
private $buildStep = self::ATTACHABLE;
|
|
||||||
|
|
||||||
const CHUNK_BYTE_LIMIT = 102400;
|
const CHUNK_BYTE_LIMIT = 102400;
|
||||||
|
|
||||||
|
@ -21,12 +19,10 @@ final class HarbormasterBuildLog extends HarbormasterDAO
|
||||||
const ENCODING_TEXT = 'text';
|
const ENCODING_TEXT = 'text';
|
||||||
|
|
||||||
public static function initializeNewBuildLog(
|
public static function initializeNewBuildLog(
|
||||||
HarbormasterBuild $build,
|
HarbormasterBuildTarget $build_target) {
|
||||||
HarbormasterBuildStep $build_step) {
|
|
||||||
|
|
||||||
return id(new HarbormasterBuildLog())
|
return id(new HarbormasterBuildLog())
|
||||||
->setBuildPHID($build->getPHID())
|
->setBuildTargetPHID($build_target->getPHID())
|
||||||
->setBuildStepPHID($build_step->getPHID())
|
|
||||||
->setDuration(null)
|
->setDuration(null)
|
||||||
->setLive(0);
|
->setLive(0);
|
||||||
}
|
}
|
||||||
|
@ -42,29 +38,19 @@ final class HarbormasterBuildLog extends HarbormasterDAO
|
||||||
HarbormasterPHIDTypeBuildLog::TYPECONST);
|
HarbormasterPHIDTypeBuildLog::TYPECONST);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function attachBuild(HarbormasterBuild $build) {
|
public function attachBuildTarget(HarbormasterBuildTarget $build_target) {
|
||||||
$this->build = $build;
|
$this->buildTarget = $build_target;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getBuild() {
|
public function getBuildTarget() {
|
||||||
return $this->assertAttached($this->build);
|
return $this->assertAttached($this->buildTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getName() {
|
public function getName() {
|
||||||
return pht('Build Log');
|
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() {
|
public function start() {
|
||||||
if ($this->getLive()) {
|
if ($this->getLive()) {
|
||||||
throw new Exception("Live logging has already started for this log.");
|
throw new Exception("Live logging has already started for this log.");
|
||||||
|
@ -189,18 +175,18 @@ final class HarbormasterBuildLog extends HarbormasterDAO
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPolicy($capability) {
|
public function getPolicy($capability) {
|
||||||
return $this->getBuild()->getPolicy($capability);
|
return $this->getBuildTarget()->getPolicy($capability);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
|
||||||
return $this->getBuild()->hasAutomaticCapability(
|
return $this->getBuildTarget()->hasAutomaticCapability(
|
||||||
$capability,
|
$capability,
|
||||||
$viewer);
|
$viewer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function describeAutomaticCapability($capability) {
|
public function describeAutomaticCapability($capability) {
|
||||||
return pht(
|
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
|
<?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() {
|
public function getConfiguration() {
|
||||||
return array(
|
return array(
|
||||||
self::CONFIG_AUX_PHID => true,
|
self::CONFIG_AUX_PHID => true,
|
||||||
|
self::CONFIG_SERIALIZATION => array(
|
||||||
|
'details' => self::SERIALIZATION_JSON,
|
||||||
|
'variables' => self::SERIALIZATION_JSON,
|
||||||
|
)
|
||||||
) + parent::getConfiguration();
|
) + parent::getConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,4 +39,85 @@ final class HarbormasterBuildTarget extends HarbormasterDAO {
|
||||||
HarbormasterPHIDTypeBuildTarget::TYPECONST);
|
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;
|
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 )----------------------------------------- */
|
/* -( PhabricatorPolicyInterface )----------------------------------------- */
|
||||||
|
|
||||||
|
|
|
@ -45,12 +45,21 @@ final class HarbormasterBuildWorker extends PhabricatorWorker {
|
||||||
|
|
||||||
// Perform the build.
|
// Perform the build.
|
||||||
foreach ($steps as $step) {
|
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()) {
|
if (!$implementation->validateSettings()) {
|
||||||
$build->setBuildStatus(HarbormasterBuild::STATUS_ERROR);
|
$build->setBuildStatus(HarbormasterBuild::STATUS_ERROR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$implementation->execute($build, $step);
|
$implementation->execute($build, $target);
|
||||||
if ($build->getBuildStatus() !== HarbormasterBuild::STATUS_BUILDING) {
|
if ($build->getBuildStatus() !== HarbormasterBuild::STATUS_BUILDING) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1796,6 +1796,10 @@ final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList {
|
||||||
'type' => 'sql',
|
'type' => 'sql',
|
||||||
'name' => $this->getPatchPath('20131129.drydockresourceblueprint.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