mirror of
https://github.com/oven-sh/setup-bun.git
synced 2025-07-02 08:13:20 +08:00
feat: bring back support for sha downloads
This commit is contained in:
parent
f96af5bf24
commit
35cdfa7e39
3
.github/workflows/test.yml
vendored
3
.github/workflows/test.yml
vendored
@ -27,7 +27,7 @@ jobs:
|
|||||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
|
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
|
||||||
&& sudo apt update \
|
&& sudo apt update \
|
||||||
&& sudo apt install gh -y
|
&& sudo apt install gh -y
|
||||||
|
|
||||||
- run: |
|
- run: |
|
||||||
gh cache delete --all || true
|
gh cache delete --all || true
|
||||||
env:
|
env:
|
||||||
@ -51,6 +51,7 @@ jobs:
|
|||||||
- "1"
|
- "1"
|
||||||
- "> 1.0.0"
|
- "> 1.0.0"
|
||||||
- "< 2"
|
- "< 2"
|
||||||
|
- "08a9b6a98b14d3c23b58080bea31513546246c50"
|
||||||
# Disable <sha> support for now. This is because Github Artifacts
|
# Disable <sha> support for now. This is because Github Artifacts
|
||||||
# expire after 90 days, and we don't have another source of truth yet.
|
# expire after 90 days, and we don't have another source of truth yet.
|
||||||
# - "822a00c4d508b54f650933a73ca5f4a3af9a7983" # 1.0.0 commit
|
# - "822a00c4d508b54f650933a73ca5f4a3af9a7983" # 1.0.0 commit
|
||||||
|
@ -13,8 +13,8 @@ import { downloadTool, extractZip } from "@actions/tool-cache";
|
|||||||
import { getExecOutput } from "@actions/exec";
|
import { getExecOutput } from "@actions/exec";
|
||||||
import { writeBunfig } from "./bunfig";
|
import { writeBunfig } from "./bunfig";
|
||||||
import { saveState } from "@actions/core";
|
import { saveState } from "@actions/core";
|
||||||
import { addExtension, getArchitecture, getPlatform, request } from "./utils";
|
import { addExtension } from "./utils";
|
||||||
import { compareVersions, satisfies, validate } from "compare-versions";
|
import { DownloadMeta, getDownloadMeta } from "./download-url";
|
||||||
|
|
||||||
export type Input = {
|
export type Input = {
|
||||||
customUrl?: string;
|
customUrl?: string;
|
||||||
@ -48,7 +48,9 @@ export default async (options: Input): Promise<Output> => {
|
|||||||
const bunfigPath = join(process.cwd(), "bunfig.toml");
|
const bunfigPath = join(process.cwd(), "bunfig.toml");
|
||||||
writeBunfig(bunfigPath, options);
|
writeBunfig(bunfigPath, options);
|
||||||
|
|
||||||
const url = await getDownloadUrl(options);
|
const downloadMeta = await getDownloadMeta(options);
|
||||||
|
const url = downloadMeta.url;
|
||||||
|
|
||||||
const cacheEnabled = isCacheEnabled(options);
|
const cacheEnabled = isCacheEnabled(options);
|
||||||
|
|
||||||
const binPath = join(homedir(), ".bun", "bin");
|
const binPath = join(homedir(), ".bun", "bin");
|
||||||
@ -91,7 +93,7 @@ export default async (options: Input): Promise<Output> => {
|
|||||||
|
|
||||||
if (!cacheHit) {
|
if (!cacheHit) {
|
||||||
info(`Downloading a new version of Bun: ${url}`);
|
info(`Downloading a new version of Bun: ${url}`);
|
||||||
revision = await downloadBun(url, bunPath);
|
revision = await downloadBun(downloadMeta, bunPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!revision) {
|
if (!revision) {
|
||||||
@ -121,11 +123,18 @@ export default async (options: Input): Promise<Output> => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
async function downloadBun(
|
async function downloadBun(
|
||||||
url: string,
|
downloadMeta: DownloadMeta,
|
||||||
bunPath: string
|
bunPath: string
|
||||||
): Promise<string | undefined> {
|
): Promise<string | undefined> {
|
||||||
// Workaround for https://github.com/oven-sh/setup-bun/issues/79 and https://github.com/actions/toolkit/issues/1179
|
// 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");
|
const zipPath = addExtension(
|
||||||
|
await downloadTool(
|
||||||
|
downloadMeta.url,
|
||||||
|
undefined,
|
||||||
|
downloadMeta.auth ?? undefined
|
||||||
|
),
|
||||||
|
".zip"
|
||||||
|
);
|
||||||
const extractedZipPath = await extractZip(zipPath);
|
const extractedZipPath = await extractZip(zipPath);
|
||||||
const extractedBunPath = await extractBun(extractedZipPath);
|
const extractedBunPath = await extractBun(extractedZipPath);
|
||||||
try {
|
try {
|
||||||
@ -153,52 +162,6 @@ function isCacheEnabled(options: Input): boolean {
|
|||||||
return isFeatureAvailable();
|
return isFeatureAvailable();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getDownloadUrl(options: Input): Promise<string> {
|
|
||||||
const { customUrl } = options;
|
|
||||||
if (customUrl) {
|
|
||||||
return customUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = (await (
|
|
||||||
await request("https://api.github.com/repos/oven-sh/bun/git/refs/tags", {
|
|
||||||
headers: {
|
|
||||||
"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, ""));
|
|
||||||
|
|
||||||
const { version, os, arch, avx2, profile } = options;
|
|
||||||
|
|
||||||
let tag = tags.find((t) => t === version);
|
|
||||||
if (!tag) {
|
|
||||||
tags = tags.filter((t) => validate(t)).sort(compareVersions);
|
|
||||||
|
|
||||||
if (version === "latest") tag = `bun-v${tags.at(-1)}`;
|
|
||||||
else tag = `bun-v${tags.filter((t) => satisfies(t, version)).at(-1)}`;
|
|
||||||
} 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 ? "-baseline" : "");
|
|
||||||
const eprofile = encodeURIComponent(profile ? "-profile" : "");
|
|
||||||
|
|
||||||
const { href } = new URL(
|
|
||||||
`${eversion}/bun-${eos}-${earch}${eavx2}${eprofile}.zip`,
|
|
||||||
"https://github.com/oven-sh/bun/releases/download/"
|
|
||||||
);
|
|
||||||
|
|
||||||
return href;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function extractBun(path: string): Promise<string> {
|
async function extractBun(path: string): Promise<string> {
|
||||||
for (const entry of readdirSync(path, { withFileTypes: true })) {
|
for (const entry of readdirSync(path, { withFileTypes: true })) {
|
||||||
const { name } = entry;
|
const { name } = entry;
|
||||||
|
113
src/download-url.ts
Normal file
113
src/download-url.ts
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
import { compareVersions, satisfies, validate } from "compare-versions";
|
||||||
|
import { Input } from "./action";
|
||||||
|
import { getArchitecture, getPlatform, request } from "./utils";
|
||||||
|
|
||||||
|
export interface DownloadMeta {
|
||||||
|
url: string;
|
||||||
|
auth?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getDownloadMeta(options: Input): Promise<DownloadMeta> {
|
||||||
|
const { customUrl } = options;
|
||||||
|
if (customUrl) {
|
||||||
|
return {
|
||||||
|
url: customUrl,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.version && /^[0-9a-f]{40}$/i.test(options.version)) {
|
||||||
|
return await getShaDownloadMeta(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await getSemverDownloadMeta(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Run {
|
||||||
|
id: string;
|
||||||
|
head_sha: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Runs {
|
||||||
|
workflow_runs: Run[];
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getShaDownloadMeta(options: Input): Promise<DownloadMeta> {
|
||||||
|
let res: Runs;
|
||||||
|
let page = 1;
|
||||||
|
let run: Run;
|
||||||
|
while (
|
||||||
|
(res = (await (
|
||||||
|
await request(
|
||||||
|
`https://api.github.com/repos/oven-sh/bun/actions/workflows/ci.yml/runs?per_page=100&page=${page}`,
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
).json()) as Runs)
|
||||||
|
) {
|
||||||
|
run = res.workflow_runs.find((item) => item.head_sha === options.version);
|
||||||
|
if (run) break;
|
||||||
|
|
||||||
|
page++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const artifacts = (await (
|
||||||
|
await request(
|
||||||
|
`https://api.github.com/repos/oven-sh/bun/actions/runs/${run.id}/artifacts`,
|
||||||
|
{}
|
||||||
|
)
|
||||||
|
).json()) as { artifacts: { name: string; archive_download_url: string }[] };
|
||||||
|
|
||||||
|
const { os, arch, avx2, profile, token } = options;
|
||||||
|
|
||||||
|
const name = `bun-${os ?? getPlatform()}-${arch ?? getArchitecture()}${
|
||||||
|
avx2 ? "-baseline" : ""
|
||||||
|
}${profile ? "-profile" : ""}`;
|
||||||
|
|
||||||
|
return {
|
||||||
|
url: artifacts.artifacts.find((item) => item.name === name)
|
||||||
|
.archive_download_url,
|
||||||
|
auth: token,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getSemverDownloadMeta(options: Input): Promise<DownloadMeta> {
|
||||||
|
const res = (await (
|
||||||
|
await request("https://api.github.com/repos/oven-sh/bun/git/refs/tags", {
|
||||||
|
headers: {
|
||||||
|
"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, ""));
|
||||||
|
|
||||||
|
const { version, os, arch, avx2, profile } = options;
|
||||||
|
|
||||||
|
let tag = tags.find((t) => t === version);
|
||||||
|
if (!tag) {
|
||||||
|
tags = tags.filter((t) => validate(t)).sort(compareVersions);
|
||||||
|
|
||||||
|
if (version === "latest") tag = `bun-v${tags.at(-1)}`;
|
||||||
|
else tag = `bun-v${tags.filter((t) => satisfies(t, version)).at(-1)}`;
|
||||||
|
} 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 ? "-baseline" : "");
|
||||||
|
const eprofile = encodeURIComponent(profile ? "-profile" : "");
|
||||||
|
|
||||||
|
const { href } = new URL(
|
||||||
|
`${eversion}/bun-${eos}-${earch}${eavx2}${eprofile}.zip`,
|
||||||
|
"https://github.com/oven-sh/bun/releases/download/"
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
url: href,
|
||||||
|
};
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user