2013-11-09 16:16:12 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
final class HarbormasterHTTPRequestBuildStepImplementation
|
2014-03-26 00:09:21 +01:00
|
|
|
extends HarbormasterBuildStepImplementation {
|
2013-11-09 16:16:12 +01:00
|
|
|
|
|
|
|
public function getName() {
|
|
|
|
return pht('Make HTTP Request');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getGenericDescription() {
|
|
|
|
return pht('Make an HTTP request.');
|
|
|
|
}
|
|
|
|
|
2015-08-06 13:19:42 +02:00
|
|
|
public function getBuildStepGroupKey() {
|
|
|
|
return HarbormasterExternalBuildStepGroup::GROUPKEY;
|
|
|
|
}
|
|
|
|
|
2013-11-09 16:16:12 +01:00
|
|
|
public function getDescription() {
|
2014-03-26 00:10:50 +01:00
|
|
|
$domain = null;
|
|
|
|
$uri = $this->getSetting('uri');
|
|
|
|
if ($uri) {
|
|
|
|
$domain = id(new PhutilURI($uri))->getDomain();
|
|
|
|
}
|
2013-11-09 16:16:12 +01:00
|
|
|
|
2014-04-16 22:01:38 +02:00
|
|
|
$method = $this->formatSettingForDescription('method', 'POST');
|
|
|
|
$domain = $this->formatValueForDescription($domain);
|
|
|
|
|
|
|
|
if ($this->getSetting('credential')) {
|
|
|
|
return pht(
|
|
|
|
'Make an authenticated HTTP %s request to %s.',
|
|
|
|
$method,
|
|
|
|
$domain);
|
|
|
|
} else {
|
|
|
|
return pht(
|
|
|
|
'Make an HTTP %s request to %s.',
|
|
|
|
$method,
|
|
|
|
$domain);
|
|
|
|
}
|
2013-11-09 16:16:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function execute(
|
|
|
|
HarbormasterBuild $build,
|
2013-12-05 02:01:12 +01:00
|
|
|
HarbormasterBuildTarget $build_target) {
|
2013-11-09 16:16:12 +01:00
|
|
|
|
2014-04-16 22:01:38 +02:00
|
|
|
$viewer = PhabricatorUser::getOmnipotentUser();
|
2013-11-09 16:16:12 +01:00
|
|
|
$settings = $this->getSettings();
|
2013-12-05 02:01:12 +01:00
|
|
|
$variables = $build_target->getVariables();
|
2013-11-09 16:16:12 +01:00
|
|
|
|
|
|
|
$uri = $this->mergeVariables(
|
|
|
|
'vurisprintf',
|
|
|
|
$settings['uri'],
|
|
|
|
$variables);
|
|
|
|
|
2014-03-26 00:08:40 +01:00
|
|
|
$method = nonempty(idx($settings, 'method'), 'POST');
|
Added 'method' field to the HTTP request build step.
Summary:
This revision adds a 'method' field to the HTTP request harbormaster build step. This allows the user to specify GET, POST, DELETE, and PUT (limited by the underlying wrapper phabricator uses for HTTP requests). I'm not sure how much sense PUT makes, but oh well.
Existing plans shouldn't break, as if this field is an empty string, we default to POST, which is the old behavior.
Fixes T4604
Test Plan: 1) Verified that the empty string does, in fact, issue a POST request. Changed the method to be GET and observed that the problem described in T4604 is resolved.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: aran, epriestley
Maniphest Tasks: T4604
Differential Revision: https://secure.phabricator.com/D8520
2014-03-13 23:49:42 +01:00
|
|
|
|
2014-04-16 22:01:38 +02:00
|
|
|
$future = id(new HTTPSFuture($uri))
|
Added 'method' field to the HTTP request build step.
Summary:
This revision adds a 'method' field to the HTTP request harbormaster build step. This allows the user to specify GET, POST, DELETE, and PUT (limited by the underlying wrapper phabricator uses for HTTP requests). I'm not sure how much sense PUT makes, but oh well.
Existing plans shouldn't break, as if this field is an empty string, we default to POST, which is the old behavior.
Fixes T4604
Test Plan: 1) Verified that the empty string does, in fact, issue a POST request. Changed the method to be GET and observed that the problem described in T4604 is resolved.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: aran, epriestley
Maniphest Tasks: T4604
Differential Revision: https://secure.phabricator.com/D8520
2014-03-13 23:49:42 +01:00
|
|
|
->setMethod($method)
|
2014-04-16 22:01:38 +02:00
|
|
|
->setTimeout(60);
|
|
|
|
|
|
|
|
$credential_phid = $this->getSetting('credential');
|
|
|
|
if ($credential_phid) {
|
|
|
|
$key = PassphrasePasswordKey::loadFromPHID(
|
|
|
|
$credential_phid,
|
|
|
|
$viewer);
|
|
|
|
$future->setHTTPBasicAuthCredentials(
|
|
|
|
$key->getUsernameEnvelope()->openEnvelope(),
|
|
|
|
$key->getPasswordEnvelope());
|
|
|
|
}
|
|
|
|
|
2015-09-25 19:43:32 +02:00
|
|
|
$this->resolveFutures(
|
2014-08-26 12:46:23 +02:00
|
|
|
$build,
|
|
|
|
$build_target,
|
2015-09-25 19:43:32 +02:00
|
|
|
array($future));
|
|
|
|
|
2015-10-15 05:01:22 +02:00
|
|
|
$this->logHTTPResponse($build, $build_target, $future, $uri);
|
2013-11-09 16:16:12 +01:00
|
|
|
|
2015-10-15 05:01:22 +02:00
|
|
|
list($status) = $future->resolve();
|
2015-10-02 18:17:51 +02:00
|
|
|
if ($status->isError()) {
|
2015-09-25 19:43:32 +02:00
|
|
|
throw new HarbormasterBuildFailureException();
|
2013-11-09 16:16:12 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-26 00:08:40 +01:00
|
|
|
public function getFieldSpecifications() {
|
2013-11-09 16:16:12 +01:00
|
|
|
return array(
|
|
|
|
'uri' => array(
|
2014-03-26 00:08:40 +01:00
|
|
|
'name' => pht('URI'),
|
|
|
|
'type' => 'text',
|
|
|
|
'required' => true,
|
2013-11-09 16:16:12 +01:00
|
|
|
),
|
Added 'method' field to the HTTP request build step.
Summary:
This revision adds a 'method' field to the HTTP request harbormaster build step. This allows the user to specify GET, POST, DELETE, and PUT (limited by the underlying wrapper phabricator uses for HTTP requests). I'm not sure how much sense PUT makes, but oh well.
Existing plans shouldn't break, as if this field is an empty string, we default to POST, which is the old behavior.
Fixes T4604
Test Plan: 1) Verified that the empty string does, in fact, issue a POST request. Changed the method to be GET and observed that the problem described in T4604 is resolved.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: aran, epriestley
Maniphest Tasks: T4604
Differential Revision: https://secure.phabricator.com/D8520
2014-03-13 23:49:42 +01:00
|
|
|
'method' => array(
|
2014-03-26 00:08:40 +01:00
|
|
|
'name' => pht('HTTP Method'),
|
|
|
|
'type' => 'select',
|
|
|
|
'options' => array_fuse(array('POST', 'GET', 'PUT', 'DELETE')),
|
Added 'method' field to the HTTP request build step.
Summary:
This revision adds a 'method' field to the HTTP request harbormaster build step. This allows the user to specify GET, POST, DELETE, and PUT (limited by the underlying wrapper phabricator uses for HTTP requests). I'm not sure how much sense PUT makes, but oh well.
Existing plans shouldn't break, as if this field is an empty string, we default to POST, which is the old behavior.
Fixes T4604
Test Plan: 1) Verified that the empty string does, in fact, issue a POST request. Changed the method to be GET and observed that the problem described in T4604 is resolved.
Reviewers: #blessed_reviewers, epriestley
Reviewed By: #blessed_reviewers, epriestley
Subscribers: aran, epriestley
Maniphest Tasks: T4604
Differential Revision: https://secure.phabricator.com/D8520
2014-03-13 23:49:42 +01:00
|
|
|
),
|
2014-04-16 22:01:38 +02:00
|
|
|
'credential' => array(
|
|
|
|
'name' => pht('Credentials'),
|
|
|
|
'type' => 'credential',
|
|
|
|
'credential.type'
|
2015-06-14 06:11:55 +02:00
|
|
|
=> PassphrasePasswordCredentialType::CREDENTIAL_TYPE,
|
2014-04-16 22:01:38 +02:00
|
|
|
'credential.provides'
|
2015-06-14 06:11:55 +02:00
|
|
|
=> PassphrasePasswordCredentialType::PROVIDES_TYPE,
|
2014-04-16 22:01:38 +02:00
|
|
|
),
|
2013-11-09 16:16:12 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
Allow Harbormaster build targets to wait for messages
Summary:
This hooks up all the pieces of the build pipeline so `harbormaster.sendmessage` actually works. Particularly:
- Candidate build steps (i.e., those which interact with external systems) can now "Wait for Message". This pauses them indefinitely when they complete, until something calls `harbormaster.sendmessage`.
- After processing a target, we check if we should move it to PASSED or WAITING.
- Before updating a build, we move WAITING targets with pending messages to either PASSED or FAILED.
- I added an explicit "Building" state, which doesn't affect workflows but communicates more information to human users.
A big part of this is avoiding races. I believe we get the correct behavior no matter which order events occur in:
- We update builds after targets complete and after we receive messages, so we're guaranteed to update once both these conditions are true. This means messages can't be lost (even if they arrive before a build completes).
- The minor changes to the build engine logic mean that firing additional build updates is always safe, no matter what the current state of the build is.
- The build itself is protected by a lock in the build engine.
- The target is not covered by an explicit lock, but for all states only the engine (waiting) //or// the worker (all other states) can interact with it. All of the interactions also move the target state forward to the same destination and have no other side effects.
- Messages are only consumed inside the engine lock, so they don't need an explicit lock.
Test Plan:
- Made an HTTP request wait after completion, then ran a pile of builds through it using `bin/harbormaster build` and the web UI.
- Passed and failed message-awaiting builds with `harbormaster.sendmessage`.
Reviewers: btrahan
Reviewed By: btrahan
Subscribers: epriestley, zeeg
Differential Revision: https://secure.phabricator.com/D8788
2014-04-16 22:01:46 +02:00
|
|
|
public function supportsWaitForMessage() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-11-09 16:16:12 +01:00
|
|
|
}
|