switched from aws to github releases

This commit is contained in:
igorklopov 2016-08-11 12:45:23 +03:00
parent 75a65aa39f
commit 4c3a6df890
5 changed files with 88 additions and 31 deletions

View File

@ -16,7 +16,7 @@ async function main () {
await build({ copyDest: local, nodeVersion, target });
console.error(`> ${chalk.yellow('Uploading')} ${local}`);
const remote = remotePlace({ arch: target, nodeVersion, platform, version });
await upload(local, remote);
await upload(local, remote, version);
}
}
}

69
lib/github.js Normal file
View File

@ -0,0 +1,69 @@
import assert from 'assert';
import fs from 'fs';
import request from 'request';
const OWNER = 'zeit';
const REPO = 'pkg-cache';
const { GITHUB_USERNAME, GTHUB_PASSWORD } = process.env;
const request2 = request.defaults({
auth: { user: GITHUB_USERNAME, pass: GTHUB_PASSWORD },
headers: { 'User-Agent': `${OWNER}/${REPO}/${GITHUB_USERNAME}` }
});
export function getRelease (tag) {
return new Promise((resolve, reject) => {
const url = `https://api.github.com/repos/${OWNER}/${REPO}/releases`;
request2(url, (error, response, body) => {
if (error) return reject(error);
// we cannot use `get release by tag` endpoint here
// because draft releases are really `untagged`.
// seems that `get release by tag` is for non-drafts.
// hence listing all releases and looking through them
const releases = JSON.parse(body);
const found = releases.filter(({ tag_name }) => tag_name === tag); // eslint-disable-line camelcase
if (found.length > 1) {
return reject(new Error(`More than one ${tag} release found. Fix it!`));
}
if (!found.length) return resolve(null);
resolve(found[0]);
});
});
}
export function createRelease (tag) {
return new Promise((resolve, reject) => {
const form = JSON.stringify({
tag_name: tag,
target_commitish: 'master', // TODO maybe git rev-parse HEAD
name: tag,
draft: true,
prerelease: true
});
const url = `https://api.github.com/repos/${OWNER}/${REPO}/releases`;
request2.post(url, { form }, (error, response, body) => {
if (error) return reject(error);
resolve(JSON.parse(body));
});
});
}
export function uploadAsset (local, release, name) {
assert(!(/[\\/]/.test(name)));
return new Promise((resolve, reject) => {
fs.stat(local, (error, stat) => {
if (error) return reject(error);
const headers = {
'Content-Length': stat.size,
'Content-Type': 'application/octet-stream'
};
const rs = fs.createReadStream(local);
const subst = `?name=${name}`;
const url = release.upload_url.replace(/\{\?name,label\}/, subst);
const req = request2.post(url, { headers }, (error2, response, body) => {
if (error2) return reject(error2);
resolve(JSON.parse(body));
});
rs.pipe(req);
});
});
}

View File

@ -1,33 +1,21 @@
import aws from 'aws-sdk';
import fs from 'fs';
import url from 'url';
import { createRelease, getRelease, uploadAsset } from './github.js';
function remoteToAwsOpts (remote) {
const { host, pathname } = url.parse(remote);
if (!(/.amazonaws.com$/.test(host))) {
throw new Error('Currently only AWS is supported');
function uniqueName (remote, names) {
if (names.indexOf(remote) < 0) return remote;
let name;
let counter = 0;
while (true) {
name = `${remote}-${counter}`;
if (names.indexOf(name) < 0) return name;
counter += 1;
}
const bucket = host.split('.')[0];
return { bucket, key: pathname };
}
export default function upload (local, remote) {
return new Promise((resolve, reject) => {
// aws credentials are taken from:
// AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
const s3 = new aws.S3();
const { bucket, key } = remoteToAwsOpts(remote);
const rs = fs.createReadStream(local);
s3.upload({
Bucket: bucket,
Key: key,
ACL: 'public-read',
StorageClass: 'REDUCED_REDUNDANCY',
ContentType: 'binary/octet-stream',
Body: rs
}, (error) => {
if (error) return reject(error);
resolve();
});
});
export default async function upload (local, remote, version) {
const tag = `v${version}`;
let release = await getRelease(tag);
if (!release) release = await createRelease(tag);
const names = release.assets.map(({ name }) => name);
const name = uniqueName(remote, names);
await uploadAsset(local, release, name);
}

View File

@ -45,11 +45,11 @@
}
},
"dependencies": {
"aws-sdk": "2.4.14",
"chalk": "1.1.3",
"child-process-promise": "2.0.3",
"expand-template": "1.0.2",
"mkdirp-promise": "2.0.0",
"request": "2.74.0",
"rimraf-promise": "2.0.0"
},
"devDependencies": {

View File

@ -1,4 +1,4 @@
{
"localPlace": "~/.pkg-cache/{version}/{nodeVersion}-{platform}-{arch}",
"remotePlace": "https://enclosejs.s3.amazonaws.com/pkg-cache/{version}/{nodeVersion}-{platform}-{arch}"
"remotePlace": "{nodeVersion}-{platform}-{arch}"
}