website-manual download refactored

This commit is contained in:
Marc Froehlich
2026-07-20 23:58:47 +02:00
parent 0b6120defc
commit 039e64eea0
2 changed files with 99 additions and 66 deletions
+69 -29
View File
@@ -1,31 +1,69 @@
const REPO = "praktimarc/kst4contest"; const REPO = "praktimarc/kst4contest";
const API = `https://api.github.com/repos/${REPO}`; const API = `https://api.github.com/repos/${REPO}`;
const FALLBACK_TAG = "v1.41.1"; const LATEST_RELEASE_URL = `https://github.com/${REPO}/releases/latest`;
async function fetchLatestReleaseTag() { async function fetchLatestReleaseTag() {
const headers = { Accept: "application/vnd.github+json" }; const headers = { Accept: "application/vnd.github+json" };
if (process.env.GITHUB_TOKEN) { if (process.env.GITHUB_TOKEN) {
headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`; headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`;
} }
try { try {
const res = await fetch(`${API}/releases/latest`, { headers }); const res = await fetch(`${API}/releases/latest`, { headers });
if (!res.ok) { if (!res.ok) {
throw new Error(`GitHub API /releases/latest failed: ${res.status}`); throw new Error(
`GitHub API /releases/latest failed: ${res.status}`
);
} }
const release = await res.json(); const release = await res.json();
return release.tag_name || FALLBACK_TAG;
if (!release.tag_name) {
throw new Error(
"GitHub API response did not contain a release tag"
);
}
return release.tag_name;
} catch (err) { } catch (err) {
console.warn(`[downloads] Could not load latest release tag, falling back to ${FALLBACK_TAG}: ${err.message}`); console.warn(
return FALLBACK_TAG; `[downloads] Could not load the latest release tag. ` +
`Download buttons will open the latest release page instead: ${err.message}`
);
return null;
} }
} }
// Builds the download list from the latest GitHub release tag so it never /**
// drifts out of sync with what tagged-release.yml actually published. * Creates a direct link to an asset from the latest Stable release.
*
* If the GitHub API was unavailable during the build, the function deliberately
* returns the generic latest-release page instead of using a hard-coded and
* increasingly outdated fallback version.
*/
function createAssetUrl(latestTag, filenameTemplate) {
if (!latestTag) {
return LATEST_RELEASE_URL;
}
const filename = filenameTemplate.replace(/\{tag\}/g, latestTag);
return `https://github.com/${REPO}/releases/download/${latestTag}/${filename}`;
}
/**
* Builds the download list from the latest Stable GitHub release.
*
* The filenames must remain aligned with the artifacts produced by
* .github/workflows/tagged-release.yml.
*/
module.exports = async function () { module.exports = async function () {
const latestTag = await fetchLatestReleaseTag(); const latestTag = await fetchLatestReleaseTag();
const base = `https://github.com/${REPO}/releases/download/${latestTag}`; const assetUrl = (filenameTemplate) =>
createAssetUrl(latestTag, filenameTemplate);
return [ return [
{ {
@@ -33,80 +71,82 @@ module.exports = async function () {
format: "ZIP x64", format: "ZIP x64",
icon: "🪟", icon: "🪟",
recommended: true, recommended: true,
note: "Best choice for most Windows users.", note: "Extract the complete archive, then start praktiKST.exe. No separate Java installation is required.",
url: `${base}/praktiKST-${latestTag}-windows-x64.zip` url: assetUrl("praktiKST-{tag}-windows-x64.zip")
}, },
{ {
os: "Linux", os: "Linux",
format: "Flatpak (.flatpakref)", format: "Flatpak (.flatpakref)",
icon: "🐧", icon: "🐧",
recommended: true, recommended: true,
note: "Recommended for most Linux users. Open the file with GNOME Software / Discover, or run: flatpak install de.x08.KST4Contest.flatpakref", note: "Installs through Flatpak and can be updated through Flatpak or the desktop software centre.",
url: `${base}/de.x08.KST4Contest.flatpakref` url: assetUrl("de.x08.KST4Contest.flatpakref")
}, },
{ {
os: "Linux", os: "Linux",
format: "AppImage x86_64", format: "AppImage x86_64",
icon: "🐧", icon: "🐧",
recommended: false, recommended: false,
note: "Portable Linux build without package installation.", note: "Portable build without package installation. Make the downloaded file executable before the first launch.",
url: `${base}/KST4Contest-${latestTag}-linux-x86_64.AppImage` url: assetUrl("KST4Contest-{tag}-linux-x86_64.AppImage")
}, },
{ {
os: "Debian / Ubuntu", os: "Debian / Ubuntu",
format: "DEB amd64", format: "DEB amd64",
icon: "📦", icon: "📦",
recommended: false, recommended: false,
note: "Native package for Debian and Ubuntu based systems.", note: "Native package for Debian, Ubuntu and distributions based on them.",
url: `${base}/KST4Contest-${latestTag}-debian-amd64.deb` url: assetUrl("KST4Contest-{tag}-debian-amd64.deb")
}, },
{ {
os: "Fedora", os: "Fedora",
format: "RPM x86_64", format: "RPM x86_64",
icon: "📦", icon: "📦",
recommended: false, recommended: false,
note: "Native package for Fedora/RPM based systems.", note: "Native package built for Fedora and compatible RPM-based systems.",
url: `${base}/KST4Contest-${latestTag}-fedora-x86_64.rpm` url: assetUrl("KST4Contest-{tag}-fedora-x86_64.rpm")
}, },
{ {
os: "Arch Linux", os: "Arch Linux",
format: "pkg.tar.zst", format: "pkg.tar.zst",
icon: "📦", icon: "📦",
recommended: false, recommended: false,
note: "Package build for Arch Linux users.", note: "Release package for direct installation with pacman. AUR alternatives are described in the installation guide.",
url: `${base}/KST4Contest-${latestTag}-archlinux-x86_64.pkg.tar.zst` url: assetUrl(
"KST4Contest-{tag}-archlinux-x86_64.pkg.tar.zst"
)
}, },
{ {
os: "macOS Apple Silicon", os: "macOS Apple Silicon",
format: "DMG arm64", format: "DMG arm64",
icon: "🍎", icon: "🍎",
recommended: false, recommended: false,
note: "For Apple Silicon Macs.", note: "Best-effort build for Apple Silicon Macs. The application is not currently notarized by Apple.",
url: `${base}/KST4Contest-${latestTag}-macos-arm64.dmg` url: assetUrl("KST4Contest-{tag}-macos-arm64.dmg")
}, },
{ {
os: "macOS Intel", os: "macOS Intel",
format: "DMG x86_64", format: "DMG x86_64",
icon: "🍎", icon: "🍎",
recommended: false, recommended: false,
note: "For Intel-based Macs.", note: "Best-effort build for Intel Macs. The application is not currently notarized by Apple.",
url: `${base}/KST4Contest-${latestTag}-macos-x86_64.dmg` url: assetUrl("KST4Contest-{tag}-macos-x86_64.dmg")
}, },
{ {
os: "Manual English", os: "Manual English",
format: "PDF", format: "PDF",
icon: "📘", icon: "📘",
recommended: false, recommended: false,
note: "English PDF manual.", note: "English PDF manual included with the Stable release.",
url: `${base}/KST4Contest-${latestTag}-manual-en.pdf` url: assetUrl("KST4Contest-{tag}-manual-en.pdf")
}, },
{ {
os: "Manual German", os: "Manual German",
format: "PDF", format: "PDF",
icon: "📘", icon: "📘",
recommended: false, recommended: false,
note: "German PDF manual.", note: "German PDF manual included with the Stable release.",
url: `${base}/KST4Contest-${latestTag}-manual-de.pdf` url: assetUrl("KST4Contest-{tag}-manual-de.pdf")
} }
]; ];
}; };
+30 -37
View File
@@ -1,14 +1,15 @@
--- ---
layout: base.njk layout: base.njk
title: Download KST4Contest title: Download KST4Contest
description: Download KST4Contest releases for Windows, Linux and macOS. description: Download the latest stable KST4Contest packages for Windows, Linux and macOS. The required Java runtime is included.
--- ---
<section class="hero"> <section class="hero">
<p class="badge">Download</p> <p class="badge">Stable release</p>
<h1>Get KST4Contest</h1> <h1>Download KST4Contest</h1>
<p class="lead"> <p class="lead">
Choose the package for your operating system. Official builds are published through GitHub Releases. Choose the package for your operating system. Official builds are published through GitHub Releases,
and the required Java runtime is already included.
</p> </p>
<div class="actions"> <div class="actions">
@@ -19,8 +20,8 @@ description: Download KST4Contest releases for Windows, Linux and macOS.
<section class="section"> <section class="section">
<div class="section-heading"> <div class="section-heading">
<p class="eyebrow">Recommended downloads</p> <p class="eyebrow">Packages by platform</p>
<h2>Pick your platform</h2> <h2>Choose the format that fits your system</h2>
</div> </div>
<div class="grid"> <div class="grid">
@@ -29,7 +30,7 @@ description: Download KST4Contest releases for Windows, Linux and macOS.
<div class="feature-icon">{{ item.icon }}</div> <div class="feature-icon">{{ item.icon }}</div>
{% if item.recommended %} {% if item.recommended %}
<p class="badge">Recommended</p> <p class="badge">Default choice</p>
{% endif %} {% endif %}
<h3>{{ item.os }}</h3> <h3>{{ item.os }}</h3>
@@ -44,44 +45,36 @@ description: Download KST4Contest releases for Windows, Linux and macOS.
<section class="section"> <section class="section">
<div class="cta-panel"> <div class="cta-panel">
<p class="eyebrow">Not sure?</p> <p class="eyebrow">Choosing a package</p>
<h2>Which file should I use?</h2> <h2>Which file should I use?</h2>
<p> <p>
Windows users usually want the ZIP package. Linux users are best served by the Flatpak, Windows users normally need the x64 ZIP package. On Linux, Flatpak is the practical choice when
which auto-updates and works across distributions; the AppImage or a native DEB/RPM/Arch updates should be managed through the desktop software centre or the Flatpak command line. The
package are alternatives if preferred. The PDF manuals are attached to the same GitHub release. AppImage is useful when a portable file is preferred, while DEB, RPM and Arch packages integrate
with their respective package managers.
</p>
<p>
macOS packages are provided for Apple Silicon and Intel systems on a best-effort basis. They are
not currently notarized by Apple. The installation guide covers the first launch, updates, the
Stable, Beta and Nightly channels, and the location of the settings directory.
</p> </p>
<div class="actions"> <div class="actions">
<a class="button" href="/manual/en/installation/">Installation guide</a> <a class="button" href="/manual/en/installation/">Read the installation guide</a>
<a class="button secondary" href="/faq/">FAQ</a> <a class="button secondary" href="/faq/">Open the FAQ</a>
</div> </div>
</div> </div>
</section> </section>
<section class="section"> <section class="section">
<div class="card content-card">
<div class="card content-card"> <h2>Development and infrastructure</h2>
<p>
<h2>Enjoying KST4Contest?</h2> KST4Contest is developed independently. If it is useful in your contest workflow and you want to
help cover continued development, testing and infrastructure costs, the support page explains
<p> what project contributions are used for.
</p>
If KST4Contest makes contesting easier for you, <div class="actions">
please consider supporting future development. <a class="button" href="/support/">Support the project</a>
</p>
<div class="actions">
<a class="button"
href="/support/">
❤️ Support Development
</a>
</div>
</div> </div>
</div>
</section> </section>