splux-site · log · files · refs · tags · releases · people · languages · GitHub · commit
bc6be95
Fill the news page from GitHub releases and git history
Parents
Stat
.github/workflows/pages.yml | 14 +++++- README.md | 27 +++++++++-- site/assets/style.css | 39 ++++++++++++++++ site/index.html | 8 ++++ site/news/index.html | 12 +++-- tools/build-site.sh | 76 ++++++++++++++++++++++++++----- tools/collect-news.sh | 88 ++++++++++++++++++++++++++++++++++++ tools/news.awk | 108 ++++++++++++++++++++++++++++++++++++++++++++ tools/subst.awk | 23 ++++++++++ 9 files changed, 374 insertions(+), 21 deletions(-)
Diff
diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
index 217703b..82557d3 100644
--- a/.github/workflows/pages.yml
+++ b/.github/workflows/pages.yml
@@ -4,8 +4,10 @@ on:
push:
branches: [main]
schedule:
- - cron: "17 * * * *"
+ - cron: "7,27,47 * * * *"
workflow_dispatch:
+ repository_dispatch:
+ types: [rebuild]
permissions:
contents: read
@@ -21,19 +23,29 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
+ with:
+ fetch-depth: 25
- uses: actions/checkout@v4
with:
repository: RobertFlexx/sps-core
path: vendor/core
+ fetch-depth: 25
- uses: actions/checkout@v4
with:
repository: RobertFlexx/sps-extra
path: vendor/extra
+ fetch-depth: 25
+ - uses: actions/checkout@v4
+ with:
+ repository: RobertFlexx/SPS
+ path: vendor/sps
+ fetch-depth: 25
- name: Build site
env:
GH_TOKEN: ${{ github.token }}
CORE: vendor/core
EXTRA: vendor/extra
+ SPS: vendor/sps
SITE_PREFIX: ""
run: sh tools/build-site.sh
- uses: actions/upload-pages-artifact@v3
diff --git a/README.md b/README.md
index 0e4e0ad..2928e8e 100644
--- a/README.md
+++ b/README.md
@@ -7,12 +7,11 @@ This site was fully handmade by RobertFlexx.
## Build
```sh
-CORE=/tmp/sps-core EXTRA=/tmp/sps-extra ./tools/build-site.sh
+CORE=/tmp/sps-core EXTRA=/tmp/sps-extra SPS=/path/to/SPS ./tools/build-site.sh
```
-If `CORE` and `EXTRA` are unset, the script clones
-`https://github.com/RobertFlexx/sps-core` and
-`https://github.com/RobertFlexx/sps-extra` into `vendor/`.
+If `CORE`, `EXTRA`, or `SPS` are unset, the script clones
+`sps-core`, `sps-extra`, and `SPS` into `vendor/`.
Output is `_site/`. Preview:
@@ -33,9 +32,27 @@ ISO names are stable:
The visible tag name is filled at build time from the GitHub Releases API.
+## News
+
+`news/` is generated at build time from GitHub, not edited by hand:
+
+- SPS live ISO releases (`RobertFlexx/SPS` GitHub Releases)
+- recent commits on SPS, sps-core, sps-extra, and this repository
+
+The Pages workflow rebuilds about every twenty minutes, and also on
+push and `workflow_dispatch`. A new ISO tag shows up here without
+committing to splux-site. Atom feed: `/news/atom.xml`.
+
+To rebuild immediately from another repository, send a
+`repository_dispatch` of type `rebuild` to `RobertFlexx/splux-site`.
+SPS does that after a live ISO release when the `SPLUX_SITE_TOKEN`
+secret is set (a PAT that can dispatch workflows on this repo).
+Without that secret, the schedule still picks releases up.
+
## GitHub Pages
-The workflow rebuilds the package index on a schedule and on push to `main`.
+The workflow rebuilds the package index and news feed on a schedule
+and on push to `main`.
The custom domain is `https://splux.robertflexx.dev`. Point a DNS CNAME
for `splux` at `robertflexx.github.io`, then GitHub Pages serves this
repository there. `SITE_PREFIX` stays empty so links are rooted at `/`.
diff --git a/site/assets/style.css b/site/assets/style.css
index bdac5fc..ed5878f 100644
--- a/site/assets/style.css
+++ b/site/assets/style.css
@@ -252,6 +252,45 @@ footer p {
margin: 0.2rem 0;
}
+.feed {
+ margin: 0.75rem 0 0;
+}
+
+.feed .item {
+ margin: 0 0 1rem;
+ padding: 0 0 1rem;
+ border-bottom: 1px solid var(--rule);
+}
+
+.feed .item:last-child {
+ border-bottom: 0;
+}
+
+.feed .item h3 {
+ margin: 0.15rem 0 0;
+ font-size: 1rem;
+ font-weight: 700;
+}
+
+.feed .meta {
+ color: var(--muted);
+ margin: 0;
+ font-size: 0.9rem;
+}
+
+.feed .kind {
+ color: var(--accent);
+}
+
+.feed .summary {
+ margin: 0.35rem 0 0;
+ color: var(--fg);
+}
+
+.info {
+ margin: 0.75rem 0 1.25rem;
+}
+
.dl-row {
display: grid;
grid-template-columns: 12rem 1fr;
diff --git a/site/index.html b/site/index.html
index 11e27dd..dbb4a4b 100644
--- a/site/index.html
+++ b/site/index.html
@@ -10,6 +10,7 @@
<meta property="og:image" content="../../../../assets/sps.png">
<link rel="icon" href="../../../../assets/favicon.png" type="image/png">
<link rel="stylesheet" href="../../../../assets/style.css">
+<link rel="alternate" type="application/atom+xml" href="../../../../news/atom.xml" title="Splux Linux news">
</head>
<body>
<a class="skip" href="#main">Skip to content</a>
@@ -98,6 +99,13 @@ this website
<hr class="rule">
<p>Splux is under active development. SPS 1.0 is usable and the official package repositories are being built out. Live images exist so the installer can be tested. Splux is not a stable release yet.</p>
+<h2 id="news"><span class="num">[008]</span> News</h2>
+<hr class="rule">
+@@NEWS_INFO@@
+@@NEWS_BRIEF@@
+<p><a href="../../../../news/">Full news feed</a> · <a href="../../../../news/atom.xml">Atom</a></p>
+<p class="note">The feed is generated from GitHub when this site builds. New ISO releases and git commits appear here without a manual site edit.</p>
+
</main>
@@FOOTER@@
</div>
diff --git a/site/news/index.html b/site/news/index.html
index 9d5356b..bbea957 100644
--- a/site/news/index.html
+++ b/site/news/index.html
@@ -4,9 +4,10 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>News - Splux Linux</title>
-<meta name="description" content="Splux Linux news.">
+<meta name="description" content="Splux Linux news from ISO releases and git history.">
<link rel="icon" href="../../../../assets/favicon.png" type="image/png">
<link rel="stylesheet" href="../../../../assets/style.css">
+<link rel="alternate" type="application/atom+xml" href="../../../../news/atom.xml" title="Splux Linux news">
</head>
<body>
<a class="skip" href="#main">Skip to content</a>
@@ -15,9 +16,12 @@
<main id="main">
<h2>News</h2>
<hr class="rule">
-<p>2026-08-31 Website brought online.</p>
-<p>2026-08-31 Live ISO snapshots published from <a href="https://github.com/RobertFlexx/SPS/releases">SPS releases</a>.</p>
-<p>Release notes stay on GitHub rather than being copied here.</p>
+<p>This page is filled from GitHub when the site builds: SPS live ISO releases, plus recent commits on SPS, sps-core, sps-extra, and this website. Nobody has to edit it for a new snapshot or commit to show up.</p>
+<p class="note">The Pages workflow rebuilds on a schedule and on push. <a href="../../../../news/atom.xml">Atom feed</a>.</p>
+@@NEWS_INFO@@
+<h2>Feed</h2>
+<hr class="rule">
+@@NEWS@@
</main>
@@FOOTER@@
</div>
diff --git a/tools/build-site.sh b/tools/build-site.sh
index ce8b413..a64ddab 100755
--- a/tools/build-site.sh
+++ b/tools/build-site.sh
@@ -9,24 +9,38 @@ cd "$(CDPATH= cd -P "$(dirname "$0")/.." && pwd)" || exit 1
CORE=${CORE:-vendor/core}
EXTRA=${EXTRA:-vendor/extra}
+SPS=${SPS:-vendor/sps}
+SITE=${SITE:-.}
OUT=${OUT:-_site}
SITE_PREFIX=${SITE_PREFIX-}
CORE_GIT=${CORE_GIT:-https://github.com/RobertFlexx/sps-core}
EXTRA_GIT=${EXTRA_GIT:-https://github.com/RobertFlexx/sps-extra}
SPS_GIT=${SPS_GIT:-https://github.com/RobertFlexx/SPS}
+SITE_URL=${SITE_URL:-https://splux.robertflexx.dev}
-if [ ! -d "$CORE" ] || [ ! -d "$EXTRA" ]; then
- mkdir -p vendor
- if [ ! -d "$CORE" ]; then
- printf '%s\n' "cloning sps-core" >&2
- git clone --depth 1 "$CORE_GIT.git" vendor/core
- CORE=vendor/core
- fi
- if [ ! -d "$EXTRA" ]; then
- printf '%s\n' "cloning sps-extra" >&2
- git clone --depth 1 "$EXTRA_GIT.git" vendor/extra
- EXTRA=vendor/extra
+clone_tree() {
+ url=$1
+ dest=$2
+ depth=${3:-25}
+ if [ -d "$dest" ]; then
+ return 0
fi
+ mkdir -p vendor
+ printf '%s\n' "cloning $url" >&2
+ git clone --depth "$depth" "$url" "$dest"
+}
+
+if [ ! -d "$CORE" ]; then
+ clone_tree "$CORE_GIT.git" vendor/core 25
+ CORE=vendor/core
+fi
+if [ ! -d "$EXTRA" ]; then
+ clone_tree "$EXTRA_GIT.git" vendor/extra 25
+ EXTRA=vendor/extra
+fi
+if [ ! -d "$SPS" ]; then
+ clone_tree "$SPS_GIT.git" vendor/sps 25
+ SPS=vendor/sps
fi
rm -rf "$OUT"
@@ -168,6 +182,40 @@ generated=$(date -u '+%Y-%m-%d %H:%M UTC' 2>/dev/null || date)
printf '%s\n' "{\"tag\":\"$tag\",\"date\":\"$date\",\"iso_tty\":\"$SPS_GIT/releases/latest/download/sps-live-tty.iso\"}" \
>"$OUT/data/release.json"
+short_sha() {
+ git -C "$1" rev-parse --short HEAD 2>/dev/null || printf '%s\n' unknown
+}
+
+export CORE EXTRA SPS SITE
+if ! sh tools/collect-news.sh >"$tmp/news.tsv"
+then
+ printf '%s\n' "warning: news collection failed" >&2
+ : >"$tmp/news.tsv"
+fi
+awk -f tools/news.awk -v mode=html "$tmp/news.tsv" >"$tmp/news.html"
+awk -f tools/news.awk -v mode=brief "$tmp/news.tsv" >"$tmp/news-brief.html"
+generated_iso=$(date -u '+%Y-%m-%dT%H:%M:%SZ' 2>/dev/null || date -u '+%Y-%m-%dT00:00:00Z')
+awk -f tools/news.awk -v mode=atom -v siteurl="$SITE_URL" \
+ -v feedupdated="$generated_iso" \
+ "$tmp/news.tsv" >"$OUT/news/atom.xml"
+cp "$tmp/news.tsv" "$OUT/data/news.tsv"
+
+sps_sha=$(short_sha "$SPS")
+core_sha=$(short_sha "$CORE")
+extra_sha=$(short_sha "$EXTRA")
+site_sha=$(short_sha "$SITE")
+
+cat >"$tmp/news-info.html" <<EOF
+<div class="info">
+<div class="dl-row"><span class="muted">Latest ISO</span><span><a href="$SPS_GIT/releases/latest">$tag</a> ($date)</span></div>
+<div class="dl-row"><span class="muted">SPS</span><span><a href="$SPS_GIT/commit/$sps_sha">$sps_sha</a></span></div>
+<div class="dl-row"><span class="muted">sps-core</span><span><a href="$CORE_GIT/commit/$core_sha">$core_sha</a></span></div>
+<div class="dl-row"><span class="muted">sps-extra</span><span><a href="$EXTRA_GIT/commit/$extra_sha">$extra_sha</a></span></div>
+<div class="dl-row"><span class="muted">Packages</span><span>$npkgs ($ncore core, $nextra extra)</span></div>
+<div class="dl-row"><span class="muted">Site build</span><span>$generated ($site_sha)</span></div>
+</div>
+EOF
+
subst() {
src=$1
dest=$2
@@ -179,6 +227,9 @@ subst() {
-v headerfile="$tmp/header.html" \
-v footerfile="$tmp/footer.html" \
-v rowsfile="$tmp/rows.html" \
+ -v newsfile="$tmp/news.html" \
+ -v brieffile="$tmp/news-brief.html" \
+ -v infofile="$tmp/news-info.html" \
-v root="$root" \
-v tag="$tag" \
-v date="$date" \
@@ -237,6 +288,9 @@ do
-v headerfile="$tmp/h2.html" \
-v footerfile="$tmp/f2.html" \
-v rowsfile="" \
+ -v newsfile="" \
+ -v brieffile="" \
+ -v infofile="" \
-v root="$root" \
-v tag="$tag" \
-v date="$date" \
diff --git a/tools/collect-news.sh b/tools/collect-news.sh
new file mode 100644
index 0000000..f911828
--- /dev/null
+++ b/tools/collect-news.sh
@@ -0,0 +1,88 @@
+#!/bin/sh
+# Collect Splux releases and git history into TSV for the news page.
+# Fields: epoch iso kind repo url title summary
+# Env: CORE EXTRA SPS SITE (git work trees). GH_TOKEN optional via gh.
+
+set -eu
+
+CORE=${CORE:-vendor/core}
+EXTRA=${EXTRA:-vendor/extra}
+SPS=${SPS:-vendor/sps}
+SITE=${SITE:-.}
+
+tab=$(printf '\t')
+out=$(mktemp "${TMPDIR:-/tmp}/splux-news.XXXXXX") || exit 1
+trap 'rm -f "$out" "$rel"' 0 HUP INT TERM
+rel=
+
+emit() {
+ epoch=$1
+ iso=$2
+ kind=$3
+ repo=$4
+ url=$5
+ title=$6
+ summary=${7-}
+ title=$(printf '%s' "$title" | tr '\t\r\n' ' ')
+ summary=$(printf '%s' "$summary" | tr '\t\r\n' ' ')
+ printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \
+ "$epoch" "$iso" "$kind" "$repo" "$url" "$title" "$summary" >>"$out"
+}
+
+epoch_of() {
+ iso=$1
+ day=${iso%%T*}
+ if date -u -d "$iso" +%s >/dev/null 2>&1; then
+ date -u -d "$iso" +%s
+ return 0
+ fi
+ awk -v d="$day" 'BEGIN {
+ n = split(d, a, "-")
+ if (n != 3) { print 0; exit }
+ print mktime(a[1] " " a[2] " " a[3] " 12 0 0") + 0
+ }'
+}
+
+git_commits() {
+ dir=$1
+ repo=$2
+ baseurl=$3
+ n=${4:-12}
+ git -C "$dir" rev-parse --is-inside-work-tree >/dev/null 2>&1 || return 0
+ git -C "$dir" log -n "$n" --format='%ct%x09%cI%x09%H%x09%s' 2>/dev/null |
+ while IFS=$tab read -r epoch iso hash subject || [ -n "${epoch-}" ]
+ do
+ [ -n "${epoch-}" ] || continue
+ [ -n "${iso-}" ] || continue
+ [ -n "${hash-}" ] || continue
+ emit "$epoch" "$iso" commit "$repo" \
+ "$baseurl/commit/$hash" "$subject" ""
+ done
+}
+
+git_commits "$SPS" SPS https://github.com/RobertFlexx/SPS 15
+git_commits "$CORE" sps-core https://github.com/RobertFlexx/sps-core 15
+git_commits "$EXTRA" sps-extra https://github.com/RobertFlexx/sps-extra 15
+git_commits "$SITE" splux-site https://github.com/RobertFlexx/splux-site 8
+
+if command -v gh >/dev/null 2>&1; then
+ rel=$(mktemp "${TMPDIR:-/tmp}/splux-rel.XXXXXX") || exit 1
+ if gh api "repos/RobertFlexx/SPS/releases?per_page=25" --jq \
+ '.[] | select(.draft == false) | [
+ .published_at,
+ .html_url,
+ (.name // .tag_name),
+ ((.body // "") | gsub("[\r\t]"; " ") | gsub("\n+"; " ") | .[0:900])
+ ] | @tsv' >"$rel" 2>/dev/null
+ then
+ while IFS=$tab read -r published url name body || [ -n "${published-}" ]
+ do
+ [ -n "${published-}" ] || continue
+ [ -n "${url-}" ] || continue
+ epoch=$(epoch_of "$published")
+ emit "$epoch" "$published" release SPS "$url" "$name" "$body"
+ done <"$rel"
+ fi
+fi
+
+LC_ALL=C sort -t "$tab" -k1,1nr "$out"
diff --git a/tools/news.awk b/tools/news.awk
new file mode 100644
index 0000000..fcbff6f
--- /dev/null
+++ b/tools/news.awk
@@ -0,0 +1,108 @@
+# Turn collect-news.sh TSV into HTML or Atom.
+# Fields: epoch iso kind repo url title summary
+# -v mode=html|brief|atom -v siteurl= -v feedupdated=
+
+BEGIN {
+ FS = "\t"
+ if (mode == "")
+ mode = "html"
+ if (siteurl == "")
+ siteurl = "https://splux.robertflexx.dev"
+ html_limit = (mode == "brief") ? 8 : 60
+ atom_limit = 40
+}
+
+function esc(s) {
+ gsub(/&/, "\\&", s)
+ gsub(/</, "\\<", s)
+ gsub(/>/, "\\>", s)
+ gsub(/"/, "\\"", s)
+ return s
+}
+
+function day_of(iso, d) {
+ d = iso
+ sub(/T.*/, "", d)
+ return d
+}
+
+function kind_label(k) {
+ if (k == "release")
+ return "release"
+ return "commit"
+}
+
+{
+ n++
+ epoch[n] = $1
+ iso[n] = $2
+ kind[n] = $3
+ repo[n] = $4
+ url[n] = $5
+ title[n] = $6
+ summary[n] = $7
+}
+
+END {
+ if (mode == "atom") {
+ print_atom()
+ exit
+ }
+ if (n == 0) {
+ print "<p class=\"note\">No GitHub events were available when this page was built.</p>"
+ exit
+ }
+ print "<div class=\"feed\">"
+ limit = html_limit
+ if (n < limit)
+ limit = n
+ for (i = 1; i <= limit; i++) {
+ print_item(i, mode == "brief")
+ }
+ print "</div>"
+}
+
+function print_item(i, brief, k, when, s) {
+ when = esc(day_of(iso[i]))
+ k = esc(kind_label(kind[i]))
+ print "<article class=\"item\">"
+ printf "<p class=\"meta\"><time datetime=\"%s\">%s</time> <span class=\"kind\">%s</span> %s</p>\n", \
+ esc(iso[i]), when, k, esc(repo[i])
+ printf "<h3><a href=\"%s\">%s</a></h3>\n", esc(url[i]), esc(title[i])
+ if (!brief) {
+ s = summary[i]
+ if (s != "")
+ printf "<p class=\"summary\">%s</p>\n", esc(s)
+ }
+ print "</article>"
+}
+
+function print_atom( i, limit, updated, id) {
+ updated = feedupdated
+ if (updated == "" && n > 0)
+ updated = iso[1]
+ if (updated == "")
+ updated = "1970-01-01T00:00:00Z"
+ print "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ print "<feed xmlns=\"http://www.w3.org/2005/Atom\">"
+ print "<title>Splux Linux news</title>"
+ printf "<link rel=\"self\" href=\"%s/news/atom.xml\"/>\n", esc(siteurl)
+ printf "<link href=\"%s/news/\"/>\n", esc(siteurl)
+ printf "<updated>%s</updated>\n", esc(updated)
+ printf "<id>%s/news/</id>\n", esc(siteurl)
+ print "<author><name>RobertFlexx</name></author>"
+ limit = atom_limit
+ if (n < limit)
+ limit = n
+ for (i = 1; i <= limit; i++) {
+ print "<entry>"
+ printf "<title>%s</title>\n", esc(title[i])
+ printf "<link href=\"%s\"/>\n", esc(url[i])
+ printf "<id>%s</id>\n", esc(url[i])
+ printf "<updated>%s</updated>\n", esc(iso[i])
+ printf "<category term=\"%s\"/>\n", esc(kind[i])
+ printf "<summary>%s</summary>\n", esc(repo[i] ": " title[i])
+ print "</entry>"
+ }
+ print "</feed>"
+}
diff --git a/tools/subst.awk b/tools/subst.awk
index eab5188..0b49d9c 100644
--- a/tools/subst.awk
+++ b/tools/subst.awk
@@ -1,6 +1,14 @@
# Replace @@HEADER@@ / @@FOOTER@@ / ../../../../ and other tokens.
# headerfile, footerfile, root, rowsfile, and token variables are -v flags.
+function dump_file(path, line) {
+ if (path == "")
+ return
+ while ((getline line < path) > 0)
+ print line
+ close(path)
+}
+
BEGIN {
if (headerfile != "") {
while ((getline line < headerfile) > 0)
@@ -35,6 +43,21 @@ $0 == "@@PKG_ROWS@@" {
next
}
+$0 == "@@NEWS@@" {
+ dump_file(newsfile)
+ next
+}
+
+$0 == "@@NEWS_BRIEF@@" {
+ dump_file(brieffile)
+ next
+}
+
+$0 == "@@NEWS_INFO@@" {
+ dump_file(infofile)
+ next
+}
+
{
gsub(/../../../..//, root)
gsub(/live-2026-09-06-1/, tag)