feat: implement wildcard resolution into the action (#93)
* feat: remove retry attempts * [autofix.ci] apply automated fixes * feat: get download url from github's api * [autofix.ci] apply automated fixes * fix: add token property to action definition & fix satisfies params * [autofix.ci] apply automated fixes * fix: getPlatform, getArchitecture + eversion * [autofix.ci] apply automated fixes * fix: duplicate v * [autofix.ci] apply automated fixes * fix: check if valid semver and add bun-v * [autofix.ci] apply automated fixes * refactor: wrap validation * [autofix.ci] apply automated fixes * ci(format): use bun bun install is rqeuired for patches * ci(format): use bun bun install is rqeuired for patches * [autofix.ci] apply automated fixes * feat: bring back support for sha downloads * [autofix.ci] apply automated fixes * fix: add bearer prefix for token * [autofix.ci] apply automated fixes * fix: proper error when artifact is not found * [autofix.ci] apply automated fixes * conflicts * autofix build * fix * fix * fix * fix * fix * autofix build * fix * [autofix.ci] apply automated fixes * fix * [autofix.ci] apply automated fixes * fix * [autofix.ci] apply automated fixes * fix * fix * [autofix.ci] apply automated fixes * fix * fix * [autofix.ci] apply automated fixes * fix: drop sha support for now * [autofix.ci] apply automated fixes * fix: filter tags * [autofix.ci] apply automated fixes * docs: token * docs: token * docs: token * refactor: cleanup * [autofix.ci] apply automated fixes * refactor: cleanup --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -13,9 +13,11 @@ import { addPath, info, warning } from "@actions/core";
|
||||
import { isFeatureAvailable, restoreCache } from "@actions/cache";
|
||||
import { downloadTool, extractZip } from "@actions/tool-cache";
|
||||
import { getExecOutput } from "@actions/exec";
|
||||
import { writeBunfig, Registry } from "./bunfig";
|
||||
import { Registry } from "./registry";
|
||||
import { writeBunfig } from "./bunfig";
|
||||
import { saveState } from "@actions/core";
|
||||
import { addExtension, retry } from "./utils";
|
||||
import { addExtension } from "./utils";
|
||||
import { getDownloadUrl } from "./download-url";
|
||||
import { cwd } from "node:process";
|
||||
|
||||
export type Input = {
|
||||
@@ -27,6 +29,7 @@ export type Input = {
|
||||
profile?: boolean;
|
||||
registries?: Registry[];
|
||||
noCache?: boolean;
|
||||
token?: string;
|
||||
};
|
||||
|
||||
export type Output = {
|
||||
@@ -48,7 +51,7 @@ export default async (options: Input): Promise<Output> => {
|
||||
const bunfigPath = join(cwd(), "bunfig.toml");
|
||||
writeBunfig(bunfigPath, options.registries);
|
||||
|
||||
const url = getDownloadUrl(options);
|
||||
const url = await getDownloadUrl(options);
|
||||
const cacheEnabled = isCacheEnabled(options);
|
||||
|
||||
const binPath = join(homedir(), ".bun", "bin");
|
||||
@@ -105,8 +108,7 @@ export default async (options: Input): Promise<Output> => {
|
||||
|
||||
if (!cacheHit) {
|
||||
info(`Downloading a new version of Bun: ${url}`);
|
||||
// TODO: remove this, temporary fix for https://github.com/oven-sh/setup-bun/issues/73
|
||||
revision = await retry(async () => await downloadBun(url, bunPath), 3);
|
||||
revision = await downloadBun(url, bunPath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,24 +194,6 @@ function isCacheEnabled(options: Input): boolean {
|
||||
return isFeatureAvailable();
|
||||
}
|
||||
|
||||
function getDownloadUrl(options: Input): string {
|
||||
const { customUrl } = options;
|
||||
if (customUrl) {
|
||||
return customUrl;
|
||||
}
|
||||
const { version, os, arch, avx2, profile } = options;
|
||||
const eversion = encodeURIComponent(version ?? "latest");
|
||||
const eos = encodeURIComponent(os ?? process.platform);
|
||||
const earch = encodeURIComponent(arch ?? process.arch);
|
||||
const eavx2 = encodeURIComponent(avx2 ?? true);
|
||||
const eprofile = encodeURIComponent(profile ?? false);
|
||||
const { href } = new URL(
|
||||
`${eversion}/${eos}/${earch}?avx2=${eavx2}&profile=${eprofile}`,
|
||||
"https://bun.sh/download/",
|
||||
);
|
||||
return href;
|
||||
}
|
||||
|
||||
async function extractBun(path: string): Promise<string> {
|
||||
for (const entry of readdirSync(path, { withFileTypes: true })) {
|
||||
const { name } = entry;
|
||||
|
||||
63
src/download-url.ts
Normal file
63
src/download-url.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { compareVersions, satisfies, validate } from "compare-versions";
|
||||
import { Input } from "./action";
|
||||
import { getArchitecture, getPlatform, request } from "./utils";
|
||||
|
||||
export async function getDownloadUrl(options: Input): Promise<string> {
|
||||
const { customUrl } = options;
|
||||
if (customUrl) {
|
||||
return customUrl;
|
||||
}
|
||||
|
||||
return await getSemverDownloadUrl(options);
|
||||
}
|
||||
|
||||
async function getSemverDownloadUrl(options: Input): Promise<string> {
|
||||
const res = (await (
|
||||
await request("https://api.github.com/repos/oven-sh/bun/git/refs/tags", {
|
||||
headers: options.token
|
||||
? { "Authorization": `Bearer ${options.token}` }
|
||||
: {},
|
||||
})
|
||||
).json()) as { ref: string }[];
|
||||
|
||||
let tags = res
|
||||
.filter(
|
||||
(tag) =>
|
||||
tag.ref.startsWith("refs/tags/bun-v") || tag.ref === "refs/tags/canary",
|
||||
)
|
||||
.map((item) => item.ref.replace(/refs\/tags\/(bun-v)?/g, ""))
|
||||
.filter(Boolean);
|
||||
|
||||
const { version, os, arch, avx2, profile } = options;
|
||||
|
||||
let tag = tags.find((t) => t === version);
|
||||
if (!tag) {
|
||||
tags = tags.filter((t) => validate(t)).sort(compareVersions);
|
||||
|
||||
const matchedTag =
|
||||
version === "latest" || !version
|
||||
? tags.at(-1)
|
||||
: tags.filter((t) => satisfies(t, version)).at(-1);
|
||||
|
||||
if (!matchedTag) {
|
||||
throw new Error(`No Bun release found matching version '${version}'`);
|
||||
}
|
||||
|
||||
tag = `bun-v${matchedTag}`;
|
||||
} else if (validate(tag)) {
|
||||
tag = `bun-v${tag}`;
|
||||
}
|
||||
|
||||
const eversion = encodeURIComponent(tag ?? version);
|
||||
const eos = encodeURIComponent(os ?? getPlatform());
|
||||
const earch = encodeURIComponent(arch ?? getArchitecture());
|
||||
const eavx2 = encodeURIComponent(avx2 === false ? "-baseline" : "");
|
||||
const eprofile = encodeURIComponent(profile === true ? "-profile" : "");
|
||||
|
||||
const { href } = new URL(
|
||||
`${eversion}/bun-${eos}-${earch}${eavx2}${eprofile}.zip`,
|
||||
"https://github.com/oven-sh/bun/releases/download/",
|
||||
);
|
||||
|
||||
return href;
|
||||
}
|
||||
@@ -30,6 +30,7 @@ runAction({
|
||||
customUrl: getInput("bun-download-url") || undefined,
|
||||
registries: registries,
|
||||
noCache: getBooleanInput("no-cache") || false,
|
||||
token: getInput("token"),
|
||||
})
|
||||
.then(({ version, revision, bunPath, url, cacheHit }) => {
|
||||
setOutput("bun-version", version);
|
||||
|
||||
46
src/utils.ts
46
src/utils.ts
@@ -3,19 +3,27 @@ import { info } from "node:console";
|
||||
import { existsSync, readFileSync, renameSync } from "node:fs";
|
||||
import { resolve, basename } from "node:path";
|
||||
|
||||
export function retry<T>(
|
||||
fn: () => Promise<T>,
|
||||
retries: number,
|
||||
timeout = 10000,
|
||||
): Promise<T> {
|
||||
return fn().catch((err) => {
|
||||
if (retries <= 0) {
|
||||
throw err;
|
||||
}
|
||||
return new Promise((resolve) => setTimeout(resolve, timeout)).then(() =>
|
||||
retry(fn, retries - 1, timeout),
|
||||
);
|
||||
export async function request(
|
||||
url: string,
|
||||
init?: RequestInit,
|
||||
): Promise<Response> {
|
||||
const headers = new Headers(init?.headers);
|
||||
if (!headers.has("User-Agent")) {
|
||||
headers.set("User-Agent", "@oven-sh/setup-bun");
|
||||
}
|
||||
|
||||
const res = await fetch(url, {
|
||||
...init,
|
||||
headers,
|
||||
});
|
||||
if (!res.ok) {
|
||||
const body = await res.text().catch(() => "");
|
||||
throw new Error(
|
||||
`Failed to fetch url ${url}. (status code: ${res.status}, status text: ${res.statusText})${body ? `\n${body}` : ""}`,
|
||||
);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
export function addExtension(path: string, ext: string): string {
|
||||
@@ -27,6 +35,20 @@ export function addExtension(path: string, ext: string): string {
|
||||
return path;
|
||||
}
|
||||
|
||||
export function getPlatform(): string {
|
||||
const platform = process.platform;
|
||||
if (platform === "win32") return "windows";
|
||||
|
||||
return platform;
|
||||
}
|
||||
|
||||
export function getArchitecture(): string {
|
||||
const arch = process.arch;
|
||||
if (arch === "arm64") return "aarch64";
|
||||
|
||||
return arch;
|
||||
}
|
||||
|
||||
const FILE_VERSION_READERS = {
|
||||
"package.json": (content: string) => {
|
||||
const pkg = JSON.parse(content);
|
||||
|
||||
Reference in New Issue
Block a user