chore: ./build is dev-only; ./build alpha is the explicit deploy
Reverts the prior CLI simplification. ./build (no arg) now does source work only — tool dist/ + cross-compiled zddc-server binaries — and leaves the website worktree alone. Channel/release cuts are explicit: ./build dev build (source only, no deploy) ./build alpha cut alpha (cascades nothing) ./build beta cut beta (cascades alpha → beta) ./build release [X.Y.Z] cut stable (cascades all) Rationale: editing source shouldn't have a side-effect on the live site. The website worktree at ~/src/zddc-website/ is what Caddy serves in real time, so any write to it is a deploy. Treating dev iteration as alpha-publish was confusing — the user wanted source builds and deploys to be distinct verbs. Mechanically: a `dev` (default) branch is added to the case statement; the post-build matrix-index regen + channel-link verifier are conditional on RELEASE_CHANNEL being set; dev builds skip them. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6167e99f3a
commit
76e1e78c55
10 changed files with 112 additions and 84 deletions
29
AGENTS.md
29
AGENTS.md
|
|
@ -3,25 +3,26 @@
|
|||
## Commands
|
||||
|
||||
```bash
|
||||
# ── Lockstep release driver: every invocation is a publish action. ────────
|
||||
# Alpha is the default since "alpha = active dev iteration" and that's
|
||||
# what running the build IS. Coordinated version (for release): max
|
||||
# across all six tools' latest tags + 1. Workflow:
|
||||
# alpha = active dev → beta = ready for general testing → stable = ship
|
||||
# ── ./build subcommands ────────────────────────────────────────────────────
|
||||
# `./build` (no arg) is a source-side dev build only — assembles tool/dist/
|
||||
# + cross-compiles zddc-server. The website worktree is left alone.
|
||||
# Channel + release subcommands deploy artifacts to the website worktree
|
||||
# under $ZDDC_DEPLOY_RELEASES_DIR (default ~/src/zddc-website/releases).
|
||||
# Workflow: alpha = active dev → beta = ready for testing → release = ship.
|
||||
|
||||
./build # cut alpha (default) — cascades nothing
|
||||
./build beta # cut beta — cascades alpha → beta
|
||||
./build release # cut stable — coordinated next version,
|
||||
# cascades all to the new version
|
||||
./build # dev build (no website worktree write)
|
||||
./build alpha # cut alpha (cascades nothing)
|
||||
./build beta # cut beta (cascades alpha → beta)
|
||||
./build release # cut stable, coordinated next version
|
||||
# (cascades alpha + beta → new stable; tags all six)
|
||||
./build release 1.2.0 # cut stable at explicit version
|
||||
./build help # usage
|
||||
./build help
|
||||
|
||||
# Build a single HTML tool's dist/ for testing (does NOT touch the
|
||||
# website worktree's release artifacts):
|
||||
# Single-tool dev build for testing (does NOT touch the website worktree):
|
||||
sh tool/build.sh # archive|transmittal|classifier|mdedit|landing
|
||||
|
||||
# Single-tool release (rare; prefer the lockstep ./build above so
|
||||
# versions don't drift between tools). Same flag form as before.
|
||||
# Single-tool release (rare; prefer ./build alpha|beta|release so versions
|
||||
# don't drift between tools). Same flag form as before.
|
||||
sh tool/build.sh --release [<version>|alpha|beta]
|
||||
./freshen-channel <tool> <channel> # rebuild one tool's alpha/beta from its current stable tag
|
||||
|
||||
|
|
|
|||
18
CLAUDE.md
18
CLAUDE.md
|
|
@ -25,15 +25,19 @@ This is a **monorepo of independent tools**, not one application:
|
|||
## Most-used commands
|
||||
|
||||
```bash
|
||||
# Lockstep release driver. Every invocation is a publish action;
|
||||
# alpha is the default since "alpha = active dev iteration".
|
||||
./build # cut alpha (default)
|
||||
./build beta # cut beta — cascades alpha → beta
|
||||
./build release # cut stable — coordinated next version, cascades all
|
||||
# Source-side dev build only — assembles tool/dist/ + cross-compiles
|
||||
# zddc-server. Does NOT write to the website worktree.
|
||||
./build
|
||||
|
||||
# Channel/release cuts — write into ~/src/zddc-website/releases/
|
||||
./build alpha # cut alpha (cascades nothing)
|
||||
./build beta # cut beta (cascades alpha → beta)
|
||||
./build release # cut stable, coordinated next version
|
||||
# (cascades alpha + beta → new stable; tags all six tools)
|
||||
./build release X.Y.Z # cut stable at explicit version
|
||||
./build help # usage
|
||||
|
||||
sh tool/build.sh # build one HTML tool's dist/ (no channel write)
|
||||
sh tool/build.sh # iterate on one HTML tool's dist/
|
||||
sh tool/build.sh --release [...] # single-tool release (rare; prefer the lockstep ./build)
|
||||
./freshen-channel <tool> <channel> # rebuild one tool's alpha/beta from its current stable tag
|
||||
|
||||
|
|
@ -55,7 +59,7 @@ No lint/typecheck/format commands exist for the HTML tools — vanilla JS + POSI
|
|||
- **No tags for alpha/beta.** Channel URLs are stable URLs by design — appending counter tags would defeat the purpose. The on-page label encodes `<date> · <sha>` for traceability. Stable cuts get clean `<tool>-vX.Y.Z` tags for every tool (six tags per cut, all sharing the same X.Y.Z).
|
||||
- **Pre-release semver in the on-page label.** Plain dev builds and `--release alpha|beta` cuts embed `vX.Y.Z-{alpha,beta}` in `{{BUILD_LABEL}}` where X.Y.Z is the next-stable target. Plain dev adds a full timestamp + `-dirty` marker; `--release alpha|beta` is date-only.
|
||||
- **Channel-link verifier.** Every `./build` ends with a check that every `<tool>_{stable,beta,alpha}.html` (and zddc-server's per-platform binary mirrors + stub pages) resolves. Bootstrap-friendly: skips zddc-server checks until the first `--release` cut materializes the binaries.
|
||||
- **`sh tool/build.sh` is a single-tool dev build.** Writes `dist/<tool>.html` only; no new per-version files / symlink updates in the website worktree. Useful for iterating on one tool without cutting alpha for the whole suite. To publish, run `./build` (cuts alpha for everything together). Release artifacts always land in `${ZDDC_DEPLOY_RELEASES_DIR:-~/src/zddc-website/releases}`; nothing is pushed automatically — commit + push the website branch when you want to publish.
|
||||
- **`./build` (no arg) is a source-side dev build.** Assembles `tool/dist/` + cross-compiled binaries; does NOT write to the website worktree. Use it to iterate without affecting the live site. To deploy, run `./build alpha|beta|release` — those promote to `${ZDDC_DEPLOY_RELEASES_DIR:-~/src/zddc-website/releases}`. Nothing is pushed to Codeberg automatically; commit + push the website branch when you want to publish.
|
||||
- **Always build before running tests** — Playwright opens `dist/tool.html` via `file://`.
|
||||
- **`</` in JS string/template literals breaks inline `<script>`** embedding. `shared/build-lib.sh` provides `escape_js_close_tags`; every tool's `build.sh` runs JS through it before inlining.
|
||||
- **All ZDDC parsing/formatting/hashing goes through `window.zddc`** (from `shared/zddc.js` + `shared/hash.js` + `shared/zddc-filter.js`). API: `parseFilename`, `parseFolder`, `parseRevision`, `formatFilename`, `formatFolder`, `compareRevisions`, `isValidStatus`, `splitExtension`, `joinExtension`, `crypto.{sha256Hex, sha256String, sha256File, bytesToHex}`, `filter.{parse, matches}`. File objects across tools use `trackingNumber` (string) and `extension` (string, **no leading dot** — use `zddc.joinExtension(name, ext)` to build a filename). Add edge cases to `tests/zddc.spec.js`, not per-tool tests.
|
||||
|
|
|
|||
127
build
127
build
|
|
@ -1,27 +1,26 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
# build — lockstep release driver for ZDDC.
|
||||
# build — ZDDC source build + lockstep release driver.
|
||||
#
|
||||
# Three subcommands. The first arg names a channel and every invocation
|
||||
# is a publish action — alpha is the default since "alpha = active dev
|
||||
# iteration" and that's what running the build IS.
|
||||
# ./build dev build: assemble tool dist/, cross-compile
|
||||
# zddc-server binaries. NO write to the website
|
||||
# worktree; nothing gets deployed.
|
||||
# ./build alpha dev build + copy alpha mirrors to the website
|
||||
# worktree (cascades nothing).
|
||||
# ./build beta dev build + copy beta mirrors (cascades alpha → beta).
|
||||
# ./build release dev build + cut coordinated stable
|
||||
# (cascades alpha + beta → new stable; tags all six tools).
|
||||
# ./build release X.Y.Z same, explicit version.
|
||||
# ./build help this message.
|
||||
#
|
||||
# ./build cut alpha (default; active dev iteration)
|
||||
# ./build beta cut beta (cascades alpha → beta)
|
||||
# ./build release cut stable (coordinated next version;
|
||||
# cascades alpha + beta → stable)
|
||||
# ./build release X.Y.Z cut stable at explicit version
|
||||
# ./build help this message
|
||||
# Lockstep: every channel/release cut bumps all six tools (5 HTML +
|
||||
# zddc-server) together. Coordinated next-stable = max(latest tag) + 1.
|
||||
#
|
||||
# Lockstep: every cut bumps all six tools (5 HTML + zddc-server)
|
||||
# together. The coordinated next-stable version is
|
||||
# max(latest tag across all tools) + 1.
|
||||
#
|
||||
# Output goes to ${ZDDC_DEPLOY_RELEASES_DIR:-$HOME/src/zddc-website/releases}
|
||||
# — the website branch's worktree, which is what Caddy serves. Nothing
|
||||
# is pushed automatically; commit + push the website branch yourself
|
||||
# when you want the changes mirrored to Codeberg.
|
||||
# Channel/release cuts write to the website worktree at
|
||||
# ${ZDDC_DEPLOY_RELEASES_DIR:-$HOME/src/zddc-website/releases}. Caddy serves
|
||||
# that path live; nothing is pushed to Codeberg automatically. To publish:
|
||||
# cd ~/src/zddc-website && git add -A && git commit && git push origin website
|
||||
|
||||
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
|
||||
|
||||
|
|
@ -33,10 +32,17 @@ root_dir="$SCRIPT_DIR"
|
|||
. "$SCRIPT_DIR/shared/build-lib.sh"
|
||||
|
||||
# --- Parse subcommand ------------------------------------------------------
|
||||
# RELEASE_CHANNEL empty means dev mode (build only, no website worktree
|
||||
# writes); set means a channel/release cut that promotes to the website
|
||||
# worktree under $ZDDC_DEPLOY_RELEASES_DIR.
|
||||
RELEASE_CHANNEL=""
|
||||
RELEASE_VERSION=""
|
||||
|
||||
case "${1:-alpha}" in
|
||||
case "${1:-dev}" in
|
||||
dev|build)
|
||||
# Dev build: tool dist/ + zddc-server binaries only. Touches
|
||||
# nothing in the website worktree.
|
||||
;;
|
||||
alpha)
|
||||
RELEASE_CHANNEL="alpha"
|
||||
;;
|
||||
|
|
@ -64,9 +70,11 @@ case "${1:-alpha}" in
|
|||
;;
|
||||
esac
|
||||
|
||||
# Per-tool argument list. The single-tool build.sh scripts still take
|
||||
# the legacy `--release [channel|version]` form, so translate.
|
||||
if [ "$RELEASE_CHANNEL" = "stable" ]; then
|
||||
# Per-tool argument list. Pass --release flag only when we're cutting
|
||||
# a channel/release; dev builds invoke each tool with no args.
|
||||
if [ -z "$RELEASE_CHANNEL" ]; then
|
||||
TOOL_RELEASE_ARGS=""
|
||||
elif [ "$RELEASE_CHANNEL" = "stable" ]; then
|
||||
TOOL_RELEASE_ARGS="--release $RELEASE_VERSION"
|
||||
else
|
||||
TOOL_RELEASE_ARGS="--release $RELEASE_CHANNEL"
|
||||
|
|
@ -218,13 +226,16 @@ echo " binary version: $ZDDC_BINARY_VERSION"
|
|||
'
|
||||
|
||||
# --- Promote zddc-server release artifacts ---------------------------------
|
||||
# Copy the freshly cross-compiled binaries to the website worktree's
|
||||
# releases/ under their canonical names + symlinks. promote_zddc_server
|
||||
# also re-runs write_zddc_server_stubs_all internally, so the matrix-cell
|
||||
# stub pages get regenerated in the same call.
|
||||
echo ""
|
||||
echo "=== Promoting zddc-server $RELEASE_CHANNEL release ==="
|
||||
promote_zddc_server "$RELEASE_CHANNEL" "$RELEASE_VERSION" "$RELEASES_DIR" "$SCRIPT_DIR/zddc/dist"
|
||||
# On a channel/release cut, copy the freshly cross-compiled binaries to
|
||||
# the website worktree's releases/ under their canonical names +
|
||||
# symlinks. promote_zddc_server also re-runs write_zddc_server_stubs_all
|
||||
# internally, so the matrix-cell stub pages get regenerated in the same
|
||||
# call. On a plain dev build, skip — we don't touch the worktree.
|
||||
if [ -n "$RELEASE_CHANNEL" ]; then
|
||||
echo ""
|
||||
echo "=== Promoting zddc-server $RELEASE_CHANNEL release ==="
|
||||
promote_zddc_server "$RELEASE_CHANNEL" "$RELEASE_VERSION" "$RELEASES_DIR" "$SCRIPT_DIR/zddc/dist"
|
||||
fi
|
||||
|
||||
# Latest stable version, by following archive_stable.html → versioned target.
|
||||
# Returns "" if no stable cut exists yet (bootstrap state). All HTML tools
|
||||
|
|
@ -623,29 +634,41 @@ PIN_END
|
|||
echo "Wrote $_out"
|
||||
}
|
||||
|
||||
echo ""
|
||||
echo "=== Building releases/index.html ==="
|
||||
build_releases_index
|
||||
|
||||
echo ""
|
||||
echo "=== Verifying channel links ==="
|
||||
verify_channel_links "$RELEASES_DIR"
|
||||
|
||||
echo ""
|
||||
echo "=== All tools built successfully ==="
|
||||
echo ""
|
||||
echo "Cut: $RELEASE_CHANNEL"
|
||||
if [ -n "$RELEASE_VERSION" ]; then
|
||||
echo "Version: v$RELEASE_VERSION"
|
||||
# Matrix index + verifier only run when we touched the website
|
||||
# worktree. Dev builds leave the worktree alone.
|
||||
if [ -n "$RELEASE_CHANNEL" ]; then
|
||||
echo ""
|
||||
echo "Tags created locally on main (push when ready):"
|
||||
for _t in archive transmittal classifier mdedit landing zddc-server; do
|
||||
echo " ${_t}-v${RELEASE_VERSION}"
|
||||
done
|
||||
echo " git push origin main && git push origin --tags"
|
||||
echo "=== Building releases/index.html ==="
|
||||
build_releases_index
|
||||
|
||||
echo ""
|
||||
echo "=== Verifying channel links ==="
|
||||
verify_channel_links "$RELEASES_DIR"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Artifacts written to $RELEASES_DIR/"
|
||||
echo " cd $(dirname "$RELEASES_DIR") && git status # to review the deploy"
|
||||
echo " cd $(dirname "$RELEASES_DIR") && git add -A && git commit && git push origin website"
|
||||
echo " ↑ commits + pushes the website branch when you're ready to publish"
|
||||
echo "=== Build done ==="
|
||||
echo ""
|
||||
if [ -z "$RELEASE_CHANNEL" ]; then
|
||||
echo "Mode: dev (source-only build, website worktree untouched)"
|
||||
echo " tool/dist/*.html ready"
|
||||
echo " zddc/dist/zddc-server-* binaries ready"
|
||||
echo ""
|
||||
echo "To deploy alpha mirrors to the website: ./build alpha"
|
||||
else
|
||||
echo "Cut: $RELEASE_CHANNEL"
|
||||
if [ -n "$RELEASE_VERSION" ]; then
|
||||
echo "Version: v$RELEASE_VERSION"
|
||||
echo ""
|
||||
echo "Tags created locally on main (push when ready):"
|
||||
for _t in archive transmittal classifier mdedit landing zddc-server; do
|
||||
echo " ${_t}-v${RELEASE_VERSION}"
|
||||
done
|
||||
echo " git push origin main && git push origin --tags"
|
||||
fi
|
||||
echo ""
|
||||
echo "Artifacts written to $RELEASES_DIR/"
|
||||
echo " cd $(dirname "$RELEASES_DIR") && git status # to review the deploy"
|
||||
echo " cd $(dirname "$RELEASES_DIR") && git add -A && git commit && git push origin website"
|
||||
echo " ↑ commits + pushes the website branch when you're ready to publish"
|
||||
fi
|
||||
|
|
|
|||
2
mdedit/dist/mdedit.html
vendored
2
mdedit/dist/mdedit.html
vendored
|
|
@ -1774,7 +1774,7 @@ body.help-open .app-header {
|
|||
</svg>
|
||||
<div class="header-title-group">
|
||||
<span class="app-header__title">ZDDC Markdown</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 76820fa</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 6167e99</span></span>
|
||||
</div>
|
||||
<button id="select-directory" class="btn btn-primary" title="Select a Directory">Select Directory</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2113,7 +2113,7 @@ td[data-field="trackingNumber"] {
|
|||
</svg>
|
||||
<div class="header-title-group">
|
||||
<span class="app-header__title">ZDDC Archive</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 76820fa</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 6167e99</span></span>
|
||||
</div>
|
||||
<button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button>
|
||||
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh Data" style="font-size:1.1rem;">⟳</button>
|
||||
|
|
|
|||
|
|
@ -1376,7 +1376,7 @@ body.help-open .app-header {
|
|||
</svg>
|
||||
<div class="header-title-group">
|
||||
<span class="app-header__title">ZDDC Classifier</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 76820fa</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 6167e99</span></span>
|
||||
</div>
|
||||
<button id="selectDirectoryBtn" class="btn btn-primary">Select Directory</button>
|
||||
<button id="refreshBtn" class="btn btn-secondary hidden" title="Refresh and rescan directory">Refresh</button>
|
||||
|
|
|
|||
|
|
@ -866,7 +866,7 @@ body {
|
|||
</g>
|
||||
</svg>
|
||||
<span class="app-header__title">ZDDC Archive</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 76820fa</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 6167e99</span></span>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<button id="theme-btn" class="btn btn-secondary" title="Theme: auto (follows OS)" aria-label="Theme: auto (follows OS)">◐</button>
|
||||
|
|
|
|||
|
|
@ -1774,7 +1774,7 @@ body.help-open .app-header {
|
|||
</svg>
|
||||
<div class="header-title-group">
|
||||
<span class="app-header__title">ZDDC Markdown</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 76820fa</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 6167e99</span></span>
|
||||
</div>
|
||||
<button id="select-directory" class="btn btn-primary" title="Select a Directory">Select Directory</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2210,7 +2210,7 @@ dialog.modal--narrow {
|
|||
</svg>
|
||||
<div class="header-title-group">
|
||||
<span class="app-header__title">ZDDC Transmittal</span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 76820fa</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 6167e99</span></span>
|
||||
</div>
|
||||
<div class="app-header__spacer"></div>
|
||||
<div class="app-header__icons">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Generated by build.sh — do not edit. One <app>=<build label> per line.
|
||||
archive=v0.0.9-alpha · 2026-05-02 · 76820fa
|
||||
transmittal=v0.0.9-alpha · 2026-05-02 · 76820fa
|
||||
classifier=v0.0.9-alpha · 2026-05-02 · 76820fa
|
||||
mdedit=v0.0.9-alpha · 2026-05-02 · 76820fa
|
||||
landing=v0.0.9-alpha · 2026-05-02 · 76820fa
|
||||
archive=v0.0.9-alpha · 2026-05-02 · 6167e99
|
||||
transmittal=v0.0.9-alpha · 2026-05-02 · 6167e99
|
||||
classifier=v0.0.9-alpha · 2026-05-02 · 6167e99
|
||||
mdedit=v0.0.9-alpha · 2026-05-02 · 6167e99
|
||||
landing=v0.0.9-alpha · 2026-05-02 · 6167e99
|
||||
|
|
|
|||
Loading…
Reference in a new issue