-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: implement wildcard resolution into the action #93
Changes from all commits
54abc74
99d7a7a
3ed283c
1cf9dea
8611d10
c3e2edf
528c470
4d53c4d
0d021b0
019399b
e53a660
d9c4697
2cadd94
bba0526
6d50d76
26e8dad
f96af5b
35cdfa7
d51557d
6c4630f
65bc9b0
bb58792
f3a3a4d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,7 +27,8 @@ | |
"@actions/exec": "^1.1.1", | ||
"@actions/glob": "^0.4.0", | ||
"@actions/io": "^1.1.2", | ||
"@actions/tool-cache": "^2.0.1" | ||
"@actions/tool-cache": "^2.0.1", | ||
"compare-versions": "^6.1.1" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^20.8.2", | ||
|
@@ -37,5 +38,8 @@ | |
}, | ||
"prettier": { | ||
"quoteProps": "preserve" | ||
}, | ||
"patchedDependencies": { | ||
"[email protected]": "patches/[email protected]" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
diff --git a/lib/esm/satisfies.js b/lib/esm/satisfies.js | ||
index 7586b71657332f855431c4dd4f05e9394fd9aac3..a6ec29bfc98907c67ed4af71fca73bd8bff88798 100644 | ||
--- a/lib/esm/satisfies.js | ||
+++ b/lib/esm/satisfies.js | ||
@@ -40,8 +40,9 @@ export const satisfies = (version, range) => { | ||
// else range of either "~" or "^" is assumed | ||
const [v1, v2, v3, , vp] = validateAndParse(version); | ||
const [r1, r2, r3, , rp] = validateAndParse(range); | ||
- const v = [v1, v2, v3]; | ||
+ const v = [v1, v2 !== null && v2 !== void 0 ? v2 : 'x', v3 !== null && v3 !== void 0 ? v3 : 'x']; | ||
const r = [r1, r2 !== null && r2 !== void 0 ? r2 : 'x', r3 !== null && r3 !== void 0 ? r3 : 'x']; | ||
+ | ||
// validate pre-release | ||
if (rp) { | ||
if (!vp) | ||
diff --git a/lib/esm/utils.js b/lib/esm/utils.js | ||
index b5cc8b9927ab38fc67032c133b531e95ec4cec15..ec56105fd2d806aa922f1488a27b02c56aff1865 100644 | ||
--- a/lib/esm/utils.js | ||
+++ b/lib/esm/utils.js | ||
@@ -28,7 +28,7 @@ const compareStrings = (a, b) => { | ||
}; | ||
export const compareSegments = (a, b) => { | ||
for (let i = 0; i < Math.max(a.length, b.length); i++) { | ||
- const r = compareStrings(a[i] || '0', b[i] || '0'); | ||
+ const r = compareStrings(a[i] || 'x', b[i] || 'x'); | ||
if (r !== 0) | ||
return r; | ||
} | ||
diff --git a/lib/umd/index.js b/lib/umd/index.js | ||
index 2cfef261bca520e21ed41fc14950732b8aa6339b..1059784db86635f3aaaba83b5a72c5015e1d8490 100644 | ||
--- a/lib/umd/index.js | ||
+++ b/lib/umd/index.js | ||
@@ -152,7 +152,7 @@ | ||
// else range of either "~" or "^" is assumed | ||
const [v1, v2, v3, , vp] = validateAndParse(version); | ||
const [r1, r2, r3, , rp] = validateAndParse(range); | ||
- const v = [v1, v2, v3]; | ||
+ const v = [v1, v2 !== null && v2 !== void 0 ? v2 : 'x', v3 !== null && v3 !== void 0 ? v3 : 'x']; | ||
const r = [r1, r2 !== null && r2 !== void 0 ? r2 : 'x', r3 !== null && r3 !== void 0 ? r3 : 'x']; | ||
// validate pre-release | ||
if (rp) { | ||
diff --git a/package.json b/package.json | ||
index b05b3daf706d7ba4e594233f8791fc3007a8e2cd..e51e76b86f95e9ebf0b5dba3b82aeb119628528d 100644 | ||
--- a/package.json | ||
+++ b/package.json | ||
@@ -26,7 +26,7 @@ | ||
"prepublishOnly": "npm run build", | ||
"test": "c8 --reporter=lcov mocha" | ||
}, | ||
- "main": "./lib/umd/index.js", | ||
+ "main": "./lib/src/index.ts", | ||
"module": "./lib/esm/index.js", | ||
"types": "./lib/esm/index.d.ts", | ||
"sideEffects": false, | ||
diff --git a/src/satisfies.ts b/src/satisfies.ts | ||
index 66cb171d7f32e68fdda6929d2da223b97a053737..6b4973f037843f264338a01efdc4ace5dcf042cd 100644 | ||
--- a/src/satisfies.ts | ||
+++ b/src/satisfies.ts | ||
@@ -43,7 +43,7 @@ export const satisfies = (version: string, range: string): boolean => { | ||
// else range of either "~" or "^" is assumed | ||
const [v1, v2, v3, , vp] = validateAndParse(version); | ||
const [r1, r2, r3, , rp] = validateAndParse(range); | ||
- const v = [v1, v2, v3]; | ||
+ const v = [v1, v2 ?? 'x', v3 ?? 'x']; | ||
const r = [r1, r2 ?? 'x', r3 ?? 'x']; | ||
|
||
// validate pre-release |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
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}`, | ||
{ | ||
headers: { | ||
"Authorization": `Bearer ${options.token}`, | ||
}, | ||
} | ||
) | ||
).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`, | ||
{ | ||
headers: { | ||
"Authorization": `Bearer ${options.token}`, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if the token is not defined in the configuration? The |
||
}, | ||
} | ||
) | ||
).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" : ""}`; | ||
|
||
const artifact = artifacts.artifacts.find((item) => item.name === name); | ||
if (!artifact) { | ||
throw new Error(`Failed to find artifact '${name}' in run '${run.id}'`); | ||
} | ||
|
||
return { | ||
url: artifact.archive_download_url, | ||
auth: `Bearer ${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, | ||
}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's more to access api.github.com with the per token rate limit instead of the per IP one. The documentation should mention that is recommended for user using wildcard or range version.