diff options
author | 2023-01-27 19:13:56 -0800 | |
---|---|---|
committer | 2023-01-27 19:14:14 -0800 | |
commit | 34b643e654c8f87456924b2e63492c63006d1ae4 (patch) | |
tree | a23b6cc3ea12a04bc29f294e796fe09663468b0c | |
parent | 2e1c7f5597e516133feaa5af2dc25c4794d8e113 (diff) | |
download | bun-34b643e654c8f87456924b2e63492c63006d1ae4.tar.gz bun-34b643e654c8f87456924b2e63492c63006d1ae4.tar.zst bun-34b643e654c8f87456924b2e63492c63006d1ae4.zip |
Enable release signing
-rw-r--r-- | .github/workflows/bun-linux-build.yml | 51 | ||||
-rw-r--r-- | .github/workflows/bun-mac-aarch64.yml | 39 | ||||
-rw-r--r-- | .github/workflows/bun-mac-x64-baseline.yml | 39 | ||||
-rw-r--r-- | .github/workflows/bun-mac-x64.yml | 39 | ||||
-rw-r--r-- | .scripts/sign-release.ts | 93 |
5 files changed, 251 insertions, 10 deletions
diff --git a/.github/workflows/bun-linux-build.yml b/.github/workflows/bun-linux-build.yml index 9908b5fa1..48d0be581 100644 --- a/.github/workflows/bun-linux-build.yml +++ b/.github/workflows/bun-linux-build.yml @@ -128,10 +128,20 @@ jobs: with: name: bun-${{matrix.tag}} path: ${{runner.temp}}/release/bun-${{matrix.tag}}.zip + - uses: actions/upload-artifact@v3 + with: + name: bun-obj-${{matrix.tag}} + path: ${{runner.temp}}/release/bun-obj + - uses: actions/upload-artifact@v3 + with: + name: ${{matrix.tag}}-dependencies + path: ${{runner.temp}}/release/bun-dependencies - name: Release id: release uses: ncipollo/release-action@v1 - if: github.ref == 'refs/heads/main' + if: | + github.repository_owner == 'oven-sh' + && github.ref == 'refs/heads/main' with: prerelease: true body: "This canary release of Bun corresponds to the commit [${{ github.sha }}]" @@ -143,11 +153,38 @@ jobs: name: "Canary (${{github.sha}})" tag: "canary" artifacts: "${{runner.temp}}/release/bun-${{matrix.tag}}.zip,${{runner.temp}}/release/bun-${{matrix.tag}}-profile.zip" - - uses: actions/upload-artifact@v3 + - id: setup-bun + name: Setup Bun + uses: oven-sh/setup-bun@v0.1.8 + if: | + github.repository_owner == 'oven-sh' + && github.ref == 'refs/heads/main' with: - name: bun-obj-${{matrix.tag}} - path: ${{runner.temp}}/release/bun-obj - - uses: actions/upload-artifact@v3 + bun-version: canary + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Sign Release + id: sign-release + if: | + github.repository_owner == 'oven-sh' + && github.ref == 'refs/heads/main' + env: + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + run: | + echo "$GPG_PASSPHRASE" | bun run .scripts/sign-release.ts + - name: Release Checksum + id: release-checksum + uses: ncipollo/release-action@v1 + if: | + github.repository_owner == 'oven-sh' + && github.ref == 'refs/heads/main' with: - name: ${{matrix.tag}}-dependencies - path: ${{runner.temp}}/release/bun-dependencies + prerelease: true + body: "This canary release of Bun corresponds to the commit [${{ github.sha }}]" + allowUpdates: true + replacesArtifacts: true + generateReleaseNotes: true + artifactErrorsFailBuild: true + token: ${{ secrets.GITHUB_TOKEN }} + name: "Canary (${{github.sha}})" + tag: "canary" + artifacts: "SHASUMS256.txt,SHASUMS256.txt.asc" diff --git a/.github/workflows/bun-mac-aarch64.yml b/.github/workflows/bun-mac-aarch64.yml index 268994020..cf51c1c82 100644 --- a/.github/workflows/bun-mac-aarch64.yml +++ b/.github/workflows/bun-mac-aarch64.yml @@ -370,7 +370,9 @@ jobs: - name: Release id: release uses: ncipollo/release-action@v1 - if: github.ref == 'refs/heads/main' + if: | + github.repository_owner == 'oven-sh' + && github.ref == 'refs/heads/main' with: prerelease: true body: "This canary release of Bun corresponds to the commit [${{ github.sha }}]" @@ -382,3 +384,38 @@ jobs: name: "Canary (${{github.sha}})" tag: "canary" artifacts: "${{runner.temp}}/release/${{matrix.tag}}.zip,${{runner.temp}}/release/${{matrix.tag}}-profile.zip" + - id: setup-bun + name: Setup Bun + uses: oven-sh/setup-bun@v0.1.8 + if: | + github.repository_owner == 'oven-sh' + && github.ref == 'refs/heads/main' + with: + bun-version: canary + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Sign Release + id: sign-release + if: | + github.repository_owner == 'oven-sh' + && github.ref == 'refs/heads/main' + env: + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + run: | + echo "$GPG_PASSPHRASE" | bun run .scripts/sign-release.ts + - name: Release Checksum + id: release-checksum + uses: ncipollo/release-action@v1 + if: | + github.repository_owner == 'oven-sh' + && github.ref == 'refs/heads/main' + with: + prerelease: true + body: "This canary release of Bun corresponds to the commit [${{ github.sha }}]" + allowUpdates: true + replacesArtifacts: true + generateReleaseNotes: true + artifactErrorsFailBuild: true + token: ${{ secrets.GITHUB_TOKEN }} + name: "Canary (${{github.sha}})" + tag: "canary" + artifacts: "SHASUMS256.txt,SHASUMS256.txt.asc" diff --git a/.github/workflows/bun-mac-x64-baseline.yml b/.github/workflows/bun-mac-x64-baseline.yml index 7066d428d..5e92719cf 100644 --- a/.github/workflows/bun-mac-x64-baseline.yml +++ b/.github/workflows/bun-mac-x64-baseline.yml @@ -374,7 +374,9 @@ jobs: - name: Release id: release uses: ncipollo/release-action@v1 - if: github.ref == 'refs/heads/main' + if: | + github.repository_owner == 'oven-sh' + && github.ref == 'refs/heads/main' with: prerelease: true body: "This canary release of Bun corresponds to the commit [${{ github.sha }}]" @@ -386,3 +388,38 @@ jobs: name: "Canary (${{github.sha}})" tag: "canary" artifacts: "${{runner.temp}}/release/${{matrix.tag}}.zip,${{runner.temp}}/release/${{matrix.tag}}-profile.zip" + - id: setup-bun + name: Setup Bun + uses: oven-sh/setup-bun@v0.1.8 + if: | + github.repository_owner == 'oven-sh' + && github.ref == 'refs/heads/main' + with: + bun-version: canary + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Sign Release + id: sign-release + if: | + github.repository_owner == 'oven-sh' + && github.ref == 'refs/heads/main' + env: + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + run: | + echo "$GPG_PASSPHRASE" | bun run .scripts/sign-release.ts + - name: Release Checksum + id: release-checksum + uses: ncipollo/release-action@v1 + if: | + github.repository_owner == 'oven-sh' + && github.ref == 'refs/heads/main' + with: + prerelease: true + body: "This canary release of Bun corresponds to the commit [${{ github.sha }}]" + allowUpdates: true + replacesArtifacts: true + generateReleaseNotes: true + artifactErrorsFailBuild: true + token: ${{ secrets.GITHUB_TOKEN }} + name: "Canary (${{github.sha}})" + tag: "canary" + artifacts: "SHASUMS256.txt,SHASUMS256.txt.asc" diff --git a/.github/workflows/bun-mac-x64.yml b/.github/workflows/bun-mac-x64.yml index aa4b79295..c5ee5c048 100644 --- a/.github/workflows/bun-mac-x64.yml +++ b/.github/workflows/bun-mac-x64.yml @@ -376,7 +376,9 @@ jobs: - name: Release id: release uses: ncipollo/release-action@v1 - if: github.ref == 'refs/heads/main' + if: | + github.repository_owner == 'oven-sh' + && github.ref == 'refs/heads/main' with: prerelease: true body: "This canary release of Bun corresponds to the commit [${{ github.sha }}]" @@ -388,3 +390,38 @@ jobs: name: "Canary (${{github.sha}})" tag: "canary" artifacts: "${{runner.temp}}/release/${{matrix.tag}}.zip,${{runner.temp}}/release/${{matrix.tag}}-profile.zip" + - id: setup-bun + name: Setup Bun + uses: oven-sh/setup-bun@v0.1.8 + if: | + github.repository_owner == 'oven-sh' + && github.ref == 'refs/heads/main' + with: + bun-version: canary + github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Sign Release + id: sign-release + if: | + github.repository_owner == 'oven-sh' + && github.ref == 'refs/heads/main' + env: + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + run: | + echo "$GPG_PASSPHRASE" | bun run .scripts/sign-release.ts + - name: Release Checksum + id: release-checksum + uses: ncipollo/release-action@v1 + if: | + github.repository_owner == 'oven-sh' + && github.ref == 'refs/heads/main' + with: + prerelease: true + body: "This canary release of Bun corresponds to the commit [${{ github.sha }}]" + allowUpdates: true + replacesArtifacts: true + generateReleaseNotes: true + artifactErrorsFailBuild: true + token: ${{ secrets.GITHUB_TOKEN }} + name: "Canary (${{github.sha}})" + tag: "canary" + artifacts: "SHASUMS256.txt,SHASUMS256.txt.asc" diff --git a/.scripts/sign-release.ts b/.scripts/sign-release.ts new file mode 100644 index 000000000..9ff189659 --- /dev/null +++ b/.scripts/sign-release.ts @@ -0,0 +1,93 @@ +/// <reference types="bun-types" /> +import { SHA256, which, write, spawnSync } from "bun"; +import { isatty } from "node:tty"; +import { createInterface } from "node:readline"; + +const tag = process.argv[2]; +const url = tag + ? `https://api.github.com/repos/oven-sh/bun/releases/tags/${tag}` + : "https://api.github.com/repos/oven-sh/bun/releases/latest"; +const response = await fetch(url); +if (response.status === 404) { + throw new Error(`Release not found: ${tag}`); +} +if (!response.ok) { + throw new Error(`Failed to find release: ${tag} [status: ${response.status}]`); +} +const release: any = await response.json(); +if (release.assets.find(({ name }) => name === "SHA256SUMS.txt.asc")) { + throw new Error(`Release already signed: ${tag}`); +} +const sha256s = await Promise.all( + release.assets.map(async ({ name, browser_download_url }) => { + return `${await sha256(browser_download_url)} ${name}`; + }), +); +await write("SHASUMS256.txt", sha256s.join("\n")); +await sign("SHASUMS256.txt"); + +async function sha256(url: string): Promise<string> { + const response = await fetch(url); + if (!response.ok) { + throw new Error(`Failed to find asset: ${url} [status: ${response.status}]`); + } + const body = await response.arrayBuffer(); + const sha256 = SHA256.hash(body); + return Buffer.from(sha256).toString("hex"); +} + +async function sign(path: string): Promise<void> { + // https://www.gnupg.org/gph/en/manual/x135.html + if (!which("gpg")) { + throw new Error("Command not found: gpg"); + } + const { stdout } = spawnSync( + [ + "gpg", + "--list-secret-keys", + "--keyid-format", + "long" + ], + { + stdout: "pipe", + stderr: "pipe", + } + ); + if (!stdout.includes("F3DCC08A8572C0749B3E18888EAB4D40A7B22B59")) { + console.warn("Signature is likely wrong, key not found: robobun@oven.sh"); + } + const passphrase = await prompt("Passphrase:"); + spawnSync( + [ + "gpg", + "--batch", + "--yes", + "--clearsign", + "--output", + `${path}.asc`, + path + ], + { + stdin: new TextEncoder().encode(passphrase), + stdout: "inherit", + stderr: "inherit", + } + ); +} + +async function prompt(question: string): Promise<string> { + if (isatty(process.stdout.fd)) { + return globalThis.prompt(question) || ""; + } + const reader = createInterface({ + input: process.stdin, + terminal: false + }); + let buffer = ""; + reader.on("line", (line) => { + buffer += line; + }); + return new Promise((resolve) => { + reader.once("close", () => resolve(buffer)); + }); +} |