Files
kst4contest/website/src/_data/nightly.js
T
Rsclub2_2andClaude Fable 5 a28abe1591 Update repository URLs to HamRadioOnline organisation (#142)
* Move remaining references to the HamRadioOnline organisation

The repository moved from praktimarc/kst4contest to
HamRadioOnline/kst4contest. Document the move in the German and English
changelog, point manuals, README, website, AUR packaging and the
version-feed tooling at the new address, and keep accepting pre-move
release URLs in the update-feed validator because published feeds still
carry the old owner. Personal identities (Ko-Fi account, contact
e-mail) stay unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WFGQ7wkSPo21itLMHPi8Yw

* Lowercase the owner in the generated Flatpak Pages URL

GITHUB_REPOSITORY_OWNER is now the mixed-case HamRadioOnline, and the
next build would write that spelling into the published flatpakrepo and
flatpakref files. Hostnames are case-insensitive, but the published
metadata should match the documented lowercase address.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WFGQ7wkSPo21itLMHPi8Yw

* Build the Flatpak against org.freedesktop.Platform 25.08

Runtime branch 24.08 is end-of-life and no longer receives security
updates, so every flatpak update now prints an EOL warning. 25.08 is
the current supported branch on Flathub. The app bundles its own Java
runtime, so the platform bump only changes the base libraries.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WFGQ7wkSPo21itLMHPi8Yw

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-17 23:06:01 +02:00

192 lines
5.7 KiB
JavaScript

const REPO = "HamRadioOnline/kst4contest";
const API = `https://api.github.com/repos/${REPO}`;
const WORKFLOW_FILE = "nightly-artifacts.yml";
const WORKFLOW_BASENAME = "nightly-artifacts";
const BRANCH = "main";
const WORKFLOW_RUNS_URL = `https://github.com/${REPO}/actions/workflows/${WORKFLOW_FILE}`;
/**
* nightly.link (https://nightly.link) mirrors the most recent successful
* GitHub Actions artifact for a given workflow/branch/artifact-name as a
* plain public download, with no GitHub account required. It always follows
* the latest successful run on its own, so these URLs stay correct without
* this site having to resolve a run ID at build time.
*/
const NIGHTLY_LINK_BASE = `https://nightly.link/${REPO}/workflows/${WORKFLOW_BASENAME}/${BRANCH}`;
/**
* Static metadata for the artifacts produced by
* .github/workflows/nightly-artifacts.yml, keyed by the upload-artifact name
* used in that workflow. Anything not listed here (e.g. the raw
* flatpak-ostree-repo folder) is skipped on the nightly page.
*/
const ARTIFACT_INFO = {
"windows-zip": {
os: "Windows",
format: "ZIP x64",
icon: "🪟",
note: "Extract the archive, then start praktiKST.exe. No separate Java installation is required.",
order: 1
},
"linux-appimage": {
os: "Linux",
format: "AppImage x86_64",
icon: "🐧",
note: "Portable build. Make the downloaded file executable before the first launch.",
order: 2
},
flatpakref: {
os: "Linux",
format: "Flatpak (.flatpakref, nightly branch)",
icon: "🐧",
note: "Adds the nightly branch of the KST4Contest Flatpak repo. See the installation guide for the flatpak CLI alternative.",
order: 3
},
"linux-debian": {
os: "Debian / Ubuntu",
format: "DEB amd64",
icon: "📦",
note: "Native package for Debian, Ubuntu and distributions based on them.",
order: 4
},
"linux-fedora": {
os: "Fedora",
format: "RPM x86_64",
icon: "📦",
note: "Native package built for Fedora and compatible RPM-based systems.",
order: 5
},
"linux-arch": {
os: "Arch Linux",
format: "pkg.tar.zst",
icon: "📦",
note: "Package for direct installation with pacman.",
order: 6
},
"macos-dmg-macos-latest": {
os: "macOS Apple Silicon",
format: "DMG arm64",
icon: "🍎",
note: "Best-effort build for Apple Silicon Macs. Signed and notarized by Apple.",
order: 7
},
"macos-dmg-macos-15-intel": {
os: "macOS Intel",
format: "DMG x86_64",
icon: "🍎",
note: "Best-effort build for Intel Macs. Signed and notarized by Apple.",
order: 8
}
};
function buildItems() {
return Object.entries(ARTIFACT_INFO)
.map(([name, info]) => ({
...info,
name,
url: `${NIGHTLY_LINK_BASE}/${name}.zip`
}))
.sort((a, b) => a.order - b.order);
}
function authHeaders() {
const headers = { Accept: "application/vnd.github+json" };
if (process.env.GITHUB_TOKEN) {
headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`;
}
return headers;
}
function formatSize(bytes) {
if (bytes < 1024 * 1024) {
return `${(bytes / 1024).toFixed(0)} KB`;
}
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}
/**
* Best-effort lookup of the run behind the current nightly.link downloads,
* purely to show a commit/date on the page. The download links themselves
* (buildItems) do not depend on this succeeding.
*/
async function fetchLatestRunMeta(headers) {
const runsRes = await fetch(
`${API}/actions/workflows/${WORKFLOW_FILE}/runs?branch=${BRANCH}&status=success&per_page=1`,
{ headers }
);
if (!runsRes.ok) {
throw new Error(`workflow runs request failed: ${runsRes.status}`);
}
const runsData = await runsRes.json();
const run = runsData.workflow_runs && runsData.workflow_runs[0];
if (!run) {
throw new Error("no successful nightly run found");
}
const meta = {
runUrl: run.html_url,
commitUrl: `https://github.com/${REPO}/commit/${run.head_sha}`,
shortSha: run.head_sha.slice(0, 7),
createdAt: run.created_at
};
try {
const artifactsRes = await fetch(
`${API}/actions/runs/${run.id}/artifacts?per_page=100`,
{ headers }
);
if (artifactsRes.ok) {
const artifactsData = await artifactsRes.json();
const sizeByName = {};
for (const artifact of artifactsData.artifacts || []) {
if (!artifact.expired) {
sizeByName[artifact.name] = formatSize(artifact.size_in_bytes);
}
}
meta.sizeByName = sizeByName;
}
} catch {
// Sizes are a nice-to-have; the run metadata above is still useful without them.
}
return meta;
}
module.exports = async function () {
const items = buildItems();
let meta = null;
try {
meta = await fetchLatestRunMeta(authHeaders());
} catch (err) {
console.warn(
`[nightly] Could not load latest nightly run metadata (commit/date will be omitted). ` +
`Download links are unaffected since they are served by nightly.link: ${err.message}`
);
}
if (meta && meta.sizeByName) {
for (const item of items) {
if (meta.sizeByName[item.name]) {
item.size = meta.sizeByName[item.name];
}
}
}
return {
runsUrl: WORKFLOW_RUNS_URL,
meta,
items
};
};