2019-05-30 14:16:13 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
final class HarbormasterTeamCityBuildStepImplementation
|
|
|
|
extends HarbormasterBuildStepImplementation {
|
|
|
|
|
|
|
|
public function getName() {
|
|
|
|
return pht('Build with TeamCity');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getGenericDescription() {
|
|
|
|
return pht('Trigger TeamCity Builds with Harbormaster');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getBuildStepGroupKey() {
|
|
|
|
return HarbormasterExternalBuildStepGroup::GROUPKEY;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getDescription() {
|
|
|
|
$domain = null;
|
|
|
|
$uri = $this->getSetting('uri');
|
|
|
|
if ($uri) {
|
|
|
|
$domain = id(new PhutilURI($uri))->getDomain();
|
|
|
|
}
|
|
|
|
|
|
|
|
$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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function execute(
|
|
|
|
HarbormasterBuild $build,
|
|
|
|
HarbormasterBuildTarget $build_target) {
|
|
|
|
|
|
|
|
$viewer = PhabricatorUser::getOmnipotentUser();
|
|
|
|
|
|
|
|
// Settings includes the custom fields set in getFieldSpecifications()
|
|
|
|
$settings = $this->getSettings();
|
|
|
|
$variables = $build_target->getVariables();
|
|
|
|
|
|
|
|
// Combined TeamCity URI
|
|
|
|
$uri = $settings['uri'] . '/app/rest/buildQueue';
|
|
|
|
|
|
|
|
$method = 'POST';
|
|
|
|
$contentType = 'application/xml';
|
|
|
|
|
|
|
|
// Using TeamCityXmlBuildBuilder create the payload to send to
|
|
|
|
// TeamCity server
|
|
|
|
$xmlBuilder = new TeamCityXmlBuildBuilder();
|
|
|
|
$payload = $xmlBuilder
|
|
|
|
->addBuildId($settings['buildId'])
|
2019-06-05 12:22:53 +02:00
|
|
|
->addRevisionBuild(implode(array("D", $variables['buildable.revision'], "-", $variables['buildable.diff'])))
|
2019-05-30 14:16:13 +02:00
|
|
|
->addPhabBuildId($variables['build.id'])
|
|
|
|
->addDiffId($variables['buildable.diff'])
|
|
|
|
->addHarbormasterPHID($variables['target.phid'])
|
|
|
|
->addRevisionId(implode(array("D", $variables['buildable.revision'])))
|
|
|
|
->build();
|
|
|
|
|
|
|
|
$future = id(new HTTPSFuture($uri, $payload))
|
|
|
|
->setMethod($method)
|
|
|
|
->addHeader('Content-Type', $contentType)
|
|
|
|
->addHeader('Origin', $settings['uri'])
|
|
|
|
->setTimeout(60);
|
|
|
|
|
|
|
|
// Add credentials to HTTP request if they have been set
|
|
|
|
$credential_phid = $this->getSetting('credential');
|
|
|
|
if ($credential_phid) {
|
|
|
|
$key = PassphraseTokenKey::loadFromPHID(
|
|
|
|
$credential_phid,
|
|
|
|
$viewer);
|
|
|
|
$future->addHeader(
|
|
|
|
'Authorization',
|
|
|
|
implode(array("Bearer ", $key->getPasswordEnvelope()->openEnvelope()))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->resolveFutures(
|
|
|
|
$build,
|
|
|
|
$build_target,
|
|
|
|
array($future));
|
|
|
|
|
|
|
|
list($status, $body, $headers) = $future->resolve();
|
|
|
|
|
|
|
|
$header_lines = array();
|
|
|
|
|
|
|
|
// TODO: We don't currently preserve the entire "HTTP" response header, but
|
|
|
|
// should. Once we do, reproduce it here faithfully.
|
|
|
|
$status_code = $status->getStatusCode();
|
|
|
|
$header_lines[] = "HTTP {$status_code}";
|
|
|
|
|
|
|
|
foreach ($headers as $header) {
|
|
|
|
list($head, $tail) = $header;
|
|
|
|
$header_lines[] = "{$head}: {$tail}";
|
|
|
|
}
|
|
|
|
$header_lines = implode("\n", $header_lines);
|
|
|
|
|
|
|
|
$build_target
|
|
|
|
->newLog($uri, 'http.head')
|
|
|
|
->append($header_lines);
|
|
|
|
|
|
|
|
$build_target
|
|
|
|
->newLog($uri, 'http.body')
|
|
|
|
->append($body);
|
|
|
|
|
|
|
|
if ($status->isError()) {
|
|
|
|
throw new HarbormasterBuildFailureException();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getFieldSpecifications() {
|
|
|
|
return array(
|
|
|
|
'uri' => array(
|
|
|
|
'name' => pht('URI'),
|
|
|
|
'type' => 'text',
|
|
|
|
'required' => true,
|
|
|
|
),
|
|
|
|
'buildId' => array(
|
|
|
|
'name' => pht('TeamCity Build Configuration ID'),
|
|
|
|
'type' => 'text',
|
|
|
|
'required' => true,
|
|
|
|
),
|
|
|
|
'credential' => array(
|
|
|
|
'name' => pht('TeamCity Credentials'),
|
|
|
|
'type' => 'credential',
|
|
|
|
'required' => true,
|
|
|
|
'credential.type'
|
|
|
|
=> PassphraseTokenCredentialType::CREDENTIAL_TYPE,
|
|
|
|
'credential.provides'
|
|
|
|
=> PassphraseTokenCredentialType::PROVIDES_TYPE,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function supportsWaitForMessage() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|