@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+114 -29
+2
src/__phutil_library_map__.php
··· 682 682 'HarbormasterCapabilityManagePlans' => 'applications/harbormaster/capability/HarbormasterCapabilityManagePlans.php', 683 683 'HarbormasterController' => 'applications/harbormaster/controller/HarbormasterController.php', 684 684 'HarbormasterDAO' => 'applications/harbormaster/storage/HarbormasterDAO.php', 685 + 'HarbormasterHTTPRequestBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterHTTPRequestBuildStepImplementation.php', 685 686 'HarbormasterObject' => 'applications/harbormaster/storage/HarbormasterObject.php', 686 687 'HarbormasterPHIDTypeBuild' => 'applications/harbormaster/phid/HarbormasterPHIDTypeBuild.php', 687 688 'HarbormasterPHIDTypeBuildItem' => 'applications/harbormaster/phid/HarbormasterPHIDTypeBuildItem.php', ··· 2979 2980 'HarbormasterCapabilityManagePlans' => 'PhabricatorPolicyCapability', 2980 2981 'HarbormasterController' => 'PhabricatorController', 2981 2982 'HarbormasterDAO' => 'PhabricatorLiskDAO', 2983 + 'HarbormasterHTTPRequestBuildStepImplementation' => 'VariableBuildStepImplementation', 2982 2984 'HarbormasterObject' => 'HarbormasterDAO', 2983 2985 'HarbormasterPHIDTypeBuild' => 'PhabricatorPHIDType', 2984 2986 'HarbormasterPHIDTypeBuildItem' => 'PhabricatorPHIDType',
+1 -1
src/applications/harbormaster/controller/HarbormasterBuildCancelController.php
··· 26 26 $build_uri = $this->getApplicationURI('/build/'.$build->getID()); 27 27 28 28 if ($request->isDialogFormPost()) { 29 - $build->setCancelRequested(true); 29 + $build->setCancelRequested(1); 30 30 $build->save(); 31 31 32 32 return id(new AphrontRedirectResponse())->setURI($build_uri);
+70
src/applications/harbormaster/step/HarbormasterHTTPRequestBuildStepImplementation.php
··· 1 + <?php 2 + 3 + final class HarbormasterHTTPRequestBuildStepImplementation 4 + extends VariableBuildStepImplementation { 5 + 6 + public function getName() { 7 + return pht('Make HTTP Request'); 8 + } 9 + 10 + public function getGenericDescription() { 11 + return pht('Make an HTTP request.'); 12 + } 13 + 14 + public function getDescription() { 15 + $settings = $this->getSettings(); 16 + 17 + $uri = new PhutilURI($settings['uri']); 18 + $domain = $uri->getDomain(); 19 + return pht('Make an HTTP request to %s', $domain); 20 + } 21 + 22 + public function execute( 23 + HarbormasterBuild $build, 24 + HarbormasterBuildStep $build_step) { 25 + 26 + $settings = $this->getSettings(); 27 + $variables = $this->retrieveVariablesFromBuild($build); 28 + 29 + $uri = $this->mergeVariables( 30 + 'vurisprintf', 31 + $settings['uri'], 32 + $variables); 33 + 34 + $log_body = $build->createLog($build_step, $uri, 'http-body'); 35 + $start = $log_body->start(); 36 + 37 + list($status, $body, $headers) = id(new HTTPSFuture($uri)) 38 + ->setMethod('POST') 39 + ->setTimeout(60) 40 + ->resolve(); 41 + 42 + $log_body->append($body); 43 + $log_body->finalize($start); 44 + 45 + if ($status->getStatusCode() != 200) { 46 + $build->setBuildStatus(HarbormasterBuild::STATUS_FAILED); 47 + } 48 + } 49 + 50 + public function validateSettings() { 51 + $settings = $this->getSettings(); 52 + 53 + if ($settings['uri'] === null || !is_string($settings['uri'])) { 54 + return false; 55 + } 56 + 57 + return true; 58 + } 59 + 60 + public function getSettingDefinitions() { 61 + return array( 62 + 'uri' => array( 63 + 'name' => 'URI', 64 + 'description' => pht('The URI to request.'), 65 + 'type' => BuildStepImplementation::SETTING_TYPE_STRING, 66 + ), 67 + ); 68 + } 69 + 70 + }
+4 -16
src/applications/harbormaster/step/RemoteCommandBuildStepImplementation.php
··· 25 25 HarbormasterBuildStep $build_step) { 26 26 27 27 $settings = $this->getSettings(); 28 - 29 - $parameters = array(); 30 - $matches = array(); 31 28 $variables = $this->retrieveVariablesFromBuild($build); 32 - $command = $settings['command']; 33 - preg_match_all( 34 - "/\\\$\\{(?P<name>[a-z\.]+)\\}/", 35 - $command, 36 - $matches); 37 - foreach ($matches["name"] as $match) { 38 - $parameters[] = idx($variables, $match, ""); 39 - } 40 - $command = str_replace("%", "%%", $command); 41 - $command = preg_replace("/\\\$\\{(?P<name>[a-z\.]+)\\}/", "%s", $command); 42 29 43 - $command = vcsprintf( 44 - $command, 45 - $parameters); 30 + $command = $this->mergeVariables( 31 + 'vcsprintf', 32 + $settings['command'], 33 + $variables); 46 34 47 35 $future = null; 48 36 if (empty($settings['sshkey'])) {
+32 -7
src/applications/harbormaster/step/VariableBuildStepImplementation.php
··· 33 33 return $results; 34 34 } 35 35 36 - public function mergeVariables(HarbormasterBuild $build, $string) { 37 - $variables = $this->retrieveVariablesFromBuild($build); 38 - foreach ($variables as $name => $value) { 39 - if ($value === null) { 40 - $value = ''; 36 + 37 + /** 38 + * Convert a user-provided string with variables in it, like: 39 + * 40 + * ls ${dirname} 41 + * 42 + * ...into a string with variables merged into it safely: 43 + * 44 + * ls 'dir with spaces' 45 + * 46 + * @param string Name of a `vxsprintf` function, like @{function:vcsprintf}. 47 + * @param string User-provided pattern string containing `${variables}`. 48 + * @param dict List of available replacement variables. 49 + * @return string String with variables replaced safely into it. 50 + */ 51 + protected function mergeVariables($function, $pattern, array $variables) { 52 + $regexp = '/\\$\\{(?P<name>[a-z\\.]+)\\}/'; 53 + 54 + $matches = null; 55 + preg_match_all($regexp, $pattern, $matches); 56 + 57 + $argv = array(); 58 + foreach ($matches['name'] as $name) { 59 + if (!array_key_exists($name, $variables)) { 60 + throw new Exception(pht("No such variable '%s'!", $name)); 41 61 } 42 - $string = str_replace('${'.$name.'}', $value, $string); 62 + $argv[] = $variables[$name]; 43 63 } 44 - return $string; 64 + 65 + $pattern = str_replace('%', '%%', $pattern); 66 + $pattern = preg_replace($regexp, '%s', $pattern); 67 + 68 + return call_user_func($function, $pattern, $argv); 45 69 } 70 + 46 71 47 72 public function getAvailableVariables() { 48 73 return array(
+2 -2
src/applications/harbormaster/storage/build/HarbormasterBuild.php
··· 54 54 public static function initializeNewBuild(PhabricatorUser $actor) { 55 55 return id(new HarbormasterBuild()) 56 56 ->setBuildStatus(self::STATUS_INACTIVE) 57 - ->setCancelRequested(false); 57 + ->setCancelRequested(0); 58 58 } 59 59 60 60 public function getConfiguration() { ··· 118 118 $copy = id(new HarbormasterBuild())->load($this->getID()); 119 119 if ($copy->getCancelRequested()) { 120 120 $this->setBuildStatus(HarbormasterBuild::STATUS_CANCELLED); 121 - $this->setCancelRequested(false); 121 + $this->setCancelRequested(0); 122 122 $this->save(); 123 123 return true; 124 124 }
+3 -3
src/applications/harbormaster/storage/build/HarbormasterBuildLog.php
··· 28 28 ->setBuildPHID($build->getPHID()) 29 29 ->setBuildStepPHID($build_step->getPHID()) 30 30 ->setDuration(null) 31 - ->setLive(false); 31 + ->setLive(0); 32 32 } 33 33 34 34 public function getConfiguration() { ··· 70 70 throw new Exception("Live logging has already started for this log."); 71 71 } 72 72 73 - $this->setLive(true); 73 + $this->setLive(1); 74 74 $this->save(); 75 75 76 76 return time(); ··· 150 150 if ($start > 0) { 151 151 $this->setDuration(time() - $start); 152 152 } 153 - $this->setLive(false); 153 + $this->setLive(0); 154 154 $this->save(); 155 155 } 156 156