Skip to content

Commit 0043e1b

Browse files
committed
Initial commit
0 parents  commit 0043e1b

32 files changed

+8356
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM node:slim
2+
3+
COPY . /action
4+
WORKDIR /action
5+
6+
RUN npm install --production
7+
8+
ENTRYPOINT ["node", "/action/main.js"]
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# github-release
2+
3+
An action used to publish GitHub releases for `wasmtime`.
4+
5+
As of the time of this writing there's a few actions floating around which
6+
perform github releases but they all tend to have their set of drawbacks.
7+
Additionally nothing handles deleting releases which we need for our rolling
8+
`dev` release.
9+
10+
To handle all this this action rolls-its-own implementation using the
11+
actions/toolkit repository and packages published there. These run in a Docker
12+
container and take various inputs to orchestrate the release from the build.
13+
14+
More comments can be found in `main.js`.
15+
16+
Testing this is really hard. If you want to try though run `npm install` and
17+
then `node main.js`. You'll have to configure a bunch of env vars though to get
18+
anything reasonably working.
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: 'js-compute-runtime github releases'
2+
description: 'js-compute-runtime github releases'
3+
inputs:
4+
token:
5+
description: ''
6+
required: true
7+
name:
8+
description: ''
9+
required: true
10+
files:
11+
description: ''
12+
required: true
13+
runs:
14+
using: 'docker'
15+
image: 'Dockerfile'
+117
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
const core = require('@actions/core');
2+
const path = require("path");
3+
const fs = require("fs");
4+
const github = require('@actions/github');
5+
const glob = require('glob');
6+
7+
function sleep(milliseconds) {
8+
return new Promise(resolve => setTimeout(resolve, milliseconds))
9+
}
10+
11+
async function runOnce() {
12+
// Load all our inputs and env vars. Note that `getInput` reads from `INPUT_*`
13+
const files = core.getInput('files');
14+
const name = core.getInput('name');
15+
const token = core.getInput('token');
16+
const slug = process.env.GITHUB_REPOSITORY;
17+
const owner = slug.split('/')[0];
18+
const repo = slug.split('/')[1];
19+
const sha = process.env.GITHUB_SHA;
20+
21+
core.info(`files: ${files}`);
22+
core.info(`name: ${name}`);
23+
core.info(`token: ${token}`);
24+
25+
const octokit = new github.GitHub(token);
26+
27+
// Delete the previous release since we can't overwrite one. This may happen
28+
// due to retrying an upload or it may happen because we're doing the dev
29+
// release.
30+
const releases = await octokit.paginate("GET /repos/:owner/:repo/releases", { owner, repo });
31+
for (const release of releases) {
32+
if (release.tag_name !== name) {
33+
continue;
34+
}
35+
const release_id = release.id;
36+
core.info(`deleting release ${release_id}`);
37+
await octokit.repos.deleteRelease({ owner, repo, release_id });
38+
}
39+
40+
// We also need to update the `dev` tag while we're at it on the `dev` branch.
41+
if (name == 'dev') {
42+
try {
43+
core.info(`updating dev tag`);
44+
await octokit.git.updateRef({
45+
owner,
46+
repo,
47+
ref: 'tags/dev',
48+
sha,
49+
force: true,
50+
});
51+
} catch (e) {
52+
console.log("ERROR: ", JSON.stringify(e, null, 2));
53+
core.info(`creating dev tag`);
54+
await octokit.git.createTag({
55+
owner,
56+
repo,
57+
tag: 'dev',
58+
message: 'dev release',
59+
object: sha,
60+
type: 'commit',
61+
});
62+
}
63+
}
64+
65+
// Creates an official GitHub release for this `tag`, and if this is `dev`
66+
// then we know that from the previous block this should be a fresh release.
67+
core.info(`creating a release`);
68+
const release = await octokit.repos.createRelease({
69+
owner,
70+
repo,
71+
tag_name: name,
72+
prerelease: name === 'dev',
73+
});
74+
75+
// Upload all the relevant assets for this release as just general blobs.
76+
for (const file of glob.sync(files)) {
77+
const size = fs.statSync(file).size;
78+
core.info(`upload ${file}`);
79+
await octokit.repos.uploadReleaseAsset({
80+
data: fs.createReadStream(file),
81+
headers: { 'content-length': size, 'content-type': 'application/octet-stream' },
82+
name: path.basename(file),
83+
url: release.data.upload_url,
84+
});
85+
}
86+
}
87+
88+
async function run() {
89+
const retries = 10;
90+
for (let i = 0; i < retries; i++) {
91+
try {
92+
await runOnce();
93+
break;
94+
} catch (e) {
95+
if (i === retries - 1)
96+
throw e;
97+
logError(e);
98+
console.log("RETRYING after 10s");
99+
await sleep(10000)
100+
}
101+
}
102+
}
103+
104+
function logError(e) {
105+
console.log("ERROR: ", e.message);
106+
try {
107+
console.log(JSON.stringify(e, null, 2));
108+
} catch (e) {
109+
// ignore json errors for now
110+
}
111+
console.log(e.stack);
112+
}
113+
114+
run().catch(err => {
115+
logError(err);
116+
core.setFailed(err.message);
117+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"name": "wasmtime-github-release",
3+
"version": "0.0.0",
4+
"main": "main.js",
5+
"dependencies": {
6+
"@actions/core": "^1.0.0",
7+
"@actions/github": "^1.0.0",
8+
"glob": "^7.1.5"
9+
}
10+
}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# install-rust
2+
3+
A small github action to install `rustup` and a Rust toolchain. This is
4+
generally expressed inline, but it was repeated enough in this repository it
5+
seemed worthwhile to extract.
6+
7+
Some gotchas:
8+
9+
* Can't `--self-update` on Windows due to permission errors (a bug in Github
10+
Actions)
11+
* `rustup` isn't installed on macOS (a bug in Github Actions)
12+
13+
When the above are fixed we should delete this action and just use this inline:
14+
15+
```yml
16+
- run: rustup update $toolchain && rustup default $toolchain
17+
shell: bash
18+
```
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: 'Install Rust toolchain'
2+
description: 'Install both `rustup` and a Rust toolchain'
3+
4+
inputs:
5+
toolchain:
6+
description: 'Default toolchan to install'
7+
required: false
8+
default: 'stable'
9+
10+
runs:
11+
using: node12
12+
main: 'main.js'

.github/actions/install-rust/main.js

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const child_process = require('child_process');
2+
const toolchain = process.env.INPUT_TOOLCHAIN;
3+
const fs = require('fs');
4+
5+
function set_env(name, val) {
6+
fs.appendFileSync(process.env['GITHUB_ENV'], `${name}=${val}\n`)
7+
}
8+
9+
if (process.platform === 'darwin') {
10+
child_process.execSync(`curl https://sh.rustup.rs | sh -s -- -y --default-toolchain=none --profile=minimal`);
11+
const bindir = `${process.env.HOME}/.cargo/bin`;
12+
fs.appendFileSync(process.env['GITHUB_PATH'], `${bindir}\n`);
13+
process.env.PATH = `${process.env.PATH}:${bindir}`;
14+
}
15+
16+
child_process.execFileSync('rustup', ['set', 'profile', 'minimal']);
17+
child_process.execFileSync('rustup', ['update', toolchain, '--no-self-update']);
18+
child_process.execFileSync('rustup', ['default', toolchain]);
19+
20+
// Deny warnings on CI to keep our code warning-free as it lands in-tree. Don't
21+
// do this on nightly though since there's a fair amount of warning churn there.
22+
if (!toolchain.startsWith('nightly')) {
23+
set_env("RUSTFLAGS", "-D warnings");
24+
}
25+
26+
// Save disk space by avoiding incremental compilation, and also we don't use
27+
// any caching so incremental wouldn't help anyway.
28+
set_env("CARGO_INCREMENTAL", "0");
29+
30+
// Turn down debuginfo from 2 to 1 to help save disk space
31+
set_env("CARGO_PROFILE_DEV_DEBUG", "1");
32+
set_env("CARGO_PROFILE_TEST_DEBUG", "1");

0 commit comments

Comments
 (0)