chore: simplify CLI to ./build / ./build beta / ./build release
Renames build.sh → build and replaces the --release flag form with
subcommands:
./build cut alpha (default; active dev iteration)
./build beta cut beta (cascades alpha → beta)
./build release cut stable (coordinated next version)
./build release X.Y.Z cut stable at explicit version
./build help
The contract shift: there's no longer a "plain dev build that doesn't
touch channels" at the top level. Every full-stack build is a publish
action — running ./build IS active dev iteration, which is what alpha
already meant. To iterate on one tool without writing to the website
worktree, use the per-tool sh tool/build.sh (unchanged).
Output continues to land in ${ZDDC_DEPLOY_RELEASES_DIR:-$HOME/src/zddc-website/releases}
and nothing is pushed automatically. Commit + push the website branch
yourself when you want to publish. Stable cuts still tag locally on
main; tags push separately too.
Behind the scenes: the export of ZDDC_DEPLOY_RELEASES_DIR is moved
above the per-tool build.sh invocations so children inherit it. The
prior "if RELEASE_CHANNEL else write_zddc_server_stubs_all" branch is
collapsed since RELEASE_CHANNEL is always set under the new CLI.
Docs (CLAUDE.md, AGENTS.md, ARCHITECTURE.md, zddc/README.md) updated
to reference ./build everywhere; the per-tool sh tool/build.sh refs
stay (they're a separate, narrower entry point).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
76820fa8dd
commit
6167e99f3a
12 changed files with 151 additions and 145 deletions
66
AGENTS.md
66
AGENTS.md
|
|
@ -3,27 +3,25 @@
|
|||
## Commands
|
||||
|
||||
```bash
|
||||
# Dev build: 5 HTML tools + cross-compile zddc-server binaries + regen the
|
||||
# matrix at ~/src/zddc-website/releases/index.html. dist/ artifacts only — no
|
||||
# new per-version files / symlink updates in the website worktree.
|
||||
sh build.sh
|
||||
# ── 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 a single HTML tool (archive | transmittal | classifier | mdedit | landing)
|
||||
sh tool/build.sh
|
||||
./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 release 1.2.0 # cut stable at explicit version
|
||||
./build help # usage
|
||||
|
||||
# ── Lockstep release: bumps ALL six tools (5 HTML + zddc-server) at once ──
|
||||
#
|
||||
# Coordinated version is max(latest tag across all six) + 1, so they
|
||||
# always converge. Channel cuts (alpha/beta) follow the same lockstep —
|
||||
# every tool's channel mirror is overwritten together. Workflow:
|
||||
# alpha = active dev iteration → beta = ready for general testing → stable = ship
|
||||
sh build.sh --release # stable, auto-coordinated next version
|
||||
sh build.sh --release 1.2.0 # stable, explicit version
|
||||
sh build.sh --release alpha # alpha cut for everything
|
||||
sh build.sh --release beta # beta cut for everything (cascades alpha → beta)
|
||||
# Build a single HTML tool's dist/ for testing (does NOT touch the
|
||||
# website worktree's release artifacts):
|
||||
sh tool/build.sh # archive|transmittal|classifier|mdedit|landing
|
||||
|
||||
# Single-tool release (rare; prefer the lockstep top-level cut above so
|
||||
# versions don't drift between tools). Same flags as the top-level form.
|
||||
# Single-tool release (rare; prefer the lockstep ./build above 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
|
||||
|
||||
|
|
@ -43,8 +41,10 @@ No lint, typecheck, or format commands exist — the project is plain sh + vanil
|
|||
The build ends with a **channel-link verifier** that asserts every
|
||||
`<tool>_{stable,beta,alpha}.html` (and zddc-server's per-platform binary
|
||||
mirrors + stub pages) resolves. Build fails if any link is dangling.
|
||||
Bootstrap-friendly: zddc-server checks are skipped until the first
|
||||
`--release` cut materializes the binaries under `~/src/zddc-website/releases/`.
|
||||
Output goes to `${ZDDC_DEPLOY_RELEASES_DIR:-$HOME/src/zddc-website/releases}`
|
||||
— the website branch's worktree, what Caddy serves. **Nothing is
|
||||
pushed automatically;** review with `git -C ~/src/zddc-website status`,
|
||||
commit + push the website branch yourself when ready.
|
||||
|
||||
## Architecture
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ shared/
|
|||
# (NOT in main's tree). Worktree typically at ~/src/zddc-website/:
|
||||
# index.html, reference.html, css/, js/, img/ hand-edited content
|
||||
# releases/
|
||||
# index.html regenerated by `sh build.sh`
|
||||
# index.html regenerated by `./build`
|
||||
# <tool>_v<X.Y.Z>.html per-version (committed, immutable)
|
||||
# <tool>_v<X.Y>.html -> ... symlink chain (regular git symlinks)
|
||||
# <tool>_stable.html -> ... channel mirror, follows latest stable
|
||||
|
|
@ -89,7 +89,7 @@ helm/
|
|||
|
||||
**Critical:** `dist/` files are gitignored. They're the canonical built artifact for testing and the source for `--release` writes into `~/src/zddc-website/releases/`, but they aren't checked in. Never edit them directly.
|
||||
|
||||
**Release artifacts live on the `website` orphan branch** of this same Codeberg repo, not on `main`. A `git worktree` of that branch — typically at `~/src/zddc-website/` — is what the system Caddy bind-mounts and serves at `zddc.varasys.io/`. The build pipeline writes its release outputs to `${ZDDC_DEPLOY_RELEASES_DIR:-$HOME/src/zddc-website/releases}` directly, then the operator commits + pushes that worktree separately from `main`. Per-version HTML and per-version zddc-server binaries are real bytes (binaries are LFS-tracked; HTML stays regular git); partial-version pins (`_v<X.Y>`, `_v<X>`) and channel mirrors (`_stable`, `_beta`, `_alpha`) are symlinks. `shared/build-lib.sh` provides `promote_release` (HTML tools) and `promote_zddc_server` (binaries + matching stub pages); the top-level `build.sh --release` calls them in lockstep. No Codeberg release-asset publication anymore; everything serves from `zddc.varasys.io/releases/`.
|
||||
**Release artifacts live on the `website` orphan branch** of this same Codeberg repo, not on `main`. A `git worktree` of that branch — typically at `~/src/zddc-website/` — is what the system Caddy bind-mounts and serves at `zddc.varasys.io/`. The build pipeline writes its release outputs to `${ZDDC_DEPLOY_RELEASES_DIR:-$HOME/src/zddc-website/releases}` directly, then the operator commits + pushes that worktree separately from `main`. Per-version HTML and per-version zddc-server binaries are real bytes (binaries are LFS-tracked; HTML stays regular git); partial-version pins (`_v<X.Y>`, `_v<X>`) and channel mirrors (`_stable`, `_beta`, `_alpha`) are symlinks. `shared/build-lib.sh` provides `promote_release` (HTML tools) and `promote_zddc_server` (binaries + matching stub pages); the top-level `./build` calls them in lockstep. No Codeberg release-asset publication anymore; everything serves from `zddc.varasys.io/releases/`.
|
||||
|
||||
## Shared CSS (`shared/base.css`)
|
||||
|
||||
|
|
@ -193,11 +193,11 @@ Format: `trackingNumber_revision (status) - title.extension`
|
|||
| `zddc-server_<X>.html` | generated stub page | per-version / per-channel; lists the four platform downloads. This is what the matrix-cell link points at — one stub fans out to four binaries |
|
||||
| `index.html` | regenerated by `build.sh` | matrix table, one column per tool, one row per release |
|
||||
|
||||
**Single point of truth.** `sh build.sh --release` is the canonical lockstep cut. It forwards each HTML tool's build with the agreed version, then `promote_zddc_server` (in `shared/build-lib.sh`) copies the freshly cross-compiled binaries into `~/src/zddc-website/releases/` with the matching symlink chain, then `write_zddc_server_stubs_all` regenerates every stub page, then `build_releases_index` rewrites the matrix, then `verify_channel_links` asserts nothing dangles.
|
||||
**Single point of truth.** `./build release` is the canonical lockstep cut. It forwards each HTML tool's build with the agreed version, then `promote_zddc_server` (in `shared/build-lib.sh`) copies the freshly cross-compiled binaries into `~/src/zddc-website/releases/` with the matching symlink chain, then `write_zddc_server_stubs_all` regenerates every stub page, then `build_releases_index` rewrites the matrix, then `verify_channel_links` asserts nothing dangles.
|
||||
|
||||
- **Stable** (`sh build.sh --release` or `--release X.Y.Z`): Writes per-version HTML for the five HTML tools + per-version binaries for zddc-server (real bytes, immutable). Refreshes 5 symlinks per HTML tool + 5 symlinks per zddc-server platform → the new version. Tags all six: `<tool>-v<X.Y.Z>`. Cascade: stable cut means beta and alpha both reset to stable for every tool. Skips silently if source for an HTML tool hasn't changed since the latest stable tag (the binary always builds).
|
||||
- **Beta** (`sh build.sh --release beta`): Overwrites `<tool>_beta.html` with dist bytes for each HTML tool, and `zddc-server_beta_<platform>` with each platform's binary. Cascade: `<tool>_alpha.html` → `<tool>_beta.html` and `zddc-server_alpha_<platform>` → `zddc-server_beta_<platform>` (symlinks). No tag.
|
||||
- **Alpha** (`sh build.sh --release alpha`): Overwrites only the alpha mirrors, all six tools. No tag, no other side-effects.
|
||||
- **Stable** (`./build release` or `--release X.Y.Z`): Writes per-version HTML for the five HTML tools + per-version binaries for zddc-server (real bytes, immutable). Refreshes 5 symlinks per HTML tool + 5 symlinks per zddc-server platform → the new version. Tags all six: `<tool>-v<X.Y.Z>`. Cascade: stable cut means beta and alpha both reset to stable for every tool. Skips silently if source for an HTML tool hasn't changed since the latest stable tag (the binary always builds).
|
||||
- **Beta** (`./build beta`): Overwrites `<tool>_beta.html` with dist bytes for each HTML tool, and `zddc-server_beta_<platform>` with each platform's binary. Cascade: `<tool>_alpha.html` → `<tool>_beta.html` and `zddc-server_alpha_<platform>` → `zddc-server_beta_<platform>` (symlinks). No tag.
|
||||
- **Alpha** (`./build`): Overwrites only the alpha mirrors, all six tools. No tag, no other side-effects.
|
||||
- **Plain dev builds** (no `--release`): produce `tool/dist/<tool>.html` for HTML tools and `zddc/dist/zddc-server-<platform>` binaries; do NOT touch `~/src/zddc-website/releases/`. The matrix index and stub pages still get regenerated from whatever `~/src/zddc-website/releases/` contains, so the build is idempotent for repeated dev runs.
|
||||
|
||||
On-page `{{BUILD_LABEL}}` format (HTML tools only — zddc-server's version comes from the binary itself):
|
||||
|
|
@ -269,7 +269,7 @@ Use `git worktree` to run multiple agents on separate branches simultaneously wi
|
|||
|
||||
- Worktrees live at `~/src/zddc-<branch-name>` (sibling of the main clone)
|
||||
- Before starting work on a feature branch, check `git worktree list`; if no worktree exists, create one: `git worktree add ~/src/zddc-<branch-name> -b <branch-name>`
|
||||
- All edits, builds (`sh build.sh`), and tests (`npm test`) run from within the worktree directory — build scripts use relative paths so this works correctly
|
||||
- All edits, builds (`./build`), and tests (`npm test`) run from within the worktree directory — build scripts use relative paths so this works correctly
|
||||
- The `dist/` force-commit rule (`git add -f`) applies per-worktree
|
||||
- After the branch is merged, clean up: `git worktree remove ~/src/zddc-<branch-name>` then delete the branch
|
||||
- Never run `git checkout` or `git switch` inside a worktree that another agent may be using
|
||||
|
|
@ -303,7 +303,7 @@ zddc-server ships as a cross-compiled binary, not a container image. There's no
|
|||
(cd zddc && go run ./cmd/zddc-server)
|
||||
```
|
||||
|
||||
The repo's top-level `sh build.sh` cross-compiles the four release binaries (linux/amd64, darwin/amd64, darwin/arm64, windows/amd64) into `zddc/dist/` via a containerized Go toolchain (podman or docker). On `--release` it also promotes those binaries to `~/src/zddc-website/releases/` with the matching symlink chain and stub pages — same lockstep flow as the HTML tools.
|
||||
The repo's top-level `./build` cross-compiles the four release binaries (linux/amd64, darwin/amd64, darwin/arm64, windows/amd64) into `zddc/dist/` via a containerized Go toolchain (podman or docker). On `--release` it also promotes those binaries to `~/src/zddc-website/releases/` with the matching symlink chain and stub pages — same lockstep flow as the HTML tools.
|
||||
|
||||
### Run (development)
|
||||
|
||||
|
|
@ -334,13 +334,13 @@ ZDDC_ROOT=/path/to/your/archive ZDDC_TLS_CERT=none ZDDC_ADDR=:8080 \
|
|||
|
||||
### Release tagging
|
||||
|
||||
zddc-server has no separate release script anymore. The top-level `sh build.sh --release [version|alpha|beta]` is the canonical path: it cross-compiles the binaries inside the containerized Go toolchain, copies them into `~/src/zddc-website/releases/` with the lockstep symlink chain (one set of symlinks per platform), regenerates the per-version + per-channel stub pages, refreshes the matrix, and tags `zddc-server-v<X.Y.Z>` alongside the five HTML-tool tags.
|
||||
zddc-server has no separate release script anymore. The top-level `./build release [version|alpha|beta]` is the canonical path: it cross-compiles the binaries inside the containerized Go toolchain, copies them into `~/src/zddc-website/releases/` with the lockstep symlink chain (one set of symlinks per platform), regenerates the per-version + per-channel stub pages, refreshes the matrix, and tags `zddc-server-v<X.Y.Z>` alongside the five HTML-tool tags.
|
||||
|
||||
```sh
|
||||
sh build.sh --release # lockstep stable, coordinated next version
|
||||
sh build.sh --release 1.2.0 # lockstep stable, explicit version
|
||||
sh build.sh --release alpha # lockstep alpha cut for everything
|
||||
sh build.sh --release beta # lockstep beta cut for everything
|
||||
./build release # lockstep stable, coordinated next version
|
||||
./build release 1.2.0 # lockstep stable, explicit version
|
||||
./build # lockstep alpha cut for everything
|
||||
./build beta # lockstep beta cut for everything
|
||||
```
|
||||
|
||||
The script tags every tool but does NOT push — finish with `git push origin main && git push origin --tags`.
|
||||
|
|
|
|||
|
|
@ -114,11 +114,11 @@ The top-level `build.sh` at the repository root is the canonical lockstep entry
|
|||
|
||||
Three release channels, applied in lockstep across all six tools (5 HTML + zddc-server). The cascade rule keeps downstream channel symlinks current automatically.
|
||||
|
||||
- **Stable** — versioned, immutable. `sh build.sh --release [version]` writes per-version HTML for the five HTML tools and per-version binaries for zddc-server (real bytes), refreshes the symlink chain (5 symlinks per HTML tool + 5 symlinks per zddc-server platform) all → the new version, and tags `<tool>-v<X.Y.Z>` for every tool. Skips per-tool HTML rewrites when source hasn't changed since that tool's last stable tag (binaries always rebuild).
|
||||
- **Beta** — `sh build.sh --release beta` overwrites `<tool>_beta.html` for each HTML tool and `zddc-server_beta_<platform>` for each platform with fresh bytes. Cascades alpha → beta for both HTML and binaries (one symlink per platform). No tag — channel URLs are stable URLs by design.
|
||||
- **Alpha** — `sh build.sh --release alpha` overwrites only the alpha mirrors, all six tools. No tag, no other side-effects.
|
||||
- **Stable** — versioned, immutable. `./build release [version]` writes per-version HTML for the five HTML tools and per-version binaries for zddc-server (real bytes), refreshes the symlink chain (5 symlinks per HTML tool + 5 symlinks per zddc-server platform) all → the new version, and tags `<tool>-v<X.Y.Z>` for every tool. Skips per-tool HTML rewrites when source hasn't changed since that tool's last stable tag (binaries always rebuild).
|
||||
- **Beta** — `./build beta` overwrites `<tool>_beta.html` for each HTML tool and `zddc-server_beta_<platform>` for each platform with fresh bytes. Cascades alpha → beta for both HTML and binaries (one symlink per platform). No tag — channel URLs are stable URLs by design.
|
||||
- **Alpha** — `./build` overwrites only the alpha mirrors, all six tools. No tag, no other side-effects.
|
||||
|
||||
A plain `sh build.sh` (no `--release`) is a dev build: it produces `dist/<tool>.html` and `zddc/dist/zddc-server-<platform>` binaries; doesn't touch `~/src/zddc-website/releases/`. The matrix index and stub pages still get regenerated from whatever's in `~/src/zddc-website/releases/`, so dev builds remain idempotent and don't break the channel-link verifier.
|
||||
A plain `./build` (no `--release`) is a dev build: it produces `dist/<tool>.html` and `zddc/dist/zddc-server-<platform>` binaries; doesn't touch `~/src/zddc-website/releases/`. The matrix index and stub pages still get regenerated from whatever's in `~/src/zddc-website/releases/`, so dev builds remain idempotent and don't break the channel-link verifier.
|
||||
|
||||
The cascade rule (stable cut → beta + alpha mirrors reset to stable; beta cut → alpha resets to beta) means downstream channels are never stale across either HTML or binaries. "No active beta" silently shows current stable; "no active alpha" silently shows current beta or stable. Operators don't need to run a freshen step after each stable release.
|
||||
|
||||
|
|
|
|||
29
CLAUDE.md
29
CLAUDE.md
|
|
@ -17,7 +17,7 @@ This is a **monorepo of independent tools**, not one application:
|
|||
|
||||
- `archive/`, `transmittal/`, `classifier/`, `mdedit/`, `landing/` — five self-contained HTML tools, each compiled to a single inlined HTML file in its own `dist/`. Naming: the first four output `dist/tool.html`; **`landing/` outputs `dist/index.html`** (it's the project picker served at the root of `zddc-server`).
|
||||
- `zddc/` — Go HTTP server (separate sub-project; Go 1.24+). Serves `ZDDC_ROOT/index.html` at `GET /` as the landing page; `Accept: application/json` on `/` returns the ACL-filtered project list. Cross-compiled binaries are committed to the `website` orphan branch (LFS-tracked) and served from `zddc.varasys.io/releases/` (no Codeberg release assets); the `helm/` charts in this repo build from source at deploy time.
|
||||
- `shared/` — `base.css` plus shared JS modules (`zddc.js`, `hash.js`, `zddc-filter.js`, `theme.js`, `help.js`) included by every tool's build, and `build-lib.sh` (POSIX sh helpers sourced by every tool's `build.sh` AND by the top-level `build.sh` for lockstep release helpers).
|
||||
- `shared/` — `base.css` plus shared JS modules (`zddc.js`, `hash.js`, `zddc-filter.js`, `theme.js`, `help.js`) included by every tool's build, and `build-lib.sh` (POSIX sh helpers sourced by every tool's `build.sh` AND by the top-level `build` for lockstep release helpers).
|
||||
- **`website` orphan branch** (same Codeberg repo) — committed static site: `index.html` (root URL, hand-edited intro), `releases/<tool>_v<X.Y.Z>.html` (immutable per-version archives), `releases/<tool>_v<X.Y>.html` and `_v<X>.html` (symlinks), `releases/<tool>_{stable,beta,alpha}.html` (channel mirrors), `releases/zddc-server_v<X.Y.Z>_<platform>` (per-version cross-compiled binaries; LFS-tracked), `releases/zddc-server_<channel>_<platform>` (binary symlinks following the same cascade), `releases/zddc-server_<X>.html` (per-version / per-channel stub pages that fan out the four platform downloads in one matrix-cell link), `releases/index.html` (matrix table regenerated by `build.sh`). **Working dir:** `~/src/zddc-website/` (a `git worktree` of the `website` branch — `git -C ~/src/zddc worktree add ~/src/zddc-website website`). **Caddy:** the `zddc.varasys.io:8443` vhost bind-mounts `~/src/zddc-website` and serves from there. **Install model:** local use is a download from `/releases/`. Server use is `zddc-server`, which has the current-stable build of all five tools baked in via `//go:embed` (compile-time default). Tools auto-served at folder-name-driven paths: `archive` everywhere, `classifier` in `Incoming`/`Working`/`Staging` subtrees, `mdedit` in `Working` subtrees, `transmittal` in `Staging` subtrees, `landing` only at root. Override via `.zddc apps:` cascade entry (channel/version/URL/path) — fetched once, cached at `<ZDDC_ROOT>/_app/`. Drop a real `.html` file at any path to override.
|
||||
- `helm/` — example Helm charts for zddc-server (`zddc-server-prod/`, `zddc-server-dev/`). Both compile from source via init container. Operators copy `values.yaml.example` and customize. No secrets in repo.
|
||||
- `tests/` — Playwright specs (Chromium only, requires File System Access API). `tests/schema.spec.js` validates `transmittal.schema.json` against canonical fixtures via `ajv` (only dev dep besides Playwright)
|
||||
|
|
@ -25,20 +25,21 @@ This is a **monorepo of independent tools**, not one application:
|
|||
## Most-used commands
|
||||
|
||||
```bash
|
||||
sh build.sh # dev build: 5 HTML tools + cross-compile zddc-server binaries + regen releases/index.html
|
||||
sh tool/build.sh # build one HTML tool (archive|transmittal|classifier|mdedit|landing)
|
||||
# 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
|
||||
./build release X.Y.Z # cut stable at explicit version
|
||||
./build help # usage
|
||||
|
||||
# Lockstep releases — every cut bumps ALL tools (5 HTML + zddc-server) to the same version
|
||||
sh build.sh --release # stable, coordinated next-version (max(latest tag) + 1)
|
||||
sh build.sh --release X.Y.Z # stable, explicit version
|
||||
sh build.sh --release alpha # alpha channel cut for everything
|
||||
sh build.sh --release beta # beta channel cut for everything
|
||||
sh tool/build.sh # build one HTML tool's dist/ (no channel write)
|
||||
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
|
||||
|
||||
sh tool/build.sh --release [version|alpha|beta] # single-tool release (rare; prefer the lockstep top-level cut)
|
||||
./freshen-channel <tool> <channel> # rebuild a single tool's alpha/beta from its current stable tag
|
||||
npm test # all Playwright specs (build first!)
|
||||
npx playwright test <tool> # one spec
|
||||
./dev-server start # ./dev-server stop # cache-busting HTTP on :8000
|
||||
./dev-server start # stop # cache-busting HTTP on :8000
|
||||
|
||||
# zddc/ Go server (sub-project)
|
||||
(cd zddc && go test ./...) # unit tests (Go 1.24+)
|
||||
|
|
@ -49,12 +50,12 @@ No lint/typecheck/format commands exist for the HTML tools — vanilla JS + POSI
|
|||
## Things that bite if you forget
|
||||
|
||||
- **`dist/` is gitignored.** `tool/dist/<tool>.html` is the canonical built artifact for testing and as the source for `--release` writes. Never hand-edit a `dist/` file.
|
||||
- **Lockstep releases.** Every release cut bumps all six artifacts (5 HTML tools + zddc-server) to the same version, even if a tool didn't change. The coordinated next-stable target is `max(latest tag across all tools) + 1`. Per-tool independent versions are no longer the norm — `sh build.sh --release` is the canonical path. Workflow: alpha = active dev, beta = ready for general testing, stable = ready to ship.
|
||||
- **Lockstep releases.** Every release cut bumps all six artifacts (5 HTML tools + zddc-server) to the same version, even if a tool didn't change. The coordinated next-stable target is `max(latest tag across all tools) + 1`. Per-tool independent versions are no longer the norm — `./build release` is the canonical path. Workflow: alpha = active dev, beta = ready for general testing, stable = ready to ship.
|
||||
- **Release artifacts live on the `website` orphan branch.** The build pipeline writes them to `${ZDDC_DEPLOY_RELEASES_DIR:-$HOME/src/zddc-website/releases}` — a git worktree of that branch, served by Caddy directly. HTML tools: per-version `<tool>_v<X.Y.Z>.html` (real immutable files) + partial-version pins + channel mirrors (symlinks). zddc-server: `zddc-server_v<X.Y.Z>_<platform>` per-version binaries (LFS), `zddc-server_v<X.Y>_<platform>` / `_v<X>_<platform>` / `_<channel>_<platform>` symlinks, plus `zddc-server_<X>.html` stub pages that surface the four platform downloads in one matrix-cell link. Same cascade rule for both: stable cut → beta + alpha both reset to stable; beta cut → alpha cascades to beta.
|
||||
- **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 `sh build.sh` 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.
|
||||
- **Plain `sh tool/build.sh` is a dev build.** Writes `dist/<tool>.html` only; no new per-version files / symlink updates in the website worktree. To publish, re-run with `sh build.sh --release alpha` to cut all six tools' alpha mirrors together. The release writes go to the `website` worktree at `${ZDDC_DEPLOY_RELEASES_DIR:-~/src/zddc-website/releases}`, which is then committed + pushed on that branch separately from `main`.
|
||||
- **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.
|
||||
- **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.
|
||||
|
|
|
|||
121
build.sh → build
121
build.sh → build
|
|
@ -1,22 +1,27 @@
|
|||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
# Top-level build script — builds all five HTML tools, cross-compiles
|
||||
# zddc-server binaries, and (when invoked with --release) cuts a lockstep
|
||||
# release that bumps every tool to the same version.
|
||||
# build — lockstep release driver for ZDDC.
|
||||
#
|
||||
# Usage:
|
||||
# sh build.sh # dev build
|
||||
# sh build.sh --release # stable cut, coordinated version
|
||||
# sh build.sh --release X.Y.Z # stable cut, explicit version
|
||||
# sh build.sh --release alpha # alpha channel cut
|
||||
# sh build.sh --release beta # beta channel cut
|
||||
# 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.
|
||||
#
|
||||
# Lockstep convention: every release bumps all six artifacts (5 HTML tools
|
||||
# + zddc-server) to the same version, even if a tool didn't change. The
|
||||
# coordinated next-stable target is max(latest tag across all tools) + 1.
|
||||
# Channel cuts (alpha/beta) follow the same lockstep — every tool's
|
||||
# channel mirror is overwritten in step.
|
||||
# ./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 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.
|
||||
|
||||
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
|
||||
|
||||
|
|
@ -27,42 +32,55 @@ SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
|
|||
root_dir="$SCRIPT_DIR"
|
||||
. "$SCRIPT_DIR/shared/build-lib.sh"
|
||||
|
||||
# --- Parse release args ----------------------------------------------------
|
||||
RELEASE_FLAG="${1:-}"
|
||||
RELEASE_ARG="${2:-}"
|
||||
# --- Parse subcommand ------------------------------------------------------
|
||||
RELEASE_CHANNEL=""
|
||||
RELEASE_VERSION=""
|
||||
|
||||
if [ "$RELEASE_FLAG" = "--release" ]; then
|
||||
case "$RELEASE_ARG" in
|
||||
alpha | beta)
|
||||
RELEASE_CHANNEL="$RELEASE_ARG"
|
||||
case "${1:-alpha}" in
|
||||
alpha)
|
||||
RELEASE_CHANNEL="alpha"
|
||||
;;
|
||||
'')
|
||||
beta)
|
||||
RELEASE_CHANNEL="beta"
|
||||
;;
|
||||
release)
|
||||
RELEASE_CHANNEL="stable"
|
||||
if [ -n "${2:-}" ]; then
|
||||
_validate_semver "$2"
|
||||
RELEASE_VERSION="$2"
|
||||
echo "=== Lockstep stable release — explicit version: v$RELEASE_VERSION ==="
|
||||
else
|
||||
RELEASE_VERSION=$(_coordinated_next_stable)
|
||||
echo "=== Lockstep stable release — coordinated version: v$RELEASE_VERSION ==="
|
||||
fi
|
||||
;;
|
||||
help | -h | --help)
|
||||
sed -n '4,22p' "$0" | sed 's/^# \{0,1\}//'
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
_validate_semver "$RELEASE_ARG"
|
||||
RELEASE_CHANNEL="stable"
|
||||
RELEASE_VERSION="$RELEASE_ARG"
|
||||
echo "=== Lockstep stable release — explicit version: v$RELEASE_VERSION ==="
|
||||
echo "build: unknown subcommand '$1'. Try './build help'." >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Build the per-tool argument list. For stable lockstep cuts pass the
|
||||
# explicit version so every tool agrees; for alpha/beta pass the channel
|
||||
# name; for plain dev builds pass nothing.
|
||||
TOOL_RELEASE_ARGS=""
|
||||
if [ -n "$RELEASE_CHANNEL" ]; then
|
||||
# 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
|
||||
TOOL_RELEASE_ARGS="--release $RELEASE_VERSION"
|
||||
else
|
||||
TOOL_RELEASE_ARGS="--release $RELEASE_CHANNEL"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Deploy directory for release artifacts. The website lives in the
|
||||
# orphan `website` branch served by Caddy from a fixed path; this dir
|
||||
# is the worktree of that branch (default ~/src/zddc-website/releases).
|
||||
# Override with $ZDDC_DEPLOY_RELEASES_DIR for testing or alternate
|
||||
# deploy targets. Exported so child per-tool build.sh invocations see
|
||||
# the same path.
|
||||
export ZDDC_DEPLOY_RELEASES_DIR="${ZDDC_DEPLOY_RELEASES_DIR:-$HOME/src/zddc-website/releases}"
|
||||
RELEASES_DIR="$ZDDC_DEPLOY_RELEASES_DIR"
|
||||
mkdir -p "$RELEASES_DIR"
|
||||
|
||||
echo "=== Building ZDDC tools ==="
|
||||
|
||||
|
|
@ -199,25 +217,14 @@ echo " binary version: $ZDDC_BINARY_VERSION"
|
|||
done
|
||||
'
|
||||
|
||||
# Deploy directory for release artifacts. The website lives in a separate
|
||||
# orphan branch served by Caddy from a fixed path; this directory is the
|
||||
# worktree of that branch (default ~/src/zddc-website/releases). Override
|
||||
# with $ZDDC_DEPLOY_RELEASES_DIR for testing or alternate deploy targets.
|
||||
RELEASES_DIR="${ZDDC_DEPLOY_RELEASES_DIR:-$HOME/src/zddc-website/releases}"
|
||||
mkdir -p "$RELEASES_DIR"
|
||||
|
||||
# --- Promote zddc-server release artifacts ---------------------------------
|
||||
# On a release cut, copy the freshly cross-compiled binaries to
|
||||
# website/releases/ under their canonical names + symlinks (lockstep with
|
||||
# the HTML tools' release flow). On a plain build, just refresh stub pages
|
||||
# from whatever artifacts already live in releases/.
|
||||
if [ -n "$RELEASE_CHANNEL" ]; then
|
||||
# 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"
|
||||
else
|
||||
write_zddc_server_stubs_all "$RELEASES_DIR"
|
||||
fi
|
||||
|
||||
# Latest stable version, by following archive_stable.html → versioned target.
|
||||
# Returns "" if no stable cut exists yet (bootstrap state). All HTML tools
|
||||
|
|
@ -627,20 +634,18 @@ verify_channel_links "$RELEASES_DIR"
|
|||
echo ""
|
||||
echo "=== All tools built successfully ==="
|
||||
echo ""
|
||||
if [ -n "$RELEASE_CHANNEL" ]; then
|
||||
echo "Release: $RELEASE_CHANNEL"
|
||||
echo "Cut: $RELEASE_CHANNEL"
|
||||
if [ -n "$RELEASE_VERSION" ]; then
|
||||
echo "Version: v$RELEASE_VERSION"
|
||||
echo ""
|
||||
echo "Tags created (push together):"
|
||||
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 "Publish: git push origin main && git push origin --tags"
|
||||
fi
|
||||
else
|
||||
echo "Server deployment package: zddc/dist/"
|
||||
echo " Binaries: zddc-server-{linux,darwin,windows}-*"
|
||||
echo " Web files: web/ (copy contents to ZDDC_ROOT)"
|
||||
fi
|
||||
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"
|
||||
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 12:47:59 · d688e20-dirty</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 76820fa</span></span>
|
||||
</div>
|
||||
<button id="select-directory" class="btn btn-primary" title="Select a Directory">Select Directory</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -488,7 +488,7 @@ Requires Go 1.24+.
|
|||
(cd zddc && go build -o zddc-server ./cmd/zddc-server)
|
||||
|
||||
# All four release platforms (cross-compiled, statically linked)
|
||||
sh build.sh # at the repo root — silently skips if Go isn't on PATH
|
||||
./build # at the repo root — silently skips if Go isn't on PATH
|
||||
# → outputs to zddc/dist/zddc-server-{linux,darwin,windows}-*
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -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 12:47:59 · d688e20-dirty</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 76820fa</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 12:47:59 · d688e20-dirty</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 76820fa</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 12:47:59 · d688e20-dirty</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 76820fa</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 12:47:59 · d688e20-dirty</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 76820fa</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 12:47:58 · d688e20-dirty</span></span>
|
||||
<span class="build-timestamp"><span style="color:red;font-weight:bold">v0.0.9-alpha · 2026-05-02 · 76820fa</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 12:47:59 · d688e20-dirty
|
||||
transmittal=v0.0.9-alpha · 2026-05-02 12:47:58 · d688e20-dirty
|
||||
classifier=v0.0.9-alpha · 2026-05-02 12:47:59 · d688e20-dirty
|
||||
mdedit=v0.0.9-alpha · 2026-05-02 12:47:59 · d688e20-dirty
|
||||
landing=v0.0.9-alpha · 2026-05-02 12:47:59 · d688e20-dirty
|
||||
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
|
||||
|
|
|
|||
Loading…
Reference in a new issue