Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ If you need to override the download URL, you can use the `bun-download-url` inp
| `bun-version` | The version of Bun to download and install. | Version from `package.json`, or `latest` | `canary`, `1.0.0`, `1.0.x` |
| `bun-version-file` | The version of Bun to download and install from file. | `undefined` | `package.json`, `.bun-version`, `.tool-versions` |
| `bun-download-url` | URL to download .zip file for Bun release | | |
| `checksum` | Expected SHA256 checksum of the downloaded Bun archive. | | |
| `registry-url` | Registry URL where some private package is stored. | `undefined` | `"https://npm.pkg.github.com/"` |
| `scope` | Scope for private packages. | `undefined` | `"@foo"`, `"@orgname"` |
| `no-cache` | Disable caching of the downloaded executable. | `false` | `true`, `false` |
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ inputs:
bun-download-url:
description: Override the URL to download Bun from. This skips version resolution and verifying AVX2 support.
required: false
checksum:
description: Expected SHA256 checksum of the downloaded Bun archive.
required: false
registries:
description: |
List of package registries with authentication support. Format:
Expand Down
10 changes: 5 additions & 5 deletions dist/cache-save/index.js

Large diffs are not rendered by default.

146 changes: 73 additions & 73 deletions dist/setup/index.js

Large diffs are not rendered by default.

12 changes: 10 additions & 2 deletions src/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ import { getExecOutput } from "@actions/exec";
import { Registry } from "./registry";
import { writeBunfig } from "./bunfig";
import { saveState } from "@actions/core";
import { addExtension, extractVersionFromUrl, getCacheKey } from "./utils";
import {
addExtension,
extractVersionFromUrl,
getCacheKey,
verifyChecksum,
} from "./utils";
import { getDownloadUrl } from "./download-url";
import { cwd } from "node:process";

Expand All @@ -29,6 +34,7 @@ export type Input = {
registries?: Registry[];
noCache?: boolean;
token?: string;
checksum?: string;
};

export type Output = {
Expand Down Expand Up @@ -121,7 +127,7 @@ export default async (options: Input): Promise<Output> => {

if (!cacheHit) {
info(`Downloading a new version of Bun: ${url}`);
revision = await downloadBun(url, bunPath);
revision = await downloadBun(url, bunPath, options.checksum);
}
}

Expand Down Expand Up @@ -177,9 +183,11 @@ function isVersionMatch(
async function downloadBun(
url: string,
bunPath: string,
checksum?: string,
): Promise<string | undefined> {
// Workaround for https://github.com/oven-sh/setup-bun/issues/79 and https://github.com/actions/toolkit/issues/1179
const zipPath = addExtension(await downloadTool(url), ".zip");
verifyChecksum(zipPath, checksum);
const extractedZipPath = await extractZip(zipPath);
const extractedBunPath = await extractBun(extractedZipPath);
try {
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ runAction({
registries: registries,
noCache: getBooleanInput("no-cache") || false,
token: getInput("token"),
checksum: getInput("checksum") || undefined,
})
.then(({ version, revision, bunPath, url, cacheHit }) => {
setOutput("bun-version", version);
Expand Down
20 changes: 20 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,26 @@ export function getCacheKey(url: string): string {
return `bun-${createHash("sha1").update(url).digest("base64")}`;
}

export function verifyChecksum(path: string, expectedChecksum?: string): void {
if (!expectedChecksum) {
return;
}

const normalizedExpected = expectedChecksum.trim().toLowerCase();
if (!/^[a-f0-9]{64}$/.test(normalizedExpected)) {
throw new Error("The checksum input must be a SHA256 hex digest.");
}

const actualChecksum = createHash("sha256")
.update(readFileSync(path))
.digest("hex");
if (actualChecksum !== normalizedExpected) {
throw new Error(
`Downloaded Bun archive checksum mismatch. Expected ${normalizedExpected}, got ${actualChecksum}.`,
);
}
}

export function extractVersionFromUrl(url: string): string | undefined {
const match = url.match(/\/bun-v([^/]+)\//);
return match?.[1];
Expand Down