Bundles a stretch of in-progress work across the SPA tools so the
tree returns to a coherent shippable state ahead of cutting a new
zddc-server stable image:
- landing: substantial rework of the project picker (sortable/filterable
table, presets refactor, ?projects= filter, ?v= channel propagation,
loading/error states)
- archive: presets cleanup, source.js refactor, filtering/url-state
alignment with the landing page
- mdedit: file-system module split, resizer, file-tree improvements,
base/toc styling tweaks
- transmittal/classifier: small template touch-ups for shared chrome
- shared: build-lib.sh helpers, new favicon.svg
- bootstrap, build.sh: pick up the channel-aware install/track zip
generation
- tests: new landing.spec.js, expanded archive/mdedit/build-label specs
- docs: CLAUDE.md picks up the zddc-server section and freshens the
alpha-build exception note
- regenerated artifacts: install.zip, track-{alpha,beta,stable}.zip,
*_alpha.html — these are produced by `sh build.sh` and per project
convention are committed alongside the source changes
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
267 lines
11 KiB
Bash
Executable file
267 lines
11 KiB
Bash
Executable file
#!/bin/sh
|
|
set -eu
|
|
|
|
# Top-level build script — builds all ZDDC HTML tools, the zddc-server
|
|
# binaries, and the downloadable bundles (install.zip and track-*.zip).
|
|
|
|
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 zips ──────────────────────────────────────────────────────────
|
|
# Generated from bootstrap/level{1,2}.html.tmpl on every build so they are
|
|
# always in sync with the current bootstrap pattern.
|
|
#
|
|
# install.zip — drop into deployment root for self-contained install.
|
|
# Contains the 5 current-stable HTMLs at root plus a
|
|
# _template/ directory with 4 level-1 stubs that
|
|
# projects can use as their starting layout.
|
|
# track-<channel>.zip — drop the level-2 stubs over deployment root to make
|
|
# the whole site track <channel> from zddc.varasys.io.
|
|
#
|
|
# install.zip needs at least one stable release to exist under
|
|
# website/releases/; if none exist yet, that zip is skipped with a warning.
|
|
|
|
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_install_zip() {
|
|
# Verify a stable release exists for every tool before staging.
|
|
_missing=""
|
|
while IFS='|' read -r _tool _file _title; do
|
|
[ -e "$RELEASES_DIR/${_tool}_stable.html" ] || _missing="$_missing $_tool"
|
|
done <<EOF
|
|
$TOOL_TABLE
|
|
EOF
|
|
|
|
if [ -n "$_missing" ]; then
|
|
echo "Skipping install.zip — no stable release for:$_missing"
|
|
return 0
|
|
fi
|
|
|
|
_staging=$(mktemp -d)
|
|
while IFS='|' read -r _tool _file _title; do
|
|
cp "$RELEASES_DIR/${_tool}_stable.html" "$_staging/$_file"
|
|
done <<EOF
|
|
$TOOL_TABLE
|
|
EOF
|
|
|
|
# _template/ holds level-1 bootstraps for the four interactive tools
|
|
# (landing only lives at deployment root; project directories do not
|
|
# have their own landing page).
|
|
mkdir -p "$_staging/_template"
|
|
while IFS='|' read -r _tool _file _title; do
|
|
render_stub "$BOOTSTRAP_DIR/level1.html.tmpl" "$_tool" "$_title" "" "$_staging/_template/$_file"
|
|
done <<EOF
|
|
archive|archive.html|Archive
|
|
transmittal|transmittal.html|Transmittal
|
|
classifier|classifier.html|Classifier
|
|
mdedit|mdedit.html|Markdown Editor
|
|
EOF
|
|
|
|
cp "$BOOTSTRAP_DIR/README.md" "$_staging/README.md"
|
|
|
|
rm -f "$WEBSITE_DIR/install.zip"
|
|
(cd "$_staging" && zip -qr "$WEBSITE_DIR/install.zip" .)
|
|
echo "Wrote $WEBSITE_DIR/install.zip"
|
|
rm -rf "$_staging"
|
|
}
|
|
|
|
build_track_zip() {
|
|
_channel="$1"
|
|
_staging=$(mktemp -d)
|
|
while IFS='|' read -r _tool _file _title; do
|
|
render_stub "$BOOTSTRAP_DIR/level2.html.tmpl" "$_tool" "$_title" "$_channel" "$_staging/$_file"
|
|
done <<EOF
|
|
$TOOL_TABLE
|
|
EOF
|
|
|
|
rm -f "$WEBSITE_DIR/track-$_channel.zip"
|
|
(cd "$_staging" && zip -qr "$WEBSITE_DIR/track-$_channel.zip" .)
|
|
echo "Wrote $WEBSITE_DIR/track-$_channel.zip"
|
|
rm -rf "$_staging"
|
|
}
|
|
|
|
# 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; }
|
|
</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
|
|
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 install.zip, track-*.zip, releases/index.html ==="
|
|
build_install_zip
|
|
build_track_zip alpha
|
|
build_track_zip beta
|
|
build_track_zip stable
|
|
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 downloads: website/"
|
|
echo " install.zip — self-contained install for deployment root"
|
|
echo " track-alpha.zip — level-2 stubs that track the alpha channel"
|
|
echo " track-beta.zip — level-2 stubs that track the beta channel"
|
|
echo " track-stable.zip — level-2 stubs that track the stable channel"
|