diff --git a/.github/actions/github-release/main.js b/.github/actions/github-release/main.js index a08e59a91a..c8145f63c2 100644 --- a/.github/actions/github-release/main.js +++ b/.github/actions/github-release/main.js @@ -5,7 +5,7 @@ const github = require('@actions/github'); const glob = require('glob'); function sleep(milliseconds) { - return new Promise(resolve => setTimeout(resolve, milliseconds)) + return new Promise(resolve => setTimeout(resolve, milliseconds)); } async function runOnce() { @@ -20,9 +20,8 @@ async function runOnce() { core.info(`files: ${files}`); core.info(`name: ${name}`); - core.info(`token: ${token}`); - const octokit = new github.GitHub(token); + const octokit = github.getOctokit(token); // 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 @@ -34,24 +33,24 @@ async function runOnce() { } const release_id = release.id; core.info(`deleting release ${release_id}`); - await octokit.repos.deleteRelease({ owner, repo, 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.git.updateRef({ - owner, - repo, - ref: 'tags/nightly', - sha, - force: true, + await octokit.rest.git.updateRef({ + owner, + repo, + ref: 'tags/nightly', + sha, + force: true, }); } catch (e) { - console.log("ERROR: ", JSON.stringify(e, null, 2)); + core.error(e); core.info(`creating nightly tag`); - await octokit.git.createTag({ + await octokit.rest.git.createTag({ owner, repo, tag: 'nightly', @@ -65,7 +64,7 @@ async function runOnce() { // 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.repos.createRelease({ + const release = await octokit.rest.repos.createRelease({ owner, repo, name, @@ -73,47 +72,68 @@ async function runOnce() { 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; - core.info(`upload ${file}`); - await octokit.repos.uploadReleaseAsset({ - data: fs.createReadStream(file), - headers: { 'content-length': size, 'content-type': 'application/octet-stream' }, - name: path.basename(file), - url: release.data.upload_url, + 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 run() { +async function runWithRetry(f) { const retries = 10; + const maxDelay = 4000; + let delay = 1000; + for (let i = 0; i < retries; i++) { try { - await runOnce(); + await f(); break; } catch (e) { if (i === retries - 1) throw e; - logError(e); - console.log("RETRYING after 10s"); - await sleep(10000) + + core.error(e); + const currentDelay = Math.round(Math.random() * delay); + core.info(`sleeping ${currentDelay} ms`); + await sleep(currentDelay); + delay = Math.min(delay * 2, maxDelay); } } } -function logError(e) { - console.log("ERROR: ", e.message); - try { - console.log(JSON.stringify(e, null, 2)); - } catch (e) { - // ignore json errors for now - } - console.log(e.stack); +async function run() { + await runWithRetry(runOnce); } run().catch(err => { - logError(err); + core.error(err); core.setFailed(err.message); }); diff --git a/.github/actions/github-release/package.json b/.github/actions/github-release/package.json index abfc55f6ff..af4bf074d2 100644 --- a/.github/actions/github-release/package.json +++ b/.github/actions/github-release/package.json @@ -3,8 +3,8 @@ "version": "0.0.0", "main": "main.js", "dependencies": { - "@actions/core": "^1.0.0", - "@actions/github": "^1.0.0", + "@actions/core": "^1.6", + "@actions/github": "^5.0", "glob": "^7.1.5" } } diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 2693e08cd4..563778ed68 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -162,12 +162,12 @@ jobs: - run: npm ci working-directory: editors/code - - name: Publish Extension (release) + - name: Package Extension (release) if: github.ref == 'refs/heads/release' run: npx vsce package -o "../../dist/rust-analyzer-alpine-x64.vsix" --target alpine-x64 working-directory: editors/code - - name: Publish Extension (nightly) + - name: Package Extension (nightly) if: github.ref != 'refs/heads/release' run: npx vsce package -o "../../dist/rust-analyzer-alpine-x64.vsix" --target alpine-x64 --pre-release working-directory: editors/code