mirror of
https://github.com/getpaseo/paseo.git
synced 2026-09-14 20:36:44 +08:00
47171b419b
The ESM main-module guard compared import.meta.url with "file://" + process.argv[1],
which never matches on Windows (file://D:\a\... vs file:///D:/a/...). On the Windows
desktop release job, scripts/github-release.mjs therefore printed nothing and
gh release upload received an empty release lookup ("release not found"), leaving
v0.8.0-beta.1 without a Windows build. Compare resolved paths instead, shared by
every release script that runs as a CLI.
110 lines
3.0 KiB
JavaScript
110 lines
3.0 KiB
JavaScript
import { execFileSync as nodeExecFileSync } from "node:child_process";
|
|
import { isMainModule } from "./is-main-module.mjs";
|
|
|
|
function parseJson(output) {
|
|
return JSON.parse(output);
|
|
}
|
|
|
|
function isNotFoundError(error) {
|
|
return String(error?.stderr ?? "").includes("HTTP 404");
|
|
}
|
|
|
|
export function getGitHubRelease(repo, tag, execFileSync = nodeExecFileSync) {
|
|
try {
|
|
return parseJson(
|
|
execFileSync("gh", ["api", `repos/${repo}/releases/tags/${tag}`], {
|
|
encoding: "utf8",
|
|
stdio: ["ignore", "pipe", "pipe"],
|
|
}),
|
|
);
|
|
} catch (error) {
|
|
if (!isNotFoundError(error)) {
|
|
throw error;
|
|
}
|
|
const expectedName = `Paseo ${tag}`;
|
|
const output = execFileSync(
|
|
"gh",
|
|
[
|
|
"api",
|
|
`repos/${repo}/releases?per_page=100`,
|
|
"--jq",
|
|
`[.[] | select(.draft == true and .name == ${JSON.stringify(expectedName)})] | sort_by(.id)`,
|
|
],
|
|
{
|
|
encoding: "utf8",
|
|
},
|
|
);
|
|
return parseJson(output)[0] ?? null;
|
|
}
|
|
}
|
|
|
|
export function getReleaseLookupTag(release) {
|
|
if (release.draft === true && release.html_url) {
|
|
return new URL(release.html_url).pathname.split("/").at(-1);
|
|
}
|
|
return release.tag_name;
|
|
}
|
|
|
|
function parseArgs(argv) {
|
|
let repo = "";
|
|
let tag = "";
|
|
let cleanupDuplicates = false;
|
|
for (let index = 0; index < argv.length; index += 1) {
|
|
if (argv[index] === "--repo") {
|
|
repo = argv[index + 1] ?? "";
|
|
index += 1;
|
|
} else if (argv[index] === "--tag") {
|
|
tag = argv[index + 1] ?? "";
|
|
index += 1;
|
|
} else if (argv[index] === "--cleanup-duplicates") {
|
|
cleanupDuplicates = true;
|
|
} else {
|
|
throw new Error(`Unknown argument: ${argv[index]}`);
|
|
}
|
|
}
|
|
if (!repo || !tag) {
|
|
throw new Error("Usage: node scripts/github-release.mjs --repo <owner/repo> --tag <tag>");
|
|
}
|
|
return { cleanupDuplicates, repo, tag };
|
|
}
|
|
|
|
if (isMainModule(import.meta.url)) {
|
|
const { cleanupDuplicates, repo, tag } = parseArgs(process.argv.slice(2));
|
|
let release = null;
|
|
for (let attempt = 0; attempt < 5 && !release; attempt += 1) {
|
|
release = getGitHubRelease(repo, tag);
|
|
if (!release && attempt < 4) {
|
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 1_000);
|
|
}
|
|
}
|
|
if (!release) {
|
|
process.exitCode = 1;
|
|
} else {
|
|
if (cleanupDuplicates && release.draft === true) {
|
|
const expectedName = `Paseo ${tag}`;
|
|
const duplicateIds = nodeExecFileSync(
|
|
"gh",
|
|
[
|
|
"api",
|
|
`repos/${repo}/releases?per_page=100`,
|
|
"--jq",
|
|
`.[] | select(.draft == true and .name == ${JSON.stringify(expectedName)} and .id != ${release.id}) | .id`,
|
|
],
|
|
{ encoding: "utf8" },
|
|
)
|
|
.trim()
|
|
.split("\n")
|
|
.filter(Boolean);
|
|
for (const duplicateId of duplicateIds) {
|
|
nodeExecFileSync("gh", [
|
|
"api",
|
|
"--method",
|
|
"DELETE",
|
|
`repos/${repo}/releases/${duplicateId}`,
|
|
]);
|
|
}
|
|
}
|
|
process.stdout.write(`${getReleaseLookupTag(release)}\n`);
|
|
}
|
|
}
|