The releases index already enumerated HTML tools by channel and
version. Add a parallel section for zddc-server with two artifact
families:
- Standalone binaries: a channel × platform table linking to
website/releases/zddc-server-{linux,darwin,windows}-{amd64,arm64}-<channel>
(the files release-image.sh now mirrors there). Empty cells render
as em-dashes; the table only renders when at least one binary
exists locally so freshly-cloned repos don't show a ghost section.
- Container images: pull-snippet, channel chips linking to the
codeberg package page, and a "Pin to version" row of historical
tags (clean stables first, recent pre-releases listed separately
with a "recent pre-releases:" label so the pre-release noise
doesn't drown out the stable list).
Recent pre-releases capped at 10 entries to keep the list scannable
as alpha cuts proliferate over time.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
331 lines
17 KiB
Bash
Executable file
331 lines
17 KiB
Bash
Executable file
#!/bin/sh
|
||
set -eu
|
||
|
||
# Top-level build script — builds all ZDDC HTML tools, the zddc-server
|
||
# binaries, and the bootstrap stubs published under website/bootstrap/.
|
||
|
||
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
|
||
|
||
echo "=== Building ZDDC tools ==="
|
||
|
||
sh "$SCRIPT_DIR/transmittal/build.sh" "${1:-}" "${2:-}"
|
||
sh "$SCRIPT_DIR/archive/build.sh" "${1:-}" "${2:-}"
|
||
sh "$SCRIPT_DIR/classifier/build.sh" "${1:-}" "${2:-}"
|
||
sh "$SCRIPT_DIR/mdedit/build.sh" "${1:-}" "${2:-}"
|
||
sh "$SCRIPT_DIR/landing/build.sh" "${1:-}" "${2:-}"
|
||
|
||
echo ""
|
||
echo "=== Assembling zddc/dist/web/ ==="
|
||
# Only landing and archive ship inside the server bundle: they call the
|
||
# server's JSON API (GET / for the project list, directory listings for the
|
||
# archive) and are useless without it. transmittal, classifier, and mdedit
|
||
# are pure client-side tools that work from file:// or any static host;
|
||
# they are released to website/ for download but not bundled with the server.
|
||
mkdir -p "$SCRIPT_DIR/zddc/dist/web"
|
||
cp "$SCRIPT_DIR/landing/dist/index.html" "$SCRIPT_DIR/zddc/dist/web/index.html"
|
||
cp "$SCRIPT_DIR/archive/dist/archive.html" "$SCRIPT_DIR/zddc/dist/web/archive.html"
|
||
echo "Wrote zddc/dist/web/index.html"
|
||
echo "Wrote zddc/dist/web/archive.html"
|
||
|
||
# Cross-compiled zddc-server binaries — only relevant if you're shipping
|
||
# standalone Linux/macOS/Windows binaries to users. Skipped silently when
|
||
# podman isn't on PATH; the runtime container release path
|
||
# (release-image.sh) does its own internal build via Containerfile's
|
||
# multi-stage flow and doesn't need these host-side binaries.
|
||
echo ""
|
||
echo "=== Building zddc-server binaries ==="
|
||
if command -v podman >/dev/null 2>&1; then
|
||
podman build --target binaries -o "$SCRIPT_DIR/zddc/dist/" "$SCRIPT_DIR/zddc/" 2>&1 | grep -v "^-->"
|
||
else
|
||
echo "podman not found — skipping cross-compiled binary build."
|
||
echo " (Standalone-binary distribution only; the runtime container"
|
||
echo " release path builds its own copy via Containerfile.)"
|
||
fi
|
||
|
||
# ─── Bootstrap stubs ─────────────────────────────────────────────────────────
|
||
# Generated from bootstrap/level{1,2}.html.tmpl on every build and published
|
||
# as standalone files under website/bootstrap/. The website's "Install on
|
||
# your server" section prints copy-pasteable shell snippets that curl these
|
||
# files into the operator's deployment directory.
|
||
#
|
||
# bootstrap/level1/<tool>.html — same-origin stubs for
|
||
# <project>/<tool>.html (4 tools;
|
||
# landing only lives at root)
|
||
# bootstrap/track-<channel>/<tool>.html — level-2 stubs that fetch the
|
||
# named channel from upstream
|
||
# (5 tools × 3 channels = 15)
|
||
|
||
WEBSITE_DIR="$SCRIPT_DIR/website"
|
||
RELEASES_DIR="$WEBSITE_DIR/releases"
|
||
BOOTSTRAP_DIR="$SCRIPT_DIR/bootstrap"
|
||
|
||
mkdir -p "$WEBSITE_DIR"
|
||
|
||
# tool|filename|title
|
||
TOOL_TABLE='archive|archive.html|Archive
|
||
transmittal|transmittal.html|Transmittal
|
||
classifier|classifier.html|Classifier
|
||
mdedit|mdedit.html|Markdown Editor
|
||
landing|index.html|ZDDC'
|
||
|
||
# Substitute {{TOOL}}, {{TOOL_TITLE}}, {{CHANNEL}}, {{FAVICON}} in a template.
|
||
# The favicon is a base64-encoded data URI built once from shared/favicon.svg.
|
||
_favicon_data_uri=""
|
||
if [ -f "$SCRIPT_DIR/shared/favicon.svg" ]; then
|
||
_favicon_data_uri="data:image/svg+xml;base64,$(base64 -w 0 "$SCRIPT_DIR/shared/favicon.svg")"
|
||
fi
|
||
render_stub() {
|
||
sed \
|
||
-e "s|{{TOOL_TITLE}}|$3|g" \
|
||
-e "s|{{TOOL}}|$2|g" \
|
||
-e "s|{{CHANNEL}}|${4:-}|g" \
|
||
-e "s|{{FAVICON}}|$_favicon_data_uri|g" \
|
||
"$1" > "$5"
|
||
}
|
||
|
||
build_bootstrap_stubs() {
|
||
_stubs="$WEBSITE_DIR/bootstrap"
|
||
rm -rf "$_stubs"
|
||
mkdir -p "$_stubs/level1"
|
||
|
||
# Level-1 stubs (same-origin, channel-agnostic). Drop into a project
|
||
# subdirectory so <project>/<tool>.html fetches ../<tool>.html.
|
||
# Landing has no level-1 stub — landing only lives at deployment root.
|
||
while IFS='|' read -r _tool _file _title; do
|
||
render_stub "$BOOTSTRAP_DIR/level1.html.tmpl" "$_tool" "$_title" "" \
|
||
"$_stubs/level1/$_file"
|
||
done <<EOF
|
||
archive|archive.html|Archive
|
||
transmittal|transmittal.html|Transmittal
|
||
classifier|classifier.html|Classifier
|
||
mdedit|mdedit.html|Markdown Editor
|
||
EOF
|
||
echo "Wrote $_stubs/level1/{archive,transmittal,classifier,mdedit}.html"
|
||
|
||
# Level-2 stubs, one set per channel. Each fetches its named channel
|
||
# from upstream on every page load.
|
||
for _channel in alpha beta stable; do
|
||
mkdir -p "$_stubs/track-$_channel"
|
||
while IFS='|' read -r _tool _file _title; do
|
||
render_stub "$BOOTSTRAP_DIR/level2.html.tmpl" "$_tool" "$_title" "$_channel" \
|
||
"$_stubs/track-$_channel/$_file"
|
||
done <<EOF
|
||
$TOOL_TABLE
|
||
EOF
|
||
echo "Wrote $_stubs/track-$_channel/ (5 stubs)"
|
||
done
|
||
}
|
||
|
||
# Regenerate website/releases/index.html — a static directory listing of
|
||
# all tool releases with channel rows + per-version archive links. Read
|
||
# from the filesystem so the page is always consistent with what's there.
|
||
build_releases_index() {
|
||
_out="$RELEASES_DIR/index.html"
|
||
{
|
||
cat <<'HEAD'
|
||
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>Releases — ZDDC</title>
|
||
<meta name="description" content="All released versions and channel builds of every ZDDC tool.">
|
||
<meta name="theme-color" content="#2a5a8a">
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||
<link rel="stylesheet" href="../css/style.css">
|
||
<style>
|
||
.rel-tool { margin-top: var(--spacing-xl); padding: var(--spacing-md); border: 1px solid var(--color-border); border-radius: 8px; }
|
||
.rel-tool h2 { margin-top: 0; }
|
||
.rel-channels { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.75rem 0 1.25rem 0; }
|
||
.rel-channels a { padding: 0.25rem 0.625rem; border-radius: 999px; text-decoration: none; border: 1px solid var(--color-border); color: var(--color-text); font-size: 0.9rem; }
|
||
.rel-channels a.stable { border-color: var(--color-primary); color: var(--color-primary); font-weight: 600; }
|
||
.rel-channels a.beta, .rel-channels a.alpha { color: var(--color-text-muted); }
|
||
.rel-channels a:hover { background: var(--color-bg-subtle); }
|
||
.rel-versions { font-size: 0.875rem; color: var(--color-text-muted); }
|
||
.rel-versions a { margin-right: 0.5rem; color: var(--color-text); text-decoration: none; padding: 0.1rem 0.4rem; border-radius: 4px; }
|
||
.rel-versions a:hover { background: var(--color-bg-subtle); text-decoration: underline; }
|
||
.rel-meta { font-size: 0.85rem; color: var(--color-text-muted); margin-top: 0.5rem; }
|
||
.rel-bin-table { width: 100%; border-collapse: collapse; margin: 0.5rem 0 1rem; font-size: 0.9rem; }
|
||
.rel-bin-table th, .rel-bin-table td { text-align: left; padding: 0.4rem 0.6rem; border-bottom: 1px solid var(--color-border); }
|
||
.rel-bin-table th { font-weight: 600; color: var(--color-text-muted); }
|
||
.rel-bin-table td.ch-stable { color: var(--color-primary); font-weight: 600; }
|
||
.rel-bin-table td.ch-beta, .rel-bin-table td.ch-alpha { color: var(--color-text-muted); }
|
||
.rel-bin-table a { color: var(--color-text); text-decoration: none; padding: 0.1rem 0.35rem; border-radius: 4px; }
|
||
.rel-bin-table a:hover { background: var(--color-bg-subtle); text-decoration: underline; }
|
||
.rel-bin-table td.empty { color: var(--color-text-muted); font-style: italic; }
|
||
.rel-pull { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.85rem; background: var(--color-bg-subtle); padding: 0.25rem 0.5rem; border-radius: 4px; display: inline-block; margin: 0.2rem 0; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<header class="site-header">
|
||
<div class="container header-content">
|
||
<a href="/" class="brand">
|
||
<div class="brand-logo">
|
||
<svg viewBox="0 0 24 24"><path d="M3 5h18v2H3V5zm0 6h12v2H3v-2zm0 6h6v2H3v-2z" /></svg>
|
||
</div>
|
||
<span class="brand-name">ZDDC</span>
|
||
</a>
|
||
<nav class="header-nav">
|
||
<a href="/" class="nav-link">Home</a>
|
||
<a href="../reference.html" class="nav-link">Docs</a>
|
||
<a href="index.html" class="nav-link active">Releases</a>
|
||
</nav>
|
||
</div>
|
||
</header>
|
||
|
||
<section class="hero">
|
||
<div class="container">
|
||
<h1>Releases</h1>
|
||
<p class="hero-subtitle">All published versions and channel builds of every ZDDC tool. Stable releases are immutable; alpha and beta channels are rebuilt without notice.</p>
|
||
</div>
|
||
</section>
|
||
|
||
<main class="container" style="margin-bottom: var(--spacing-2xl);">
|
||
HEAD
|
||
printf '%s\n' "$TOOL_TABLE" | while IFS='|' read -r _tool _file _title; do
|
||
_stable_target=""
|
||
if [ -L "$RELEASES_DIR/${_tool}_stable.html" ]; then
|
||
_stable_target=$(readlink "$RELEASES_DIR/${_tool}_stable.html")
|
||
fi
|
||
printf ' <section class="rel-tool">\n'
|
||
printf ' <h2>%s</h2>\n' "$_title"
|
||
printf ' <div class="rel-channels">\n'
|
||
[ -e "$RELEASES_DIR/${_tool}_stable.html" ] && printf ' <a class="stable" href="%s_stable.html">stable</a>\n' "$_tool"
|
||
[ -e "$RELEASES_DIR/${_tool}_beta.html" ] && printf ' <a class="beta" href="%s_beta.html">beta</a>\n' "$_tool"
|
||
[ -e "$RELEASES_DIR/${_tool}_alpha.html" ] && printf ' <a class="alpha" href="%s_alpha.html">alpha</a>\n' "$_tool"
|
||
printf ' </div>\n'
|
||
_versions=$(ls -1 "$RELEASES_DIR" 2>/dev/null | grep -E "^${_tool}_v[0-9]" | sort -V -r)
|
||
if [ -n "$_versions" ]; then
|
||
printf ' <div class="rel-versions"><strong>Pin to version:</strong>\n'
|
||
printf '%s\n' "$_versions" | while read -r _v; do
|
||
_ver=${_v#${_tool}_v}; _ver=${_ver%.html}
|
||
printf ' <a href="%s">v%s</a>\n' "$_v" "$_ver"
|
||
done
|
||
printf ' </div>\n'
|
||
fi
|
||
if [ -n "$_stable_target" ]; then
|
||
printf ' <div class="rel-meta">stable currently → %s</div>\n' "$_stable_target"
|
||
fi
|
||
printf ' </section>\n'
|
||
done
|
||
# zddc-server section — different artifact shape than the HTML tools.
|
||
# Two artifact families:
|
||
# 1. Downloadable binaries at website/releases/zddc-server-<os>-<arch>-<channel>
|
||
# (mutable channel pointers; release-image.sh writes them).
|
||
# 2. Container images at codeberg.org/varasys/zddc-server:<channel> and
|
||
# :<version> (the registry; we don't proxy them through the website,
|
||
# but we list the recent tags and a `podman pull` snippet for each).
|
||
printf ' <section class="rel-tool">\n'
|
||
printf ' <h2>zddc-server</h2>\n'
|
||
printf ' <p style="margin-top:0;color:var(--color-text-muted);font-size:0.95rem;">Go HTTP file server with ACL, .archive index, and a delegated-admin .zddc editor. Distributed as a container image (preferred) or a standalone binary.</p>\n'
|
||
|
||
# Binaries table.
|
||
_platforms="linux-amd64 darwin-amd64 darwin-arm64 windows-amd64"
|
||
_have_any_bin=0
|
||
for _ch in stable beta alpha; do
|
||
for _p in $_platforms; do
|
||
_ext=""; case "$_p" in windows-*) _ext=".exe" ;; esac
|
||
if [ -f "$RELEASES_DIR/zddc-server-${_p}-${_ch}${_ext}" ]; then
|
||
_have_any_bin=1; break 2
|
||
fi
|
||
done
|
||
done
|
||
if [ "$_have_any_bin" = "1" ]; then
|
||
printf ' <h3 style="font-size:1rem;margin:0.75rem 0 0.4rem;">Standalone binaries</h3>\n'
|
||
printf ' <table class="rel-bin-table"><thead><tr><th>Channel</th>'
|
||
for _p in $_platforms; do printf '<th>%s</th>' "$_p"; done
|
||
printf '</tr></thead><tbody>\n'
|
||
for _ch in stable beta alpha; do
|
||
printf ' <tr><td class="ch-%s">%s</td>' "$_ch" "$_ch"
|
||
for _p in $_platforms; do
|
||
_ext=""; case "$_p" in windows-*) _ext=".exe" ;; esac
|
||
_f="zddc-server-${_p}-${_ch}${_ext}"
|
||
if [ -f "$RELEASES_DIR/$_f" ]; then
|
||
printf '<td><a href="%s">download</a></td>' "$_f"
|
||
else
|
||
printf '<td class="empty">—</td>'
|
||
fi
|
||
done
|
||
printf '</tr>\n'
|
||
done
|
||
printf ' </tbody></table>\n'
|
||
fi
|
||
|
||
# Container image: pull-snippet box plus the recent git tag list.
|
||
printf ' <h3 style="font-size:1rem;margin:0.75rem 0 0.4rem;">Container image</h3>\n'
|
||
printf ' <p style="margin:0 0 0.4rem;font-size:0.9rem;">Pull from <a href="https://codeberg.org/VARASYS/-/packages/container/zddc-server">codeberg.org/varasys/zddc-server</a>:</p>\n'
|
||
printf ' <div class="rel-channels">\n'
|
||
printf ' <a class="stable" href="https://codeberg.org/VARASYS/-/packages/container/zddc-server/stable">:stable</a>\n'
|
||
printf ' <a class="beta" href="https://codeberg.org/VARASYS/-/packages/container/zddc-server/beta">:beta</a>\n'
|
||
printf ' <a class="alpha" href="https://codeberg.org/VARASYS/-/packages/container/zddc-server/alpha">:alpha</a>\n'
|
||
printf ' </div>\n'
|
||
printf ' <code class="rel-pull">podman pull codeberg.org/varasys/zddc-server:stable</code>\n'
|
||
|
||
# Recent zddc-server tags from git: clean stables first (top), then
|
||
# the most recent pre-releases. Dropping older pre-releases keeps the
|
||
# list readable since alpha/beta cuts proliferate.
|
||
_server_stables=$(git -C "$SCRIPT_DIR" tag --list 'zddc-server-v*' 2>/dev/null \
|
||
| grep -E '^zddc-server-v[0-9]+\.[0-9]+\.[0-9]+$' \
|
||
| sed 's|^zddc-server-v||' \
|
||
| sort -V -r)
|
||
_server_prereleases=$(git -C "$SCRIPT_DIR" tag --list 'zddc-server-v*' 2>/dev/null \
|
||
| grep -E '^zddc-server-v[0-9]+\.[0-9]+\.[0-9]+-' \
|
||
| sed 's|^zddc-server-v||' \
|
||
| sort -V -r \
|
||
| head -10)
|
||
if [ -n "$_server_stables" ] || [ -n "$_server_prereleases" ]; then
|
||
printf ' <div class="rel-versions" style="margin-top:0.6rem;"><strong>Pin to version:</strong>\n'
|
||
printf '%s\n' "$_server_stables" | while read -r _v; do
|
||
[ -n "$_v" ] || continue
|
||
printf ' <a href="https://codeberg.org/VARASYS/-/packages/container/zddc-server/%s">v%s</a>\n' "$_v" "$_v"
|
||
done
|
||
if [ -n "$_server_prereleases" ]; then
|
||
printf ' <span style="color:var(--color-text-muted);">recent pre-releases:</span>\n'
|
||
printf '%s\n' "$_server_prereleases" | while read -r _v; do
|
||
[ -n "$_v" ] || continue
|
||
printf ' <a href="https://codeberg.org/VARASYS/-/packages/container/zddc-server/%s">v%s</a>\n' "$_v" "$_v"
|
||
done
|
||
fi
|
||
printf ' </div>\n'
|
||
fi
|
||
printf ' </section>\n'
|
||
|
||
cat <<'TAIL'
|
||
|
||
<section style="margin-top: var(--spacing-2xl); color: var(--color-text-muted); font-size: 0.9rem;">
|
||
<p>Append <code>?v=alpha</code>, <code>?v=beta</code>, <code>?v=stable</code>, or <code>?v=0.0.1</code> to any deployment URL to switch versions for a single request — see <a href="../">the home page</a>.</p>
|
||
</section>
|
||
</main>
|
||
|
||
<footer class="site-footer">
|
||
<div class="container footer-content">
|
||
<span>ZDDC is open source — <a href="https://codeberg.org/VARASYS/ZDDC">codeberg.org/VARASYS/ZDDC</a></span>
|
||
</div>
|
||
</footer>
|
||
</body>
|
||
</html>
|
||
TAIL
|
||
} > "$_out"
|
||
echo "Wrote $_out"
|
||
}
|
||
|
||
echo ""
|
||
echo "=== Building bootstrap stubs and releases/index.html ==="
|
||
build_bootstrap_stubs
|
||
build_releases_index
|
||
|
||
echo ""
|
||
echo "=== All tools built successfully ==="
|
||
echo ""
|
||
echo "Server deployment package: zddc/dist/"
|
||
echo " Binaries: zddc-server-{linux,darwin,windows}-*"
|
||
echo " Web files: web/ (copy contents to ZDDC_ROOT)"
|
||
echo ""
|
||
echo "Bootstrap stubs: website/bootstrap/"
|
||
echo " level1/<tool>.html — same-origin stubs for project subdirs"
|
||
echo " track-{alpha,beta,stable}/ — level-2 stubs for each channel"
|
||
echo ""
|
||
echo "The home page's 'Install on your server' section prints copy-pasteable"
|
||
echo "shell snippets that curl these files into the operator's deployment dir."
|