setup-bun/dist/setup.js

100 lines
3.4 KiB
JavaScript
Raw Normal View History

2023-02-22 17:47:24 -08:00
import { homedir } from "node:os";
import { join } from "node:path";
import { readdir } from "node:fs/promises";
import * as action from "@actions/core";
import { downloadTool, extractZip } from "@actions/tool-cache";
import * as cache from "@actions/cache";
import { restoreCache, saveCache } from "@actions/cache";
import { mv } from "@actions/io";
import { getExecOutput } from "@actions/exec";
export default async (options) => {
2023-02-22 17:51:12 -08:00
const { url, cacheKey } = getDownloadUrl(options);
const cacheEnabled = cacheKey && cache.isFeatureAvailable();
const dir = join(homedir(), ".bun", "bin");
action.addPath(dir);
const path = join(dir, "bun");
let version;
let cacheHit = false;
if (cacheEnabled) {
const cacheRestored = await restoreCache([path], cacheKey);
if (cacheRestored) {
version = await verifyBun(path);
if (version) {
cacheHit = true;
action.info("Using a cached version of Bun.");
}
else {
action.warning("Found a cached version of Bun, but it appears to be corrupted? Attempting to download a new version.");
}
}
2023-02-22 17:47:24 -08:00
}
2023-02-22 17:51:12 -08:00
if (!cacheHit) {
action.info(`Downloading a new version of Bun: ${url}`);
const zipPath = await downloadTool(url);
const extractedPath = await extractZip(zipPath);
const exePath = await extractBun(extractedPath);
await mv(exePath, path);
version = await verifyBun(path);
2023-02-22 17:47:24 -08:00
}
2023-02-22 17:51:12 -08:00
if (!version) {
throw new Error("Downloaded a new version of Bun, but failed to check its version? Try again in debug mode.");
}
if (cacheEnabled) {
try {
await saveCache([path], cacheKey);
}
catch (error) {
action.warning("Failed to save Bun to cache.");
}
}
return {
version,
cacheHit,
};
2023-02-22 17:47:24 -08:00
};
function getDownloadUrl(options) {
2023-02-22 17:51:12 -08:00
if (options?.customUrl) {
return {
url: options.customUrl,
cacheKey: null,
};
}
const release = encodeURIComponent(options?.version ?? "latest");
2023-02-22 17:51:12 -08:00
const os = options?.os ?? process.platform;
const arch = options?.arch ?? process.arch;
const avx2 = options?.avx2 ?? true;
const profile = options?.profile ?? false;
const { href } = new URL(`${release}/${os}/${arch}?avx2=${avx2}&profile=${profile}`, "https://bun.sh/download/");
2023-02-22 17:47:24 -08:00
return {
2023-02-22 17:51:12 -08:00
url: href,
cacheKey: /^canary|latest$/i.test(release)
? null
: `bun-${release}-${os}-${arch}-${avx2}-${profile}`,
2023-02-22 17:47:24 -08:00
};
}
async function extractBun(path) {
2023-02-22 17:51:12 -08:00
for (const entry of await readdir(path, { withFileTypes: true })) {
2023-02-22 18:19:00 -08:00
const { name } = entry;
const entryPath = join(path, name);
if (entry.isFile()) {
if (name === "bun") {
return entryPath;
}
if (/^bun.*\.zip/.test(name)) {
const extractedPath = await extractZip(entryPath);
return extractBun(extractedPath);
}
2023-02-22 17:51:12 -08:00
}
2023-02-22 18:19:00 -08:00
if (/^bun/.test(name) && entry.isDirectory()) {
2023-02-22 17:51:12 -08:00
return extractBun(entryPath);
}
2023-02-22 17:47:24 -08:00
}
2023-02-22 17:51:12 -08:00
throw new Error("Could not find executable: bun");
2023-02-22 17:47:24 -08:00
}
async function verifyBun(path) {
2023-02-22 17:51:12 -08:00
const { exitCode, stdout } = await getExecOutput(path, ["--version"], {
ignoreReturnCode: true,
});
return exitCode === 0 ? stdout.trim() : undefined;
2023-02-22 17:47:24 -08:00
}