145 lines
3.9 KiB
JavaScript
145 lines
3.9 KiB
JavaScript
const core = require('@actions/core');
|
|
const path = require("path");
|
|
const fs = require("fs");
|
|
const github = require('@actions/github');
|
|
const glob = require('glob');
|
|
|
|
function sleep(milliseconds) {
|
|
return new Promise(resolve => setTimeout(resolve, milliseconds));
|
|
}
|
|
|
|
async function runOnce() {
|
|
// Load all our inputs and env vars. Note that `getInput` reads from `INPUT_*`
|
|
const files = core.getInput('files');
|
|
const name = core.getInput('name');
|
|
const token = core.getInput('token');
|
|
const slug = process.env.GITHUB_REPOSITORY;
|
|
const owner = slug.split('/')[0];
|
|
const repo = slug.split('/')[1];
|
|
const sha = process.env.HEAD_SHA;
|
|
|
|
core.info(`files: ${files}`);
|
|
core.info(`name: ${name}`);
|
|
|
|
const options = {
|
|
request: {
|
|
timeout: 30000,
|
|
}
|
|
};
|
|
const octokit = github.getOctokit(token, options);
|
|
|
|
// Delete the previous release since we can't overwrite one. This may happen
|
|
// due to retrying an upload or it may happen because we're doing the dev
|
|
// release.
|
|
const releases = await octokit.paginate("GET /repos/:owner/:repo/releases", { owner, repo });
|
|
for (const release of releases) {
|
|
if (release.tag_name !== name) {
|
|
continue;
|
|
}
|
|
const release_id = release.id;
|
|
core.info(`deleting release ${release_id}`);
|
|
await octokit.rest.repos.deleteRelease({ owner, repo, release_id });
|
|
}
|
|
|
|
// We also need to update the `dev` tag while we're at it on the `dev` branch.
|
|
if (name == 'nightly') {
|
|
try {
|
|
core.info(`updating nightly tag`);
|
|
await octokit.rest.git.updateRef({
|
|
owner,
|
|
repo,
|
|
ref: 'tags/nightly',
|
|
sha,
|
|
force: true,
|
|
});
|
|
} catch (e) {
|
|
core.error(e);
|
|
core.info(`creating nightly tag`);
|
|
await octokit.rest.git.createTag({
|
|
owner,
|
|
repo,
|
|
tag: 'nightly',
|
|
message: 'nightly release',
|
|
object: sha,
|
|
type: 'commit',
|
|
});
|
|
}
|
|
}
|
|
|
|
// Creates an official GitHub release for this `tag`, and if this is `dev`
|
|
// then we know that from the previous block this should be a fresh release.
|
|
core.info(`creating a release`);
|
|
const release = await octokit.rest.repos.createRelease({
|
|
owner,
|
|
repo,
|
|
name,
|
|
tag_name: name,
|
|
target_commitish: sha,
|
|
prerelease: name === 'nightly',
|
|
});
|
|
const release_id = release.data.id;
|
|
|
|
// Upload all the relevant assets for this release as just general blobs.
|
|
for (const file of glob.sync(files)) {
|
|
const size = fs.statSync(file).size;
|
|
const name = path.basename(file);
|
|
|
|
await runWithRetry(async function () {
|
|
// We can't overwrite assets, so remove existing ones from a previous try.
|
|
let assets = await octokit.rest.repos.listReleaseAssets({
|
|
owner,
|
|
repo,
|
|
release_id
|
|
});
|
|
for (const asset of assets.data) {
|
|
if (asset.name === name) {
|
|
core.info(`delete asset ${name}`);
|
|
const asset_id = asset.id;
|
|
await octokit.rest.repos.deleteReleaseAsset({ owner, repo, asset_id });
|
|
}
|
|
}
|
|
|
|
core.info(`upload ${file}`);
|
|
const headers = { 'content-length': size, 'content-type': 'application/octet-stream' };
|
|
const data = fs.createReadStream(file);
|
|
await octokit.rest.repos.uploadReleaseAsset({
|
|
data,
|
|
headers,
|
|
name,
|
|
url: release.data.upload_url,
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
async function runWithRetry(f) {
|
|
const retries = 10;
|
|
const maxDelay = 4000;
|
|
let delay = 1000;
|
|
|
|
for (let i = 0; i < retries; i++) {
|
|
try {
|
|
await f();
|
|
break;
|
|
} catch (e) {
|
|
if (i === retries - 1)
|
|
throw e;
|
|
|
|
core.error(e);
|
|
const currentDelay = Math.round(Math.random() * delay);
|
|
core.info(`sleeping ${currentDelay} ms`);
|
|
await sleep(currentDelay);
|
|
delay = Math.min(delay * 2, maxDelay);
|
|
}
|
|
}
|
|
}
|
|
|
|
async function run() {
|
|
await runWithRetry(runOnce);
|
|
}
|
|
|
|
run().catch(err => {
|
|
core.error(err);
|
|
core.setFailed(err.message);
|
|
});
|