mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-06-05 21:48:31 +01:00
Per maintainer feedback (fredrikburmester, lancechant): the version dropdown no longer surfaces draft releases as "X (TestFlight)" — drafts and prereleases are unreliable version identifiers. update-issue-form.mjs now fetches only published, non-prerelease releases and drops the per-version TestFlight label; the workflow triggers on `released` events only; and the generic "TestFlight/Development build" sentinel is restored at the end of the list.
115 lines
3.6 KiB
JavaScript
115 lines
3.6 KiB
JavaScript
#!/usr/bin/env bun
|
|
/**
|
|
* Populates the "Streamyfin Version" dropdown in the issue report form with the
|
|
* latest GitHub releases. Run by the "Update Issue Form Versions" workflow on
|
|
* release events + a weekly cron (and manually via workflow_dispatch).
|
|
*
|
|
* Source: published, non-draft, non-prerelease GitHub releases, newest first.
|
|
* Non-version sentinels (e.g. "older", "TestFlight/Development build") are
|
|
* preserved at the end of the list.
|
|
*
|
|
* Usage:
|
|
* bun scripts/update-issue-form.mjs # rewrite the form in place
|
|
* ISSUE_FORM_LIMIT=8 bun scripts/update-issue-form.mjs
|
|
* bun scripts/update-issue-form.mjs --dry-run # print the new options, don't write
|
|
*
|
|
* Env: GITHUB_REPOSITORY (owner/repo), GH_TOKEN/GITHUB_TOKEN (for gh, provided in CI).
|
|
*/
|
|
|
|
import { execFileSync } from "node:child_process";
|
|
import {
|
|
appendFileSync,
|
|
readFileSync as read,
|
|
writeFileSync as write,
|
|
} from "node:fs";
|
|
|
|
const FORM = ".github/ISSUE_TEMPLATE/issue_report.yml";
|
|
const DROPDOWN_ID = "version"; // the `id:` of the dropdown to populate
|
|
const parsedLimit = Number.parseInt(process.env.ISSUE_FORM_LIMIT ?? "", 10);
|
|
const LIMIT =
|
|
Number.isInteger(parsedLimit) && parsedLimit > 0 ? parsedLimit : 5;
|
|
const REPO = process.env.GITHUB_REPOSITORY || "streamyfin/streamyfin";
|
|
const DRY = process.argv.includes("--dry-run");
|
|
|
|
// Matches "0.54.1" and prerelease/beta tags like "0.54.0-beta.1".
|
|
const isVersion = (s) => /^\d+\.\d+/.test(s.trim());
|
|
|
|
// 1. Fetch published releases (newest first), excluding drafts and prereleases —
|
|
// those aren't a full release users run, so they don't belong in the dropdown.
|
|
const raw = execFileSync(
|
|
"gh",
|
|
[
|
|
"api",
|
|
`repos/${REPO}/releases`,
|
|
"--paginate",
|
|
"--jq",
|
|
".[] | select(.draft == false and .prerelease == false) | .tag_name",
|
|
],
|
|
{ encoding: "utf8" },
|
|
);
|
|
const seen = new Set();
|
|
const versions = [];
|
|
for (const tag of raw.split("\n")) {
|
|
if (!tag) continue;
|
|
const ver = tag.trim().replace(/^v/, "");
|
|
if (!isVersion(ver) || seen.has(ver)) continue;
|
|
seen.add(ver);
|
|
versions.push(ver);
|
|
if (versions.length >= LIMIT) break;
|
|
}
|
|
|
|
if (!versions.length) {
|
|
console.error("No release versions found — leaving the form untouched.");
|
|
process.exit(1);
|
|
}
|
|
|
|
// 2. rewrite the dropdown options, preserving non-version sentinels
|
|
// (e.g. "older", "TestFlight/Development build") at the end of the list.
|
|
const lines = read(FORM, "utf8").split("\n");
|
|
const idIdx = lines.findIndex((l) =>
|
|
l.match(new RegExp(`^\\s*id:\\s*${DROPDOWN_ID}\\s*$`)),
|
|
);
|
|
if (idIdx === -1)
|
|
throw new Error(`dropdown id: ${DROPDOWN_ID} not found in ${FORM}`);
|
|
const optIdx = lines.findIndex(
|
|
(l, i) => i > idIdx && /^\s*options:\s*$/.test(l),
|
|
);
|
|
if (optIdx === -1)
|
|
throw new Error(`options: not found after id: ${DROPDOWN_ID}`);
|
|
|
|
const itemIndent = lines[optIdx].match(/^\s*/)[0] + " "; // options items are nested one level deeper
|
|
let end = optIdx + 1;
|
|
const sentinels = [];
|
|
while (end < lines.length && /^\s*-\s+/.test(lines[end])) {
|
|
const val = lines[end].replace(/^\s*-\s+/, "");
|
|
if (!isVersion(val)) sentinels.push(val);
|
|
end++;
|
|
}
|
|
|
|
const newOptions = [...versions, ...sentinels].map(
|
|
(v) => `${itemIndent}- ${v}`,
|
|
);
|
|
const updated = [
|
|
...lines.slice(0, optIdx + 1),
|
|
...newOptions,
|
|
...lines.slice(end),
|
|
].join("\n");
|
|
|
|
console.log(
|
|
`Versions: ${versions.join(", ")}${sentinels.length ? ` | kept: ${sentinels.join(", ")}` : ""}`,
|
|
);
|
|
if (DRY) {
|
|
console.log("--dry-run: not writing.");
|
|
} else {
|
|
write(FORM, updated);
|
|
console.log(`Updated ${FORM}.`);
|
|
}
|
|
|
|
// Expose the resulting list for the workflow (PR description).
|
|
if (process.env.GITHUB_OUTPUT) {
|
|
appendFileSync(
|
|
process.env.GITHUB_OUTPUT,
|
|
`versions=${versions.join(", ")}\n`,
|
|
);
|
|
}
|