1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-04-11 20:08:35 +02:00

Add a "Make an HTTP Request" build step

Summary:
Ref T1049. This is very minimal, but does what it says.

I merged the variable replacement code so Remote + HTTP can share more stuff.

Test Plan:
Ran "HTTP" and "Remote" build plans.

{F79886}

{F79887}

Reviewers: hach-que, btrahan

Reviewed By: hach-que

CC: zeeg, aran

Maniphest Tasks: T1049

Differential Revision: https://secure.phabricator.com/D7541
This commit is contained in:
epriestley 2013-11-09 07:16:12 -08:00
parent 43847d6bd7
commit 56c65e33ef
7 changed files with 114 additions and 29 deletions

View file

@ -682,6 +682,7 @@ phutil_register_library_map(array(
'HarbormasterCapabilityManagePlans' => 'applications/harbormaster/capability/HarbormasterCapabilityManagePlans.php',
'HarbormasterController' => 'applications/harbormaster/controller/HarbormasterController.php',
'HarbormasterDAO' => 'applications/harbormaster/storage/HarbormasterDAO.php',
'HarbormasterHTTPRequestBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterHTTPRequestBuildStepImplementation.php',
'HarbormasterObject' => 'applications/harbormaster/storage/HarbormasterObject.php',
'HarbormasterPHIDTypeBuild' => 'applications/harbormaster/phid/HarbormasterPHIDTypeBuild.php',
'HarbormasterPHIDTypeBuildItem' => 'applications/harbormaster/phid/HarbormasterPHIDTypeBuildItem.php',
@ -2979,6 +2980,7 @@ phutil_register_library_map(array(
'HarbormasterCapabilityManagePlans' => 'PhabricatorPolicyCapability',
'HarbormasterController' => 'PhabricatorController',
'HarbormasterDAO' => 'PhabricatorLiskDAO',
'HarbormasterHTTPRequestBuildStepImplementation' => 'VariableBuildStepImplementation',
'HarbormasterObject' => 'HarbormasterDAO',
'HarbormasterPHIDTypeBuild' => 'PhabricatorPHIDType',
'HarbormasterPHIDTypeBuildItem' => 'PhabricatorPHIDType',

View file

@ -26,7 +26,7 @@ final class HarbormasterBuildCancelController
$build_uri = $this->getApplicationURI('/build/'.$build->getID());
if ($request->isDialogFormPost()) {
$build->setCancelRequested(true);
$build->setCancelRequested(1);
$build->save();
return id(new AphrontRedirectResponse())->setURI($build_uri);

View file

@ -0,0 +1,70 @@
<?php
final class HarbormasterHTTPRequestBuildStepImplementation
extends VariableBuildStepImplementation {
public function getName() {
return pht('Make HTTP Request');
}
public function getGenericDescription() {
return pht('Make an HTTP request.');
}
public function getDescription() {
$settings = $this->getSettings();
$uri = new PhutilURI($settings['uri']);
$domain = $uri->getDomain();
return pht('Make an HTTP request to %s', $domain);
}
public function execute(
HarbormasterBuild $build,
HarbormasterBuildStep $build_step) {
$settings = $this->getSettings();
$variables = $this->retrieveVariablesFromBuild($build);
$uri = $this->mergeVariables(
'vurisprintf',
$settings['uri'],
$variables);
$log_body = $build->createLog($build_step, $uri, 'http-body');
$start = $log_body->start();
list($status, $body, $headers) = id(new HTTPSFuture($uri))
->setMethod('POST')
->setTimeout(60)
->resolve();
$log_body->append($body);
$log_body->finalize($start);
if ($status->getStatusCode() != 200) {
$build->setBuildStatus(HarbormasterBuild::STATUS_FAILED);
}
}
public function validateSettings() {
$settings = $this->getSettings();
if ($settings['uri'] === null || !is_string($settings['uri'])) {
return false;
}
return true;
}
public function getSettingDefinitions() {
return array(
'uri' => array(
'name' => 'URI',
'description' => pht('The URI to request.'),
'type' => BuildStepImplementation::SETTING_TYPE_STRING,
),
);
}
}

View file

@ -25,24 +25,12 @@ final class RemoteCommandBuildStepImplementation
HarbormasterBuildStep $build_step) {
$settings = $this->getSettings();
$parameters = array();
$matches = array();
$variables = $this->retrieveVariablesFromBuild($build);
$command = $settings['command'];
preg_match_all(
"/\\\$\\{(?P<name>[a-z\.]+)\\}/",
$command,
$matches);
foreach ($matches["name"] as $match) {
$parameters[] = idx($variables, $match, "");
}
$command = str_replace("%", "%%", $command);
$command = preg_replace("/\\\$\\{(?P<name>[a-z\.]+)\\}/", "%s", $command);
$command = vcsprintf(
$command,
$parameters);
$command = $this->mergeVariables(
'vcsprintf',
$settings['command'],
$variables);
$future = null;
if (empty($settings['sshkey'])) {

View file

@ -33,17 +33,42 @@ abstract class VariableBuildStepImplementation extends BuildStepImplementation {
return $results;
}
public function mergeVariables(HarbormasterBuild $build, $string) {
$variables = $this->retrieveVariablesFromBuild($build);
foreach ($variables as $name => $value) {
if ($value === null) {
$value = '';
/**
* Convert a user-provided string with variables in it, like:
*
* ls ${dirname}
*
* ...into a string with variables merged into it safely:
*
* ls 'dir with spaces'
*
* @param string Name of a `vxsprintf` function, like @{function:vcsprintf}.
* @param string User-provided pattern string containing `${variables}`.
* @param dict List of available replacement variables.
* @return string String with variables replaced safely into it.
*/
protected function mergeVariables($function, $pattern, array $variables) {
$regexp = '/\\$\\{(?P<name>[a-z\\.]+)\\}/';
$matches = null;
preg_match_all($regexp, $pattern, $matches);
$argv = array();
foreach ($matches['name'] as $name) {
if (!array_key_exists($name, $variables)) {
throw new Exception(pht("No such variable '%s'!", $name));
}
$string = str_replace('${'.$name.'}', $value, $string);
$argv[] = $variables[$name];
}
return $string;
$pattern = str_replace('%', '%%', $pattern);
$pattern = preg_replace($regexp, '%s', $pattern);
return call_user_func($function, $pattern, $argv);
}
public function getAvailableVariables() {
return array(
'buildable.revision' =>

View file

@ -54,7 +54,7 @@ final class HarbormasterBuild extends HarbormasterDAO
public static function initializeNewBuild(PhabricatorUser $actor) {
return id(new HarbormasterBuild())
->setBuildStatus(self::STATUS_INACTIVE)
->setCancelRequested(false);
->setCancelRequested(0);
}
public function getConfiguration() {
@ -118,7 +118,7 @@ final class HarbormasterBuild extends HarbormasterDAO
$copy = id(new HarbormasterBuild())->load($this->getID());
if ($copy->getCancelRequested()) {
$this->setBuildStatus(HarbormasterBuild::STATUS_CANCELLED);
$this->setCancelRequested(false);
$this->setCancelRequested(0);
$this->save();
return true;
}

View file

@ -28,7 +28,7 @@ final class HarbormasterBuildLog extends HarbormasterDAO
->setBuildPHID($build->getPHID())
->setBuildStepPHID($build_step->getPHID())
->setDuration(null)
->setLive(false);
->setLive(0);
}
public function getConfiguration() {
@ -70,7 +70,7 @@ final class HarbormasterBuildLog extends HarbormasterDAO
throw new Exception("Live logging has already started for this log.");
}
$this->setLive(true);
$this->setLive(1);
$this->save();
return time();
@ -150,7 +150,7 @@ final class HarbormasterBuildLog extends HarbormasterDAO
if ($start > 0) {
$this->setDuration(time() - $start);
}
$this->setLive(false);
$this->setLive(0);
$this->save();
}