Skip to content

Commit

Permalink
Automating github API releases for v2
Browse files Browse the repository at this point in the history
  • Loading branch information
mtdowling committed Oct 22, 2014
1 parent 10c82c7 commit 9d5d947
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 123 deletions.
12 changes: 6 additions & 6 deletions Makefile
Expand Up @@ -57,12 +57,12 @@ tag: check_tag
# "make release" to push a release. This task requires that the
# OAUTH_TOKEN environment variable is available and the token has permission
# to push to the repository.
release: package
@echo "Pushing code to master"
release: check_tag package
git push origin master
@echo "Pushing latest tag to Github"
git push origin `git describe --abbrev=0 --tags`
echo "Creating a Github release"
php build/gh-release.php
git push origin $(TAG)
php build/gh-release.php $(TAG)

# Tags the repo and publishes a release.
full_release: tag release

.PHONY: docs burgomaster
172 changes: 55 additions & 117 deletions build/gh-release.php
@@ -1,126 +1,64 @@
<?php
/*
* This script creates a new Github release via the releases API using
* the staging directory, artifacts built via the package.php script,
* an OAUTH_TOKEN provided as an environment variable.
* Creates a Github API release using the changelog contents. Attaches aws.zip
* and aws.phar to the release.
*
* The contents of the release notes are parsed from the CHANGELOG.md file
* using the latest version found in the CHANGELOG.
*/
require __DIR__ . '/../vendor/autoload.php';

/**
* Github release helper class.
* The OAUTH_TOKEN environment variable is required.
*
* Usage: php gh-release.php X.Y.Z
*/
class Release
{
private $token;
private $owner;
private $repo;
private $client;

public function __construct($token, $owner, $repo)
{
$this->token = $token;
$this->owner = $owner;
$this->repo = $repo;
$this->client = new \Guzzle\Http\Client();
$this->client->setUserAgent('aws-sdk-php');
$this->client->setDefaultOption(
'headers/Authorization',
'token ' . $token
);
}

/**
* Executes a command and returns the output as a string. If it fails it throws.
*/
public static function exec($command)
{
exec($command, $output, $returnValue);
$output = implode("\n", $output);

if ($returnValue != 0) {
die("Error executing command: {$command}\n$output");
}

return $output;
}

public function createRelease(
$tag,
$contents,
$branch = 'master',
$draft = false
) {
$request = $this->client->createRequest(
'POST',
"https://api.github.com/repos/$this->owner/$this->repo/releases",
array('Content-Type' => 'application/json'),
json_encode(array(
'tag_name' => $tag,
'target_commitish' => $branch,
'name' => $tag . ' release',
'body' => $contents,
'draft' => $draft
))
);

return $this->client->send($request)->json();
}

public function uploadAsset($id, $name, $contents, $contentType)
{
$request = $this->client->createRequest(
'POST',
sprintf(
"https://api.github.com/repos/%s/%s/releases/%s/assets?name=%s",
$this->owner, $this->repo, $id, $name
),
array('Content-Type' => $contentType),
$contents
);
require __DIR__ . '/../vendor/autoload.php';

return $this->client->send($request)->json();
}
}
use Guzzle\Http\Client;
use Guzzle\Http\Url;
use Guzzle\Stream;

$owner = 'aws';
$repo = 'aws-sdk-php';
$returnVal = shell_exec('which chag') or die('chag not found in path');
$token = getenv('OAUTH_TOKEN') or die('OAUTH_TOKEN environment var not found!');
$artifacts = realpath(__DIR__ . '/artifacts') or die('artifacts dir not found');
$stageDir = realpath($artifacts . '/staging') or die('stage dir not found');
$zip = realpath($artifacts . '/aws.zip') or die('zip not found');
$phar = realpath($artifacts . '/aws.phar') or die('phar not found');

// Get the latest changelog entry
chdir($stageDir);
$tag = Release::exec('chag get');
$contents = Release::exec('chag contents');
echo "Found tag: {$tag}\n\n{$contents}\n\n";

$release = new Release($token, $owner, $repo);
$res = $release->createRelease($tag, $contents, 'master', true);
echo "Created release: {$res['id']}\n";

// Upload the phar
$upload = $release->uploadAsset(
$res['id'],
'aws.phar',
file_get_contents($phar),
'application/octet-stream'
);

echo "Uploaded asset: {$upload['browser_download_url']}\n";

// Upload the zip
$upload = $release->uploadAsset(
$res['id'],
'aws.zip',
file_get_contents($zip),
'application/zip'
);

echo "Uploaded asset: {$upload['browser_download_url']}\n\n";
echo "Successfully create GitHub release\n";
$token = getenv('OAUTH_TOKEN') or die('An OAUTH_TOKEN environment variable is required');
isset($argv[1]) or die('Usage php gh-release.php X.Y.Z');
$tag = $argv[1];

assert(file_exists(__DIR__ . '/artifacts/aws.zip'));
assert(file_exists(__DIR__ . '/artifacts/aws.phar'));

// Grab and validate the tag annotation
chdir("..");
$message = `chag contents -t "$tag"` or die('Chag could not find or parse the tag');

// Create a GitHub client.
$client = new Client('https://api.github.com/');
$client->setDefaultOption('headers/Authorization', "token $token");

// Create the release
$response = $client->post(
"repos/${owner}/${repo}/releases",
array('Content-Type' => 'application/json'),
json_encode(array(
'tag_name' => $tag,
'name' => "Version {$tag}",
'body' => $message,
'prerelease' => false
))
)->send();

// Grab the location of the new release
$url = (string) $response->getHeader('Location');
// Uploads go to uploads.github.com
$uploadUrl = Url::factory($url);
$uploadUrl->setHost('uploads.github.com');

$client->post(
$uploadUrl . '/assets?name=aws.zip',
array('Content-Type' => 'application/zip'),
fopen(__DIR__ . '/artifacts/aws.zip', 'r')
)->send();

$client->post(
$uploadUrl . '/assets?name=aws.phar',
array('Content-Type' => 'application/phar'),
fopen(__DIR__ . '/artifacts/aws.phar', 'r')
)->send();

echo "Release successfully published to: $url\n";

0 comments on commit 9d5d947

Please sign in to comment.