mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-18 19:40:55 +01:00
Allow builds to have parameters
Summary: Ref T9352. See D13635. Build targets can have variables already, but let builds have them too. This mostly enables future use cases (sub-builds, more sophisticated build triggers). Test Plan: With a custom Herald rule + action like the one in T9352, updated a revision and saw it generate multiple builds with varying parameters. Reviewers: chad, hach-que Reviewed By: hach-que Maniphest Tasks: T9352 Differential Revision: https://secure.phabricator.com/D14222
This commit is contained in:
parent
878a493301
commit
2728a9f964
14 changed files with 108 additions and 27 deletions
|
@ -0,0 +1,5 @@
|
||||||
|
ALTER TABLE {$NAMESPACE}_harbormaster.harbormaster_build
|
||||||
|
ADD buildParameters LONGTEXT COLLATE {$COLLATE_TEXT} NOT NULL;
|
||||||
|
|
||||||
|
UPDATE {$NAMESPACE}_harbormaster.harbormaster_build
|
||||||
|
SET buildParameters = '{}' WHERE buildParameters = '';
|
|
@ -972,6 +972,7 @@ phutil_register_library_map(array(
|
||||||
'HarbormasterBuildPlanTransaction' => 'applications/harbormaster/storage/configuration/HarbormasterBuildPlanTransaction.php',
|
'HarbormasterBuildPlanTransaction' => 'applications/harbormaster/storage/configuration/HarbormasterBuildPlanTransaction.php',
|
||||||
'HarbormasterBuildPlanTransactionQuery' => 'applications/harbormaster/query/HarbormasterBuildPlanTransactionQuery.php',
|
'HarbormasterBuildPlanTransactionQuery' => 'applications/harbormaster/query/HarbormasterBuildPlanTransactionQuery.php',
|
||||||
'HarbormasterBuildQuery' => 'applications/harbormaster/query/HarbormasterBuildQuery.php',
|
'HarbormasterBuildQuery' => 'applications/harbormaster/query/HarbormasterBuildQuery.php',
|
||||||
|
'HarbormasterBuildRequest' => 'applications/harbormaster/engine/HarbormasterBuildRequest.php',
|
||||||
'HarbormasterBuildStep' => 'applications/harbormaster/storage/configuration/HarbormasterBuildStep.php',
|
'HarbormasterBuildStep' => 'applications/harbormaster/storage/configuration/HarbormasterBuildStep.php',
|
||||||
'HarbormasterBuildStepCoreCustomField' => 'applications/harbormaster/customfield/HarbormasterBuildStepCoreCustomField.php',
|
'HarbormasterBuildStepCoreCustomField' => 'applications/harbormaster/customfield/HarbormasterBuildStepCoreCustomField.php',
|
||||||
'HarbormasterBuildStepCustomField' => 'applications/harbormaster/customfield/HarbormasterBuildStepCustomField.php',
|
'HarbormasterBuildStepCustomField' => 'applications/harbormaster/customfield/HarbormasterBuildStepCustomField.php',
|
||||||
|
@ -4757,6 +4758,7 @@ phutil_register_library_map(array(
|
||||||
'HarbormasterBuildPlanTransaction' => 'PhabricatorApplicationTransaction',
|
'HarbormasterBuildPlanTransaction' => 'PhabricatorApplicationTransaction',
|
||||||
'HarbormasterBuildPlanTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
'HarbormasterBuildPlanTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||||
'HarbormasterBuildQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'HarbormasterBuildQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'HarbormasterBuildRequest' => 'Phobject',
|
||||||
'HarbormasterBuildStep' => array(
|
'HarbormasterBuildStep' => array(
|
||||||
'HarbormasterDAO',
|
'HarbormasterDAO',
|
||||||
'PhabricatorApplicationTransactionInterface',
|
'PhabricatorApplicationTransactionInterface',
|
||||||
|
|
|
@ -10,7 +10,7 @@ final class HeraldDifferentialRevisionAdapter
|
||||||
protected $changesets;
|
protected $changesets;
|
||||||
private $haveHunks;
|
private $haveHunks;
|
||||||
|
|
||||||
private $buildPlanPHIDs = array();
|
private $buildRequests = array();
|
||||||
|
|
||||||
public function getAdapterApplicationClass() {
|
public function getAdapterApplicationClass() {
|
||||||
return 'PhabricatorDifferentialApplication';
|
return 'PhabricatorDifferentialApplication';
|
||||||
|
@ -139,12 +139,13 @@ final class HeraldDifferentialRevisionAdapter
|
||||||
return $this->getObject()->getPHID();
|
return $this->getObject()->getPHID();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getQueuedHarbormasterBuildPlanPHIDs() {
|
public function getQueuedHarbormasterBuildRequests() {
|
||||||
return $this->buildPlanPHIDs;
|
return $this->buildRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function queueHarbormasterBuildPlanPHID($phid) {
|
public function queueHarbormasterBuildRequest(
|
||||||
$this->buildPlanPHIDs[] = $phid;
|
HarbormasterBuildRequest $request) {
|
||||||
|
$this->buildRequests[] = $request;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ final class HeraldCommitAdapter
|
||||||
protected $affectedPackages;
|
protected $affectedPackages;
|
||||||
protected $auditNeededPackages;
|
protected $auditNeededPackages;
|
||||||
|
|
||||||
private $buildPlanPHIDs = array();
|
private $buildRequests = array();
|
||||||
|
|
||||||
public function getAdapterApplicationClass() {
|
public function getAdapterApplicationClass() {
|
||||||
return 'PhabricatorDiffusionApplication';
|
return 'PhabricatorDiffusionApplication';
|
||||||
|
@ -308,12 +308,13 @@ final class HeraldCommitAdapter
|
||||||
return $this->getObject()->getRepository()->getPHID();
|
return $this->getObject()->getRepository()->getPHID();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getQueuedHarbormasterBuildPlanPHIDs() {
|
public function getQueuedHarbormasterBuildRequests() {
|
||||||
return $this->buildPlanPHIDs;
|
return $this->buildRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function queueHarbormasterBuildPlanPHID($phid) {
|
public function queueHarbormasterBuildRequest(
|
||||||
$this->buildPlanPHIDs[] = $phid;
|
HarbormasterBuildRequest $request) {
|
||||||
|
$this->buildRequests[] = $request;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ final class HarbormasterPlanRunController extends HarbormasterController {
|
||||||
|
|
||||||
if (!$errors) {
|
if (!$errors) {
|
||||||
$buildable->save();
|
$buildable->save();
|
||||||
$buildable->applyPlan($plan);
|
$buildable->applyPlan($plan, array());
|
||||||
|
|
||||||
$buildable_uri = '/B'.$buildable->getID();
|
$buildable_uri = '/B'.$buildable->getID();
|
||||||
return id(new AphrontRedirectResponse())->setURI($buildable_uri);
|
return id(new AphrontRedirectResponse())->setURI($buildable_uri);
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Structure used to ask Harbormaster to start a build.
|
||||||
|
*
|
||||||
|
* Requests to start builds sometimes originate several layers away from where
|
||||||
|
* they are processed. For example, Herald rules which start builds pass the
|
||||||
|
* requests through the adapter and then through the editor before they reach
|
||||||
|
* Harbormaster.
|
||||||
|
*
|
||||||
|
* This class is just a thin wrapper around these requests so we can make them
|
||||||
|
* more complex later without needing to rewrite any APIs.
|
||||||
|
*/
|
||||||
|
final class HarbormasterBuildRequest extends Phobject {
|
||||||
|
|
||||||
|
private $buildPlanPHID;
|
||||||
|
private $buildParameters = array();
|
||||||
|
|
||||||
|
public function setBuildPlanPHID($build_plan_phid) {
|
||||||
|
$this->buildPlanPHID = $build_plan_phid;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBuildPlanPHID() {
|
||||||
|
return $this->buildPlanPHID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setBuildParameters(array $build_parameters) {
|
||||||
|
$this->buildParameters = $build_parameters;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBuildParameters() {
|
||||||
|
return $this->buildParameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -206,7 +206,7 @@ final class HarbormasterTargetEngine extends Phobject {
|
||||||
// resource and "own" it, so we don't try to handle this, but may need
|
// resource and "own" it, so we don't try to handle this, but may need
|
||||||
// to be more careful here if use of autotargets expands.
|
// to be more careful here if use of autotargets expands.
|
||||||
|
|
||||||
$build = $buildable->applyPlan($plan);
|
$build = $buildable->applyPlan($plan, array());
|
||||||
PhabricatorWorker::setRunAllTasksInProcess(false);
|
PhabricatorWorker::setRunAllTasksInProcess(false);
|
||||||
} catch (Exception $ex) {
|
} catch (Exception $ex) {
|
||||||
PhabricatorWorker::setRunAllTasksInProcess(false);
|
PhabricatorWorker::setRunAllTasksInProcess(false);
|
||||||
|
|
|
@ -4,8 +4,9 @@ interface HarbormasterBuildableAdapterInterface {
|
||||||
|
|
||||||
public function getHarbormasterBuildablePHID();
|
public function getHarbormasterBuildablePHID();
|
||||||
public function getHarbormasterContainerPHID();
|
public function getHarbormasterContainerPHID();
|
||||||
public function getQueuedHarbormasterBuildPlanPHIDs();
|
public function getQueuedHarbormasterBuildRequests();
|
||||||
public function queueHarbormasterBuildPlanPHID($phid);
|
public function queueHarbormasterBuildRequest(
|
||||||
|
HarbormasterBuildRequest $request);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,9 @@ final class HarbormasterRunBuildPlansHeraldAction
|
||||||
$phids = array_fuse(array_keys($targets));
|
$phids = array_fuse(array_keys($targets));
|
||||||
|
|
||||||
foreach ($phids as $phid) {
|
foreach ($phids as $phid) {
|
||||||
$adapter->queueHarbormasterBuildPlanPHID($phid);
|
$request = id(new HarbormasterBuildRequest())
|
||||||
|
->setBuildPlanPHID($phid);
|
||||||
|
$adapter->queueHarbormasterBuildRequest($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->logEffect(self::DO_BUILD, $phids);
|
$this->logEffect(self::DO_BUILD, $phids);
|
||||||
|
|
|
@ -89,7 +89,7 @@ final class HarbormasterManagementBuildWorkflow
|
||||||
PhabricatorEnv::getProductionURI('/B'.$buildable->getID()));
|
PhabricatorEnv::getProductionURI('/B'.$buildable->getID()));
|
||||||
|
|
||||||
PhabricatorWorker::setRunAllTasksInProcess(true);
|
PhabricatorWorker::setRunAllTasksInProcess(true);
|
||||||
$buildable->applyPlan($plan);
|
$buildable->applyPlan($plan, array());
|
||||||
|
|
||||||
$console->writeOut("%s\n", pht('Done.'));
|
$console->writeOut("%s\n", pht('Done.'));
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,7 @@ abstract class HarbormasterBuildStepImplementation extends Phobject {
|
||||||
* @return string String with variables replaced safely into it.
|
* @return string String with variables replaced safely into it.
|
||||||
*/
|
*/
|
||||||
protected function mergeVariables($function, $pattern, array $variables) {
|
protected function mergeVariables($function, $pattern, array $variables) {
|
||||||
$regexp = '/\\$\\{(?P<name>[a-z\\.]+)\\}/';
|
$regexp = '@\\$\\{(?P<name>[a-z\\./-]+)\\}@';
|
||||||
|
|
||||||
$matches = null;
|
$matches = null;
|
||||||
preg_match_all($regexp, $pattern, $matches);
|
preg_match_all($regexp, $pattern, $matches);
|
||||||
|
|
|
@ -96,15 +96,21 @@ final class HarbormasterBuildable extends HarbormasterDAO
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Looks up the plan PHIDs and applies the plans to the specified
|
* Start builds for a given buildable.
|
||||||
* object identified by it's PHID.
|
*
|
||||||
|
* @param phid PHID of the object to build.
|
||||||
|
* @param phid Container PHID for the buildable.
|
||||||
|
* @param list<HarbormasterBuildRequest> List of builds to perform.
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function applyBuildPlans(
|
public static function applyBuildPlans(
|
||||||
$phid,
|
$phid,
|
||||||
$container_phid,
|
$container_phid,
|
||||||
array $plan_phids) {
|
array $requests) {
|
||||||
|
|
||||||
if (!$plan_phids) {
|
assert_instances_of($requests, 'HarbormasterBuildRequest');
|
||||||
|
|
||||||
|
if (!$requests) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,31 +122,49 @@ final class HarbormasterBuildable extends HarbormasterDAO
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||||
|
|
||||||
$buildable = self::createOrLoadExisting(
|
$buildable = self::createOrLoadExisting(
|
||||||
PhabricatorUser::getOmnipotentUser(),
|
$viewer,
|
||||||
$phid,
|
$phid,
|
||||||
$container_phid);
|
$container_phid);
|
||||||
|
|
||||||
|
$plan_phids = mpull($requests, 'getBuildPlanPHID');
|
||||||
$plans = id(new HarbormasterBuildPlanQuery())
|
$plans = id(new HarbormasterBuildPlanQuery())
|
||||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
->setViewer($viewer)
|
||||||
->withPHIDs($plan_phids)
|
->withPHIDs($plan_phids)
|
||||||
->execute();
|
->execute();
|
||||||
foreach ($plans as $plan) {
|
$plans = mpull($plans, null, 'getPHID');
|
||||||
|
|
||||||
|
foreach ($requests as $request) {
|
||||||
|
$plan_phid = $request->getBuildPlanPHID();
|
||||||
|
$plan = idx($plans, $plan_phid);
|
||||||
|
|
||||||
|
if (!$plan) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Failed to load build plan ("%s").',
|
||||||
|
$plan_phid));
|
||||||
|
}
|
||||||
|
|
||||||
if ($plan->isDisabled()) {
|
if ($plan->isDisabled()) {
|
||||||
// TODO: This should be communicated more clearly -- maybe we should
|
// TODO: This should be communicated more clearly -- maybe we should
|
||||||
// create the build but set the status to "disabled" or "derelict".
|
// create the build but set the status to "disabled" or "derelict".
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$buildable->applyPlan($plan);
|
$parameters = $request->getBuildParameters();
|
||||||
|
$buildable->applyPlan($plan, $parameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyPlan(HarbormasterBuildPlan $plan) {
|
public function applyPlan(HarbormasterBuildPlan $plan, array $parameters) {
|
||||||
|
|
||||||
$viewer = PhabricatorUser::getOmnipotentUser();
|
$viewer = PhabricatorUser::getOmnipotentUser();
|
||||||
$build = HarbormasterBuild::initializeNewBuild($viewer)
|
$build = HarbormasterBuild::initializeNewBuild($viewer)
|
||||||
->setBuildablePHID($this->getPHID())
|
->setBuildablePHID($this->getPHID())
|
||||||
->setBuildPlanPHID($plan->getPHID())
|
->setBuildPlanPHID($plan->getPHID())
|
||||||
|
->setBuildParameters($parameters)
|
||||||
->setBuildStatus(HarbormasterBuild::STATUS_PENDING);
|
->setBuildStatus(HarbormasterBuild::STATUS_PENDING);
|
||||||
|
|
||||||
$auto_key = $plan->getPlanAutoKey();
|
$auto_key = $plan->getPlanAutoKey();
|
||||||
|
|
|
@ -9,6 +9,7 @@ final class HarbormasterBuild extends HarbormasterDAO
|
||||||
protected $buildPlanPHID;
|
protected $buildPlanPHID;
|
||||||
protected $buildStatus;
|
protected $buildStatus;
|
||||||
protected $buildGeneration;
|
protected $buildGeneration;
|
||||||
|
protected $buildParameters = array();
|
||||||
protected $planAutoKey;
|
protected $planAutoKey;
|
||||||
|
|
||||||
private $buildable = self::ATTACHABLE;
|
private $buildable = self::ATTACHABLE;
|
||||||
|
@ -156,6 +157,9 @@ final class HarbormasterBuild extends HarbormasterDAO
|
||||||
protected function getConfiguration() {
|
protected function getConfiguration() {
|
||||||
return array(
|
return array(
|
||||||
self::CONFIG_AUX_PHID => true,
|
self::CONFIG_AUX_PHID => true,
|
||||||
|
self::CONFIG_SERIALIZATION => array(
|
||||||
|
'buildParameters' => self::SERIALIZATION_JSON,
|
||||||
|
),
|
||||||
self::CONFIG_COLUMN_SCHEMA => array(
|
self::CONFIG_COLUMN_SCHEMA => array(
|
||||||
'buildStatus' => 'text32',
|
'buildStatus' => 'text32',
|
||||||
'buildGeneration' => 'uint32',
|
'buildGeneration' => 'uint32',
|
||||||
|
@ -258,6 +262,10 @@ final class HarbormasterBuild extends HarbormasterDAO
|
||||||
'build.id' => null,
|
'build.id' => null,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
foreach ($this->getBuildParameters() as $key => $value) {
|
||||||
|
$results['build/'.$key] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
$buildable = $this->getBuildable();
|
$buildable = $this->getBuildable();
|
||||||
$object = $buildable->getBuildableObject();
|
$object = $buildable->getBuildableObject();
|
||||||
|
|
||||||
|
|
|
@ -2837,7 +2837,7 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
HarbormasterBuildable::applyBuildPlans(
|
HarbormasterBuildable::applyBuildPlans(
|
||||||
$adapter->getHarbormasterBuildablePHID(),
|
$adapter->getHarbormasterBuildablePHID(),
|
||||||
$adapter->getHarbormasterContainerPHID(),
|
$adapter->getHarbormasterContainerPHID(),
|
||||||
$adapter->getQueuedHarbormasterBuildPlanPHIDs());
|
$adapter->getQueuedHarbormasterBuildRequests());
|
||||||
}
|
}
|
||||||
|
|
||||||
return array_merge(
|
return array_merge(
|
||||||
|
|
Loading…
Reference in a new issue