docs: drop alpha/beta channels + partial-version pins from repo docs
Match the build/build-lib + apps.go simplification in bdd1460. Each
tool now has one canonical URL (<tool>.html, symlink → current stable)
and a set of immutable per-version files (<tool>_v<X.Y.Z>.html). Beta
cuts are internal-only (SHA snapshot for the BMC dev chart); no public
beta or alpha channels exist anymore.
Touched:
- CLAUDE.md "Repo shape" + "Things that bite" — drop channel mirrors
and partial-version pins from the artifact-layout bullet, rewrite
the seed-from-live bullet, drop "channel-link verifier" bullet,
rewrite build-label bullet for the dev/beta/stable shape.
- AGENTS.md "Commands" + "Releasing — lockstep stable + beta snapshot"
(renamed from "lockstep, channels, layout") + "Release discipline"
(renamed from "Channel discipline"). "Freshen helper" section
deleted entirely. Artifact-layout table simplified.
- ARCHITECTURE.md Build System + Channels (renamed "Release verbs")
+ Install distribution model. Artifact-layout block + label table
+ spec syntax in the `.zddc apps:` cascade — all rewritten.
- zddc/README.md release-tagging + apps-resolver spec syntax +
signing-pipeline section.
The May 2026 simplification is now self-documenting — references to it
appear where readers might wonder why the older shape is gone.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
bdd14609d1
commit
470a34a690
4 changed files with 129 additions and 148 deletions
139
AGENTS.md
139
AGENTS.md
|
|
@ -6,16 +6,17 @@
|
||||||
# ── ./build subcommands ────────────────────────────────────────────────────
|
# ── ./build subcommands ────────────────────────────────────────────────────
|
||||||
# `./build` (no arg) is a source-side dev build only — assembles tool/dist/
|
# `./build` (no arg) is a source-side dev build only — assembles tool/dist/
|
||||||
# + cross-compiles zddc-server. dist/release-output/ and the live site are
|
# + cross-compiles zddc-server. dist/release-output/ and the live site are
|
||||||
# left alone. Channel + release subcommands produce a complete release
|
# left alone. `./build beta` is an internal SHA snapshot for the BMC dev
|
||||||
# bundle in dist/release-output/ (gitignored). Run `./deploy` to publish.
|
# chart (no public artifacts). `./build release` is the canonical stable
|
||||||
# Workflow: alpha = active dev → beta = ready for testing → release = ship.
|
# cut. Run `./deploy` to publish a stable cut.
|
||||||
|
|
||||||
./build # dev build (no release bundle)
|
./build # dev build (no release bundle)
|
||||||
./build alpha # cut alpha (cascades nothing)
|
./build beta # internal SHA snapshot for BMC dev chart
|
||||||
./build beta # cut beta (cascades alpha → beta)
|
# (regenerates embedded/* + chore commit;
|
||||||
./build release # cut stable, coordinated next version
|
# no public artifacts in dist/release-output/)
|
||||||
# (cascades alpha + beta → new stable; tags all nine)
|
./build release # coordinated stable cut, next version
|
||||||
./build release 1.2.0 # cut stable at explicit version
|
# (tags all 8 artifacts at release commit)
|
||||||
|
./build release 1.2.0 # coordinated stable cut, explicit version
|
||||||
./build help
|
./build help
|
||||||
|
|
||||||
# ── ./deploy subcommands ────────────────────────────────────────────────────
|
# ── ./deploy subcommands ────────────────────────────────────────────────────
|
||||||
|
|
@ -29,10 +30,9 @@
|
||||||
# Single-tool dev build for testing (does NOT touch dist/release-output/):
|
# Single-tool dev build for testing (does NOT touch dist/release-output/):
|
||||||
sh tool/build.sh # archive|transmittal|classifier|landing|form|tables|browse
|
sh tool/build.sh # archive|transmittal|classifier|landing|form|tables|browse
|
||||||
|
|
||||||
# Single-tool release (rare; prefer ./build alpha|beta|release so versions
|
# Single-tool stable cut (rare; prefer ./build release so versions don't
|
||||||
# don't drift between tools). Same flag form as before.
|
# drift between tools).
|
||||||
sh tool/build.sh --release [<version>|alpha|beta]
|
sh tool/build.sh --release [<version>]
|
||||||
./freshen-channel <tool> <channel> # rebuild one tool's alpha/beta from its current stable tag
|
|
||||||
|
|
||||||
# Test all tools
|
# Test all tools
|
||||||
npm test
|
npm test
|
||||||
|
|
@ -47,14 +47,14 @@ npx playwright test tool # archive | transmittal | classifier | brow
|
||||||
|
|
||||||
No lint, typecheck, or format commands exist — the project is plain sh + vanilla JS.
|
No lint, typecheck, or format commands exist — the project is plain sh + vanilla JS.
|
||||||
|
|
||||||
Channel/release cuts seed `dist/release-output/` from the current
|
Stable cuts seed `dist/release-output/` from the current
|
||||||
`/srv/zddc/releases/` (preserving symlinks) before running per-tool
|
`/srv/zddc/releases/` — copying only immutable per-version files
|
||||||
promote, then mutate the channels being cut on top. The bundle is
|
(`<tool>_v<X.Y.Z>.html`, `zddc-server_v<X.Y.Z>_<plat>`) + their `.sig`
|
||||||
therefore always a complete intended-live snapshot, not a sparse diff.
|
sidecars + `pubkey.pem`. The cut writes this version's per-version
|
||||||
The build ends with a **channel-link verifier** that asserts every
|
file + canonical `<tool>.html` / `zddc-server_<plat>` symlinks on top.
|
||||||
`<tool>_{stable,beta,alpha}.html` (and zddc-server's per-platform binary
|
`./deploy --releases` (rsync `--delete-after`) cleanses any stale
|
||||||
mirrors + stub pages) resolves. Build fails if any link is dangling —
|
files in the live tree that this cut didn't include.
|
||||||
because the bundle is complete, dangling-link errors mean a real bug.
|
|
||||||
**Nothing is pushed automatically.** Run `./deploy` to publish; commit
|
**Nothing is pushed automatically.** Run `./deploy` to publish; commit
|
||||||
+ push source changes to `main` separately.
|
+ push source changes to `main` separately.
|
||||||
|
|
||||||
|
|
@ -104,10 +104,9 @@ shared/
|
||||||
# index.html regenerated by `./build`
|
# index.html regenerated by `./build`
|
||||||
# <tool>_v<X.Y.Z>.html per-version (immutable)
|
# <tool>_v<X.Y.Z>.html per-version (immutable)
|
||||||
# <tool>_v<X.Y>.html -> ... symlink chain
|
# <tool>_v<X.Y>.html -> ... symlink chain
|
||||||
# <tool>_stable.html -> ... channel mirror, follows latest stable
|
# <tool>.html -> ... canonical symlink → current stable
|
||||||
# <tool>_{beta,alpha}.html -> ... channels (cascade to stable when idle)
|
|
||||||
# zddc-server_v<X.Y.Z>_<platform> per-platform binary (raw bytes, no LFS)
|
# zddc-server_v<X.Y.Z>_<platform> per-platform binary (raw bytes, no LFS)
|
||||||
# zddc-server_<channel>_<platform> channel binary mirror (symlink)
|
# zddc-server_<platform> canonical per-platform symlink → current stable
|
||||||
# zddc-server_<X>.html stub page surfacing 4 platform DLs
|
# zddc-server_<X>.html stub page surfacing 4 platform DLs
|
||||||
|
|
||||||
helm/
|
helm/
|
||||||
|
|
@ -118,7 +117,7 @@ helm/
|
||||||
|
|
||||||
**Critical:** `dist/` files are gitignored. `tool/dist/<tool>.html` is the canonical built artifact for testing and the source for `--release` writes into `dist/release-output/`. `dist/release-output/` is the local-only release bundle. Neither is in git. Never edit them directly.
|
**Critical:** `dist/` files are gitignored. `tool/dist/<tool>.html` is the canonical built artifact for testing and the source for `--release` writes into `dist/release-output/`. `dist/release-output/` is the local-only release bundle. Neither is in git. Never edit them directly.
|
||||||
|
|
||||||
**Two-repo + deploy-host model.** Source code lives here (`codeberg.org/VARASYS/ZDDC`); hand-edited website content lives in a separate repo (`codeberg.org/VARASYS/ZDDC-website`, typically cloned at `~/src/zddc-website/`). The live site at `zddc.varasys.io` is `/srv/zddc/` on the deploy host (Caddy bind-mount), populated by `./deploy`. Release artifacts are NOT in git — they're produced by `./build alpha|beta|release` into `dist/release-output/` and rsync'd to `/srv/zddc/releases/` by `./deploy --releases`. Per-version files (HTML and zddc-server binaries) are real immutable bytes; 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` seeds from live state, then calls them in lockstep. Older releases are reproducible from any `<tool>-vX.Y.Z` tag in this repo (`git checkout zddc-server-v0.0.8 && ./build release 0.0.8`). No Codeberg release assets, no LFS.
|
**Two-repo + deploy-host model.** Source code lives here (`codeberg.org/VARASYS/ZDDC`); hand-edited website content lives in a separate repo (`codeberg.org/VARASYS/ZDDC-website`, typically cloned at `~/src/zddc-website/`). The live site at `zddc.varasys.io` is `/srv/zddc/` on the deploy host (Caddy bind-mount), populated by `./deploy`. Release artifacts are NOT in git — they're produced by `./build release` into `dist/release-output/` and rsync'd to `/srv/zddc/releases/` by `./deploy --releases`. Each tool has exactly one canonical URL (`<tool>.html`, symlink → current stable) and a set of per-version immutable files (`<tool>_v<X.Y.Z>.html`). Same shape for zddc-server per platform. `shared/build-lib.sh` provides `promote_release` (HTML tools) and `promote_zddc_server` (binaries + matching stub pages); the top-level `./build` seeds per-version immutables from live state, then calls them in lockstep. Older releases are reproducible from any `<tool>-vX.Y.Z` tag in this repo (`git checkout zddc-server-v0.0.8 && ./build release 0.0.8`). No Codeberg release assets, no LFS.
|
||||||
|
|
||||||
## Shared CSS (`shared/base.css`)
|
## Shared CSS (`shared/base.css`)
|
||||||
|
|
||||||
|
|
@ -144,7 +143,7 @@ Included as the **first** positional arg to every tool's `concat_files` CSS call
|
||||||
- Build scripts use **POSIX sh** (`#!/bin/sh` with `set -eu`), not bash.
|
- Build scripts use **POSIX sh** (`#!/bin/sh` with `set -eu`), not bash.
|
||||||
- `concat_files` accepts **positional args only** (not array names).
|
- `concat_files` accepts **positional args only** (not array names).
|
||||||
- `awk` processes `template.html`, replacing `{{PLACEHOLDER}}` markers and stripping CDN `<script>`/`<link>` tags (pattern: `https?://`)
|
- `awk` processes `template.html`, replacing `{{PLACEHOLDER}}` markers and stripping CDN `<script>`/`<link>` tags (pattern: `https?://`)
|
||||||
- `{{BUILD_LABEL}}` is substituted in all eight HTML tools via `gsub` in awk (use `gsub`, not `print` — the placeholder is inline in an HTML line). Value is `Built: <timestamp> BETA` for dev builds, `v<version>` for stable releases, and `<channel> · <date> · <sha>` for alpha/beta channel builds; computed before the awk step. The shared `is_red` flag controls whether the label is wrapped in a red+bold `<span>` (true for dev/alpha/beta, false for stable).
|
- `{{BUILD_LABEL}}` is substituted in all seven HTML tools via `gsub` in awk (use `gsub`, not `print` — the placeholder is inline in an HTML line). Value is `v<next>-dev · <ts> · <sha>[-dirty]` for plain dev builds, `v<next>-beta · <ts> · <sha>` for `./build beta` snapshot cuts, and `v<X.Y.Z>` for stable releases; computed before the awk step. The shared `is_red` flag controls whether the label is wrapped in a red+bold `<span>` (true for dev/beta, false for stable).
|
||||||
- Cleans up temp files via `trap cleanup EXIT`
|
- Cleans up temp files via `trap cleanup EXIT`
|
||||||
|
|
||||||
**`</` escaping is mandatory.** Any JS containing `</tag>` inside string or template literals will break inline `<script>` embedding. Run:
|
**`</` escaping is mandatory.** Any JS containing `</tag>` inside string or template literals will break inline `<script>` embedding. Run:
|
||||||
|
|
@ -228,77 +227,60 @@ Format: `trackingNumber_revision (status) - title.extension`
|
||||||
- Hand-edited website content lives in a separate Codeberg repo (`codeberg.org/VARASYS/ZDDC-website`, cloned at `~/src/zddc-website/`). Source-code commits go to `main` here; content commits go to that repo
|
- Hand-edited website content lives in a separate Codeberg repo (`codeberg.org/VARASYS/ZDDC-website`, cloned at `~/src/zddc-website/`). Source-code commits go to `main` here; content commits go to that repo
|
||||||
- Release artifacts live on the deploy host (`/srv/zddc/`), not in any git history. Use `./deploy` to publish
|
- Release artifacts live on the deploy host (`/srv/zddc/`), not in any git history. Use `./deploy` to publish
|
||||||
|
|
||||||
### Releasing — lockstep, channels, layout
|
### Releasing — lockstep stable + beta snapshot
|
||||||
|
|
||||||
**Lockstep convention.** Every release cut bumps all nine artifacts (8 HTML tools + zddc-server) to the same version, even if a tool didn't change. Per-tool independent versions are gone. The coordinated next-stable target is `max(latest tag across all nine tools) + 1` — `_coordinated_next_stable` in `shared/build-lib.sh`. Channel cuts (alpha/beta) follow the same lockstep — every tool's channel mirror is overwritten in step. Three channels, ordered: **alpha** (dev iteration) → **beta** (general testing) → **stable** (ship).
|
**Lockstep convention.** Every stable cut bumps all 8 artifacts (7 HTML tools + zddc-server) to the same version, even if a tool didn't change. Per-tool independent versions are gone. The coordinated next-stable target is `max(latest tag across all 8 tools) + 1` — `_coordinated_next_stable` in `shared/build-lib.sh`.
|
||||||
|
|
||||||
**Storage model.** All release artifacts live on the deploy host at `/srv/zddc/releases/` (Caddy bind-mount, served as `https://zddc.varasys.io/releases/`). Locally they materialize in this repo's `dist/release-output/` (gitignored) when `./build alpha|beta|release` runs; `./deploy` rsyncs them out. **No git history holds release artifacts** — older versions are reproducible from any `<tool>-vX.Y.Z` tag (`git checkout zddc-server-v0.0.8 && ./build release 0.0.8`). No Codeberg release assets, no LFS, no third-party mirrors.
|
**No alpha or beta channels in the public release surface.** Simplified in May 2026 — channel mirrors (`_stable`, `_beta`, `_alpha`) and partial-version pins (`_v<X.Y>`, `_v<X>`) are gone. Each tool has exactly one canonical URL (`<tool>.html`, symlink → current stable) and a set of immutable per-version files (`<tool>_v<X.Y.Z>.html`). Same shape for zddc-server per platform.
|
||||||
|
|
||||||
|
**Storage model.** All release artifacts live on the deploy host at `/srv/zddc/releases/` (Caddy bind-mount, served as `https://zddc.varasys.io/releases/`). Locally they materialize in this repo's `dist/release-output/` (gitignored) when `./build release` runs; `./deploy` rsyncs them out. **No git history holds release artifacts** — older versions are reproducible from any `<tool>-vX.Y.Z` tag (`git checkout zddc-server-v0.0.8 && ./build release 0.0.8`). No Codeberg release assets, no LFS, no third-party mirrors.
|
||||||
|
|
||||||
| Artifact | Type | Layout |
|
| Artifact | Type | Layout |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `<tool>_v<X.Y.Z>.html` | real, immutable | per-version HTML for each of archive, transmittal, classifier, landing, form, tables, browse |
|
| `<tool>_v<X.Y.Z>.html` | real, immutable | per-version HTML for each of archive, transmittal, classifier, landing, form, tables, browse |
|
||||||
| `<tool>_v<X.Y>.html`, `<tool>_v<X>.html` | symlinks | partial-version pins |
|
| `<tool>.html` | symlink | canonical "current stable" URL per tool — always points at the latest cut's per-version file |
|
||||||
| `<tool>_<channel>.html` | symlink (or real bytes during active channel dev) | mutable channel mirror per tool, channel ∈ {stable, beta, alpha} |
|
| `<tool>_v<X.Y.Z>.html.sig` | real, immutable | Ed25519 detached signature |
|
||||||
|
| `<tool>.html.sig` | symlink | canonical .sig URL (symlink → matching `.sig` of the symlinked target) |
|
||||||
| `zddc-server_v<X.Y.Z>_<platform>` | real binary | per-version cross-compiled binary, platform ∈ {linux-amd64, darwin-amd64, darwin-arm64, windows-amd64.exe} |
|
| `zddc-server_v<X.Y.Z>_<platform>` | real binary | per-version cross-compiled binary, platform ∈ {linux-amd64, darwin-amd64, darwin-arm64, windows-amd64.exe} |
|
||||||
| `zddc-server_v<X.Y>_<platform>`, `zddc-server_v<X>_<platform>`, `zddc-server_<channel>_<platform>` | symlinks (or real bytes during active channel dev) | partial-pin and channel mirrors per platform — same cascade as the HTML tools |
|
| `zddc-server_<platform>` | symlink | canonical "current stable" per platform |
|
||||||
| `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 |
|
| `zddc-server_v<X.Y.Z>_<platform>.sig` | real | matching detached signature |
|
||||||
| `index.html` | regenerated by `build.sh` | matrix table, one column per tool, one row per release |
|
| `zddc-server_<platform>.sig` | symlink | canonical .sig URL |
|
||||||
|
| `zddc-server.html` | generated stub | current-stable four-platform download page |
|
||||||
|
| `zddc-server_v<X.Y.Z>.html` | generated stub | per-version four-platform download page |
|
||||||
|
| `index.html` | regenerated by `build` | downloads landing page (version dropdown, tool cards, apps composer) |
|
||||||
|
|
||||||
**Single point of truth.** `./build release` is the canonical lockstep cut. It seeds `dist/release-output/` from `/srv/zddc/releases/` (so cascades and the verifier see a complete world), 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 `dist/release-output/` with the matching symlink chain, then `write_zddc_server_stubs_all` regenerates every stub page, then `build_releases_index` rewrites the index, then `verify_channel_links` asserts nothing dangles. **Then** the top-level build folds the regenerated `zddc/internal/apps/embedded/*` files into a `release: vX.Y.Z lockstep` commit and tags all nine artifacts at that commit. `./deploy --releases` then publishes the bundle.
|
**Single point of truth.** `./build release` is the canonical lockstep cut. It seeds `dist/release-output/` from `/srv/zddc/releases/` (only per-version immutables + `.sig` + `pubkey.pem`), forwards each HTML tool's build with the agreed version, calls `promote_zddc_server` (in `shared/build-lib.sh`) to copy the freshly cross-compiled binaries with their canonical symlinks, then `write_zddc_server_stubs_all` regenerates stub pages, then `sign_release_artifacts` produces `.sig` for every new per-version file, then `build_releases_index` rewrites the downloads page. **Then** the top-level build folds the regenerated `zddc/internal/apps/embedded/*` files into a `release: vX.Y.Z lockstep` commit and tags all 8 artifacts at that commit. `./deploy --releases` publishes the bundle.
|
||||||
|
|
||||||
- **Stable** (`./build release` or `--release X.Y.Z`): Writes per-version HTML for the eight 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. Updates `zddc/internal/apps/embedded/*` to stable-labeled bytes, makes a release commit, tags all nine (`<tool>-v<X.Y.Z>`) **at that commit** so binaries built from the tag embed clean stable bytes. Cascade: stable cut means beta and alpha both reset to stable for every tool.
|
- **Stable** (`./build release` or `--release X.Y.Z`): Writes per-version HTML for the seven HTML tools + per-version binaries for zddc-server (real bytes, immutable) + canonical `<tool>.html` and `zddc-server_<platform>` symlinks. Updates `zddc/internal/apps/embedded/*` to stable-labeled bytes, makes a release commit, tags all 8 (`<tool>-v<X.Y.Z>`) **at that commit** so binaries built from the tag embed clean stable bytes.
|
||||||
- **Beta** (`./build beta`): Overwrites `<tool>_beta.html` with dist bytes for each HTML tool, and `zddc-server_beta_<platform>` with each platform's binary. Updates `zddc/internal/apps/embedded/*` to beta-labeled bytes (the dev image picks them up via `ZDDC_REF=main`). Cascade: `<tool>_alpha.html` → `<tool>_beta.html` and `zddc-server_alpha_<platform>` → `zddc-server_beta_<platform>` (symlinks). No tag.
|
- **Beta** (`./build beta`): Internal SHA snapshot for the BMC dev chart pipeline. Regenerates `zddc/internal/apps/embedded/*` with beta-labeled bytes and makes a `chore(embedded): cut v<X.Y.Z>-beta` commit. **NO public artifact in `dist/release-output/`.** The chart's appVersion gets set to `"<X.Y.Z>-beta-<sha>"`; chart's Dockerfile parses the suffix and `git fetch`-es that SHA. The chart compiles its own binary from the fetched source — the binary's embedded HTML tools are whatever this commit wrote. No tag.
|
||||||
- **Alpha** (`./build alpha`): Overwrites only the alpha mirrors in `dist/release-output/`, all nine artifacts. **Does NOT update `zddc/internal/apps/embedded/`** — the project invariant is that alpha is never baked into the binary. No tag, no other side-effects.
|
|
||||||
- **Plain dev builds** (`./build` with no arg): produce `tool/dist/<tool>.html` for HTML tools and `zddc/dist/zddc-server-<platform>` binaries; do NOT touch `dist/release-output/`, the live site, or `embedded/`. Use it to iterate without affecting deployable state.
|
- **Plain dev builds** (`./build` with no arg): produce `tool/dist/<tool>.html` for HTML tools and `zddc/dist/zddc-server-<platform>` binaries; do NOT touch `dist/release-output/`, the live site, or `embedded/`. Use it to iterate without affecting deployable state.
|
||||||
|
|
||||||
**Bake-in invariant** — what zddc-server's binary embeds via `//go:embed` from `zddc/internal/apps/embedded/`:
|
**Bake-in invariant** — what zddc-server's binary embeds via `//go:embed` from `zddc/internal/apps/embedded/`:
|
||||||
|
|
||||||
| Image | `ZDDC_REF` | Embeds |
|
| Image | Chart pin | Embeds |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Prod (Dockerfile.prod, BMCD) | `stable` (latest tag) | Stable-labeled bytes from the tagged release commit |
|
| Prod (Dockerfile.prod, BMCD) | `appVersion: "X.Y.Z"` → tag `zddc-server-v<X.Y.Z>` | Stable-labeled bytes from the tagged release commit |
|
||||||
| Dev (Dockerfile, devshell) | `main` | Beta or stable bytes — whatever the last beta/stable cut wrote |
|
| Dev (Dockerfile, devshell) | `appVersion: "X.Y.Z"` or `"X.Y.Z-beta-<sha>"` → tag or SHA | Stable or beta-snapshot bytes (whichever the chart points at) |
|
||||||
| Local dev iteration | n/a | Use `tool/dist/<tool>.html` directly; binary's embedded copy lags |
|
| Local dev iteration | n/a | Use `tool/dist/<tool>.html` directly; binary's embedded copy lags |
|
||||||
|
|
||||||
**Alpha is never baked in.** Active dev work uses the tool's local dist HTML opened directly in a browser; the binary's embedded copy is the "default fallback" served when no `.zddc apps:` override exists, and only ever holds beta or stable bytes.
|
|
||||||
|
|
||||||
On-page `{{BUILD_LABEL}}` format (HTML tools only — zddc-server's version comes from the binary itself):
|
On-page `{{BUILD_LABEL}}` format (HTML tools only — zddc-server's version comes from the binary itself):
|
||||||
|
|
||||||
- Plain dev: `vX.Y.Z-alpha · <full-ts> · <sha>[-dirty]` (red), where X.Y.Z is the per-tool next-stable target.
|
- Plain dev: `vX.Y.Z-dev · <full-ts> · <sha>[-dirty]` (red), where X.Y.Z is the next-stable target.
|
||||||
- `--release alpha`: `vX.Y.Z-alpha · <date> · <sha>` (red).
|
- `./build beta`: `vX.Y.Z-beta · <full-ts> · <sha>` (red). Only seen on the dev chart's compiled binary.
|
||||||
- `--release beta`: `vX.Y.Z-beta · <date> · <sha>` (red).
|
- `./build release [X.Y.Z]`: `v<X.Y.Z>` (black).
|
||||||
- `--release [version]`: `v<X.Y.Z>` (black).
|
|
||||||
|
|
||||||
After cutting a stable release, `git push origin main && git push origin --tags` to publish the new version files + symlinks + every per-tool tag in lockstep.
|
After cutting a stable release, `git push origin main && git push origin --tags` to publish the new release commit + every per-tool tag in lockstep.
|
||||||
|
|
||||||
### Channel discipline (MUST rules)
|
### Release discipline (MUST rules)
|
||||||
|
|
||||||
The build enforces lockstep mechanically (one command bumps all nine). The rules below are still on you.
|
The build enforces lockstep mechanically (one command bumps all 8). The rules below are still on you.
|
||||||
|
|
||||||
1. **Stable doesn't regress.** No known-broken features that worked in the previous stable. If `v0.0.5` ships with a bug, the path forward is `v0.0.6` with a fix — never edit a previously-published per-version file in place. Stable per-version files are immutable.
|
1. **Stable doesn't regress.** No known-broken features that worked in the previous stable. If `v0.0.5` ships with a bug, the path forward is `v0.0.6` with a fix — never edit a previously-published per-version file in place. Per-version files are immutable.
|
||||||
2. **Lockstep is the contract.** Don't cut a single tool's release without bumping the rest. The HTML tool's standalone `--release` flag still exists as an escape hatch but emits a tag that immediately drifts out of sync with the others.
|
2. **Lockstep is the contract.** Don't cut a single tool's stable without bumping the rest. The HTML tool's standalone `sh tool/build.sh --release X.Y.Z` flag still exists as an escape hatch but emits a tag that immediately drifts out of sync with the others.
|
||||||
3. **No backports.** Always cut a new stable at a higher version. Users pinned to an old version stay pinned by choice.
|
3. **No backports.** Always cut a new stable at a higher version. Users pinned to an old version stay pinned by choice.
|
||||||
4. **Alpha and beta are mutable.** Document this anywhere you invite users to test them. Pinning a deployment to a channel mirror means it gets rebuilt without notice. For reproducibility, pin to a per-version URL — `<tool>_v0.0.5.html` or `zddc-server_v0.0.5.html`.
|
4. **Beta is internal.** Don't advertise `./build beta` snapshots to users — they're a BMC dev pipeline plumbing concept, not a "preview" release. The canonical URL `<tool>.html` always points at the latest stable.
|
||||||
5. **Cascade is automatic.** Stable cut → beta + alpha mirrors reset to stable (per-tool HTML AND per-platform zddc-server). Beta cut → alpha → beta. "No active beta" silently shows current stable. No freshen step required after a stable release.
|
5. **Hotfix path.** For critical bugs: fix on `main`, cut a new stable. Tag the commit message `fix:` or include "hotfix" so intent is visible in `git log`.
|
||||||
6. **Hotfix path.** For critical bugs: fix on `main`, cut a new stable. Tag the commit message `fix:` or include "hotfix" so intent is visible in `git log`.
|
6. **Beta soak before promoting (recommended).** Give a beta-snapshotted build a few days on the dev chart before cutting the same code as stable. Not enforced; use judgment for trivial changes.
|
||||||
7. **Beta soak before promoting (recommended).** Give a beta a few days of exposure before cutting the same code as stable. Not enforced; use judgment for trivial changes.
|
|
||||||
|
|
||||||
### Freshen helper
|
|
||||||
|
|
||||||
`./freshen-channel <tool> <channel>` rebuilds the alpha or beta channel of a tool from its current stable tag — useful when you want a channel to advance to current stable code without doing active dev on it (e.g. after upstream dependency changes). Most of the time you don't need it: the cascade rule (rule 5 above) means a stable cut already resets the downstream channel symlinks. Use this when you specifically want a fresh build with a new on-page label timestamp instead of a symlink.
|
|
||||||
|
|
||||||
```sh
|
|
||||||
./freshen-channel archive alpha
|
|
||||||
./freshen-channel transmittal beta
|
|
||||||
```
|
|
||||||
|
|
||||||
What it does:
|
|
||||||
|
|
||||||
1. Finds the latest `<tool>-v*` clean stable tag.
|
|
||||||
2. Creates a temporary git worktree at that tag — does **not** touch the main worktree's HEAD or working tree.
|
|
||||||
3. Runs `<tool>/build.sh --release <channel>` inside the worktree, which overwrites `<tool>_<channel>.html` with the freshly-built bytes. (Note: this is in the worktree, not on main — you'll need to commit the resulting changes back to main afterward.)
|
|
||||||
4. Removes the worktree.
|
|
||||||
|
|
||||||
The build pipeline used is the one **at the tag**, not on `main`. That is intentional (pure reproducibility). If you have made build-system improvements since stable was cut and want the freshen to use them, cut a new stable first.
|
|
||||||
|
|
||||||
### Install model
|
### Install model
|
||||||
|
|
||||||
|
|
@ -309,7 +291,7 @@ No install script. Two paths:
|
||||||
|
|
||||||
To override at any level, either:
|
To override at any level, either:
|
||||||
1. Drop a real `<app>.html` file at the path → static handler serves it (highest priority).
|
1. Drop a real `<app>.html` file at the path → static handler serves it (highest priority).
|
||||||
2. Write an `apps:` entry in any `.zddc` along the path. Spec is one of `stable`/`beta`/`alpha`/`v0.0.4`/`v0.0`/`v0`/full URL/local path. Closer-to-leaf entries win. (Or change `default_tool` / `dir_tool` / `available_tools` to route a different tool entirely.)
|
2. Write an `apps:` entry in any `.zddc` along the path. Spec is one of `stable` (canonical "latest stable"), `v0.0.4` (exact-version pin), full URL, or local path. Closer-to-leaf entries win. (Or change `default_tool` / `dir_tool` / `available_tools` to route a different tool entirely.)
|
||||||
|
|
||||||
URL sources fetch once and cache forever in `<ZDDC_ROOT>/_app/<host>/<path>`. To force a re-fetch, delete the cache file. No background refresh, no SHA-256 verification, no admin UI. If a configured URL fetch fails, the server falls back to the embedded copy and emits a one-time WARN log.
|
URL sources fetch once and cache forever in `<ZDDC_ROOT>/_app/<host>/<path>`. To force a re-fetch, delete the cache file. No background refresh, no SHA-256 verification, no admin UI. If a configured URL fetch fails, the server falls back to the embedded copy and emits a one-time WARN log.
|
||||||
|
|
||||||
|
|
@ -538,7 +520,7 @@ podman run --rm --network=host -v "$PWD":/src:Z -v /tmp/gocache:/root/go/pkg/mod
|
||||||
# launch the binary on the host (`./zddc/zddc-server`).
|
# launch the binary on the host (`./zddc/zddc-server`).
|
||||||
```
|
```
|
||||||
|
|
||||||
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 `./build alpha|beta|release` it also promotes those binaries to `dist/release-output/` with the matching symlink chain and stub pages — same lockstep flow as the HTML tools. `./deploy` rsyncs the bundle to `/srv/zddc/releases/`.
|
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 `./build release` it also promotes those binaries to `dist/release-output/` with their per-platform canonical symlinks + stub pages — same lockstep flow as the HTML tools. `./deploy` rsyncs the bundle to `/srv/zddc/releases/`.
|
||||||
|
|
||||||
### Test
|
### Test
|
||||||
|
|
||||||
|
|
@ -703,19 +685,18 @@ Implementation: `zddc/internal/zddc/admin.go` (Principal struct + gated function
|
||||||
|
|
||||||
### Release tagging
|
### Release tagging
|
||||||
|
|
||||||
zddc-server has no separate release script. The top-level `./build alpha|beta|release [version]` is the canonical path: it cross-compiles the binaries inside the containerized Go toolchain, copies them into `dist/release-output/` with the lockstep symlink chain (one set of symlinks per platform), regenerates the per-version + per-channel stub pages, refreshes the index, and (on stable) tags `zddc-server-v<X.Y.Z>` alongside the eight HTML-tool tags.
|
zddc-server has no separate release script. The top-level `./build release [version]` is the canonical path: it cross-compiles the binaries inside the containerized Go toolchain, copies them into `dist/release-output/` with their per-platform canonical symlinks (`zddc-server_<platform>` → `zddc-server_v<X.Y.Z>_<platform>`), regenerates the per-version + canonical stub pages, refreshes the index, and tags `zddc-server-v<X.Y.Z>` alongside the seven HTML-tool tags.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./build release # lockstep stable, coordinated next version
|
./build release # lockstep stable, coordinated next version
|
||||||
./build release 1.2.0 # lockstep stable, explicit version
|
./build release 1.2.0 # lockstep stable, explicit version
|
||||||
./build alpha # lockstep alpha cut for everything
|
./build beta # internal SHA snapshot for the BMC dev chart
|
||||||
./build beta # lockstep beta cut for everything
|
|
||||||
./deploy --releases # publish the bundle to /srv/zddc/releases/
|
./deploy --releases # publish the bundle to /srv/zddc/releases/
|
||||||
```
|
```
|
||||||
|
|
||||||
The script tags every tool but does NOT push — finish with `git push origin main && git push origin --tags` (and run `./deploy` to put the artifacts on the live site).
|
The script tags every tool but does NOT push — finish with `git push origin main && git push origin --tags` (and run `./deploy` to put the artifacts on the live site).
|
||||||
|
|
||||||
**Versioning** — clean semver. Stable cuts emit one `<tool>-vX.Y.Z` tag per tool, all nine sharing the same X.Y.Z. No `-alpha.N` / `-beta.N` counter tags — channel URLs are stable URLs by design. Historical per-tool independent tags (`archive-v0.0.2`, `zddc-server-v0.0.7`, etc.) stay as artifacts; the next coordinated cut jumps every tool to the same number.
|
**Versioning** — clean semver. Stable cuts emit one `<tool>-vX.Y.Z` tag per tool, all 8 sharing the same X.Y.Z. No `-alpha.N` / `-beta.N` counter tags — the canonical URL `<tool>.html` is the stable URL; counters would defeat that. Historical per-tool independent tags (`archive-v0.0.2`, `zddc-server-v0.0.7`, etc.) stay as artifacts; the next coordinated cut jumps every tool to the same number.
|
||||||
|
|
||||||
**Binary distribution** — `/srv/zddc/releases/zddc-server_<X>_<platform>` (on the deploy host) are real static files served from `zddc.varasys.io/releases/`. No Codeberg release assets, no `$CODEBERG_TOKEN`, no third-party mirror, no LFS. The matrix-cell link points at `zddc-server_<X>.html`, a generated stub page that surfaces the four platform downloads in one click.
|
**Binary distribution** — `/srv/zddc/releases/zddc-server_<X>_<platform>` (on the deploy host) are real static files served from `zddc.varasys.io/releases/`. No Codeberg release assets, no `$CODEBERG_TOKEN`, no third-party mirror, no LFS. The matrix-cell link points at `zddc-server_<X>.html`, a generated stub page that surfaces the four platform downloads in one click.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,19 +43,19 @@ Website files (what `zddc.varasys.io` serves) live on a **separate Codeberg repo
|
||||||
README.md, LICENSE # repo housekeeping
|
README.md, LICENSE # repo housekeeping
|
||||||
# NO releases/ — release artifacts are NOT in any git history.
|
# NO releases/ — release artifacts are NOT in any git history.
|
||||||
|
|
||||||
~/src/zddc/dist/release-output/ (gitignored, produced by ./build alpha|beta|release)
|
~/src/zddc/dist/release-output/ (gitignored, produced by ./build release)
|
||||||
index.html # download page, regenerated by build
|
index.html # download page, regenerated by build
|
||||||
<tool>_v<X.Y.Z>.html # real per-version HTML (immutable)
|
<tool>_v<X.Y.Z>.html # real per-version HTML (immutable)
|
||||||
<tool>_v<X.Y>.html → ... # symlink: latest patch within X.Y.*
|
<tool>_v<X.Y.Z>.html.sig # detached Ed25519 signature
|
||||||
<tool>_v<X>.html → ... # symlink: latest within X.*.*
|
<tool>.html → <tool>_v<X.Y.Z>.html # canonical "current stable" symlink
|
||||||
<tool>_stable.html → ... # symlink: current stable HTML
|
<tool>.html.sig → <tool>_v<X.Y.Z>.html.sig # canonical .sig symlink (chains to per-version .sig)
|
||||||
<tool>_beta.html → ... # symlink to stable (or real bytes when active beta dev)
|
|
||||||
<tool>_alpha.html → ... # symlink to beta/stable (or real bytes when active alpha dev)
|
|
||||||
zddc-server_v<X.Y.Z>_<platform> # real per-version cross-compiled binary (raw bytes, no LFS)
|
zddc-server_v<X.Y.Z>_<platform> # real per-version cross-compiled binary (raw bytes, no LFS)
|
||||||
zddc-server_v<X.Y>_<platform> → ... # symlink chain (mirrors the HTML cascade per platform)
|
zddc-server_v<X.Y.Z>_<platform>.sig # detached signature
|
||||||
zddc-server_v<X>_<platform> → ...
|
zddc-server_<platform> → ... # canonical per-platform symlink → current stable
|
||||||
zddc-server_<channel>_<platform> → ... # channel mirror per platform
|
zddc-server_<platform>.sig → ... # canonical .sig symlink
|
||||||
zddc-server_<X>.html # generated stub: cell link → fans out 4 platform downloads
|
zddc-server_v<X.Y.Z>.html # per-version stub: 4 platform downloads for that version
|
||||||
|
zddc-server.html # canonical stub: 4 platform downloads for current stable
|
||||||
|
pubkey.pem # signing pubkey (seeded from live)
|
||||||
|
|
||||||
/srv/zddc/ (deploy host; Caddy bind-mount)
|
/srv/zddc/ (deploy host; Caddy bind-mount)
|
||||||
index.html, reference.html, css/, js/, img/ ← rsync'd from ~/src/zddc-website/
|
index.html, reference.html, css/, js/, img/ ← rsync'd from ~/src/zddc-website/
|
||||||
|
|
@ -64,11 +64,11 @@ Website files (what `zddc.varasys.io` serves) live on a **separate Codeberg repo
|
||||||
|
|
||||||
`<tool>` ∈ {archive, transmittal, classifier, landing, form, tables, browse}. `<platform>` ∈ {linux-amd64, darwin-amd64, darwin-arm64, windows-amd64.exe}.
|
`<tool>` ∈ {archive, transmittal, classifier, landing, form, tables, browse}. `<platform>` ∈ {linux-amd64, darwin-amd64, darwin-arm64, windows-amd64.exe}.
|
||||||
|
|
||||||
Every URL under `/releases/` resolves directly via the symlink chain — no `manifest.json`, no Caddy regex-rewrite, no JavaScript indirection, no third-party mirror. Caddy serves these as plain static files. The Docker-tag pattern: `:1.2.3` is pinned, `:1.2` floats, `:1` floats further, `:stable` floats furthest, and `:beta` / `:alpha` are mutable channel mirrors that overwrite in place.
|
Every URL under `/releases/` resolves directly via the symlink chain — no `manifest.json`, no Caddy regex-rewrite, no JavaScript indirection, no third-party mirror. Caddy serves these as plain static files. Two URL shapes per tool: `<tool>.html` (canonical, mutable symlink → current stable) and `<tool>_v<X.Y.Z>.html` (immutable per-version pin). Same for zddc-server per platform. The May 2026 simplification dropped channel mirrors (`_stable`, `_beta`, `_alpha`) and partial-version pins (`_v<X.Y>`, `_v<X>`) — operators pin to exact versions when they want stability, otherwise track the canonical URL.
|
||||||
|
|
||||||
**zddc-server binaries are reproducible from a tag, not in git** — `./build alpha|beta|release` cross-compiles them into `dist/release-output/`, `./deploy` rsyncs them to `/srv/zddc/releases/`, Caddy serves from there. Older versions: `git checkout zddc-server-v0.0.8 && ./build release 0.0.8`. The `helm/zddc-server-{prod,dev,cache}/` charts build from source via init container, but operators who want a prebuilt binary just `curl -O https://zddc.varasys.io/releases/zddc-server_stable_linux-amd64`. The single cell link per release points at `zddc-server_<X>.html`, a small generated stub that surfaces all four platform downloads.
|
**zddc-server binaries are reproducible from a tag, not in git** — `./build release` cross-compiles them into `dist/release-output/`, `./deploy` rsyncs them to `/srv/zddc/releases/`, Caddy serves from there. Older versions: `git checkout zddc-server-v0.0.8 && ./build release 0.0.8`. The `helm/zddc-server-{prod,dev,cache}/` charts build from source via init container, but operators who want a prebuilt binary just `curl -O https://zddc.varasys.io/releases/zddc-server_linux-amd64`. The four-platform fan-out lives at `zddc-server.html` (current stable) or `zddc-server_v<X.Y.Z>.html` (per-version).
|
||||||
|
|
||||||
To preview a build locally, open `dist/tool.html` directly via the dev server. To publish on `zddc.varasys.io`, cut a release with `./build alpha|beta|release` and then `./deploy`.
|
To preview a build locally, open `dist/tool.html` directly via the dev server. To publish on `zddc.varasys.io`, cut a release with `./build release` and then `./deploy`.
|
||||||
|
|
||||||
Vendor dependencies (bundled third-party libraries) live in `tool/vendor/` if present. The build script is responsible for inlining them into the output.
|
Vendor dependencies (bundled third-party libraries) live in `tool/vendor/` if present. The build script is responsible for inlining them into the output.
|
||||||
|
|
||||||
|
|
@ -105,42 +105,36 @@ Each HTML tool's `build.sh`:
|
||||||
2. Reads JS files in declaration order, concatenates them
|
2. Reads JS files in declaration order, concatenates them
|
||||||
3. Processes `template.html` with `awk`, replacing `{{PLACEHOLDER}}` markers with the concatenated content and stripping CDN `<script>`/`<link>` tags
|
3. Processes `template.html` with `awk`, replacing `{{PLACEHOLDER}}` markers with the concatenated content and stripping CDN `<script>`/`<link>` tags
|
||||||
4. Writes the result to `dist/tool.html`
|
4. Writes the result to `dist/tool.html`
|
||||||
5. If `--release <channel-or-version>` was passed, calls `promote_release` to write into `dist/release-output/` (per-version file + symlink updates for stable; channel mirror overwrite for alpha/beta).
|
5. If `--release [<version>]` was passed (stable cut), calls `promote_release` to write into `dist/release-output/`: per-version immutable file + canonical `<tool>.html` symlink + .sig companion. Beta cuts skip — `./build beta` is internal-only (embedded regen + chore commit), no public artifact.
|
||||||
|
|
||||||
The top-level `./build` at the repository root is the canonical lockstep entry point. It:
|
The top-level `./build` at the repository root is the canonical lockstep entry point. It:
|
||||||
|
|
||||||
1. On a channel/release cut, **seeds `dist/release-output/` from `/srv/zddc/releases/`** (preserving symlinks) so the bundle is a complete intended-live snapshot, not a sparse one-channel diff. Cascades and the verifier downstream see the same world the live site has.
|
1. On a stable cut, **seeds `dist/release-output/` from `/srv/zddc/releases/`** — copying only the immutable per-version files (`<tool>_v<X.Y.Z>.html`, `zddc-server_v<X.Y.Z>_<plat>`) + their `.sig` sidecars + `pubkey.pem`. The canonical symlinks get rewritten by this cut; any stale files in the live tree are cleaned by deploy's `--delete-after`.
|
||||||
2. Forwards `--release [version|alpha|beta]` to every HTML tool's build, computing a coordinated next-stable target via `_coordinated_next_stable` (max of every tool's latest tag + 1) when no explicit version is given.
|
2. Forwards `--release [version]` to every HTML tool's build (or `--release beta` for the snapshot path), computing a coordinated next-stable target via `_coordinated_next_stable` (max of every tool's latest tag + 1) when no explicit version is given.
|
||||||
3. Cross-compiles zddc-server for the four target platforms inside a containerized Go toolchain (podman/docker).
|
3. Cross-compiles zddc-server for the four target platforms inside a containerized Go toolchain (podman/docker).
|
||||||
4. On a channel/release cut, calls `promote_zddc_server` to copy the freshly cross-compiled binaries into `dist/release-output/` with the matching symlink chain (one set per platform) and tag `zddc-server-v<X.Y.Z>` alongside the eight HTML-tool tags (stable cuts only).
|
4. On a stable cut, calls `promote_zddc_server` to copy the freshly cross-compiled binaries into `dist/release-output/` with per-platform canonical symlinks (`zddc-server_<platform>`) and `.sig` companions; tagging `zddc-server-v<X.Y.Z>` is deferred to the embedded-commit block at the end.
|
||||||
5. Calls `write_zddc_server_stubs_all` to refresh the per-version + per-channel stub HTML pages from whatever artifacts are in `dist/release-output/`.
|
5. Calls `write_zddc_server_stubs_all` to refresh the per-version + canonical stub HTML pages from whatever artifacts are in `dist/release-output/`.
|
||||||
6. Regenerates `dist/release-output/index.html` as the action-first download page.
|
6. Regenerates `dist/release-output/index.html` as the action-first download page.
|
||||||
7. Calls `verify_channel_links` — fails the build if any channel link is dangling.
|
|
||||||
|
|
||||||
Then `./deploy --releases` rsyncs `dist/release-output/` → `/srv/zddc/releases/` with `--delete-after`.
|
Then `./deploy --releases` rsyncs `dist/release-output/` → `/srv/zddc/releases/` with `--delete-after`.
|
||||||
|
|
||||||
### Channels
|
### Release verbs
|
||||||
|
|
||||||
Three release channels, applied in lockstep across all nine artifacts (8 HTML + zddc-server). The cascade rule keeps downstream channel symlinks current automatically.
|
Two release verbs (plus dev). The May 2026 simplification dropped alpha and made beta internal-only.
|
||||||
|
|
||||||
- **Stable** — versioned, immutable. `./build release [version]` writes per-version HTML for the eight 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).
|
- **Stable** — versioned, immutable. `./build release [version]` writes per-version HTML for the seven HTML tools and per-version binaries for zddc-server (real bytes), writes the canonical `<tool>.html` and `zddc-server_<platform>` symlinks → the new version, signs every per-version artifact (and companion `.sig` symlink for the canonical URL), and tags `<tool>-v<X.Y.Z>` for every tool at the release commit.
|
||||||
- **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.
|
- **Beta** — `./build beta` is the BMC dev chart's plumbing. It regenerates `zddc/internal/apps/embedded/*` with beta-labeled HTML bytes and makes a `chore(embedded): cut v<X.Y.Z>-beta` commit. No public artifact in `dist/release-output/`. The chart's appVersion pins to `"<X.Y.Z>-beta-<sha>"`; its Dockerfile parses the suffix and `git fetch`-es that SHA, compiling its own binary from the fetched source.
|
||||||
- **Alpha** — `./build alpha` overwrites only the alpha mirrors, all nine artifacts. No tag, no other side-effects.
|
- **Dev** — plain `./build` (no arg) produces `dist/<tool>.html` and `zddc/dist/zddc-server-<platform>` binaries; doesn't touch `dist/release-output/`, the live site, or `embedded/`.
|
||||||
|
|
||||||
A plain `./build` (no arg) is a dev build: it produces `dist/<tool>.html` and `zddc/dist/zddc-server-<platform>` binaries; doesn't touch `dist/release-output/` or the live site. The download index, stub pages, and verifier only run when a channel/release is being cut.
|
The on-page `{{BUILD_LABEL}}` is rendered red+bold for dev/beta builds (`is_red=1`) and black for stable releases. The label format is:
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
The on-page `{{BUILD_LABEL}}` is rendered red+bold for dev/alpha/beta builds (`is_red=1`) and black for stable releases. The label format is:
|
|
||||||
|
|
||||||
| Build | Label |
|
| Build | Label |
|
||||||
|--------------------|--------------------------------------------------------|
|
|--------------------|--------------------------------------------------------|
|
||||||
| dev (no `--release`) | `v0.0.6-alpha · 2026-04-27 14:00:00 · abc1234[-dirty]` |
|
| dev (no `--release`) | `v0.0.6-dev · 2026-04-27 14:00:00 · abc1234[-dirty]` |
|
||||||
| `--release alpha` | `v0.0.6-alpha · 2026-04-27 · abc1234` |
|
| `--release beta` | `v0.0.6-beta · 2026-04-27 14:00:00 · abc1234` |
|
||||||
| `--release beta` | `v0.0.6-beta · 2026-04-27 · abc1234` |
|
|
||||||
| `--release [ver]` | `v0.0.5` |
|
| `--release [ver]` | `v0.0.5` |
|
||||||
|
|
||||||
`X.Y.Z` for non-stable labels is the **next-stable target** — patch+1 from the latest clean `<tool>-vX.Y.Z` tag. Dev builds use the full timestamp + `-dirty` marker so iterative work is distinguishable from a formal `--release alpha` cut (which stamps date-only and is committed-clean by definition).
|
`X.Y.Z` for non-stable labels is the **next-stable target** — patch+1 from the latest clean `<tool>-vX.Y.Z` tag. Dev builds use the `-dirty` marker so iterative work is distinguishable from a formal beta cut.
|
||||||
|
|
||||||
### Install distribution model
|
### Install distribution model
|
||||||
|
|
||||||
|
|
@ -161,7 +155,7 @@ Two orthogonal axes: how the bytes get there (this section), and what runtime mo
|
||||||
Resolution order at a request to `<dir>/<app>.html` where the app is available:
|
Resolution order at a request to `<dir>/<app>.html` where the app is available:
|
||||||
|
|
||||||
1. **Override** — real `.html` file at the path → static handler.
|
1. **Override** — real `.html` file at the path → static handler.
|
||||||
2. **`.zddc apps:` cascade** — walk leaf→root for an `apps.<app>` entry. Spec is `stable`/`beta`/`alpha` (canonical channel), `v0.0.4`/`v0.0`/`v0` (canonical version), full URL (custom mirror), or local path. Closer-to-leaf wins.
|
2. **`.zddc apps:` cascade** — walk leaf→root for an `apps.<app>` entry. Spec is `stable` (canonical "current stable"), `v0.0.4` (exact-version pin), full URL (custom mirror), or local path. Closer-to-leaf wins.
|
||||||
3. **Embedded** — the build-time HTML compiled into the binary.
|
3. **Embedded** — the build-time HTML compiled into the binary.
|
||||||
|
|
||||||
URL sources fetch once on first request and cache forever in `<ZDDC_ROOT>/_app/<host>/<path>`. There is no background refresh, no SHA-256 verification, no admin UI. To pull a new build, delete the cache file. Concurrent misses for the same URL share one outbound fetch (hand-rolled singleflight). Failed fetches fall through to embedded with a one-time WARN log per source URL. Direct URL access to `/_app/...` is blocked at dispatch.
|
URL sources fetch once on first request and cache forever in `<ZDDC_ROOT>/_app/<host>/<path>`. There is no background refresh, no SHA-256 verification, no admin UI. To pull a new build, delete the cache file. Concurrent misses for the same URL share one outbound fetch (hand-rolled singleflight). Failed fetches fall through to embedded with a one-time WARN log per source URL. Direct URL access to `/_app/...` is blocked at dispatch.
|
||||||
|
|
@ -177,10 +171,10 @@ Independent of how the tool got installed. `archive` auto-detects from the URL a
|
||||||
Every `build.sh` must:
|
Every `build.sh` must:
|
||||||
|
|
||||||
- Begin with `#!/bin/sh` and `set -eu` (POSIX sh, not bash)
|
- Begin with `#!/bin/sh` and `set -eu` (POSIX sh, not bash)
|
||||||
- Source `shared/build-lib.sh` first (provides `ensure_exists`, `concat_files`, `build_timestamp`, `compute_build_label`, `promote_release`, plus the lockstep helpers `_coordinated_next_stable`, `promote_zddc_server`, `write_zddc_server_stubs_all`, `verify_channel_links`)
|
- Source `shared/build-lib.sh` first (provides `ensure_exists`, `concat_files`, `build_timestamp`, `compute_build_label`, `promote_release`, plus the lockstep helpers `_coordinated_next_stable`, `promote_zddc_server`, `write_zddc_server_stubs_all`)
|
||||||
- Fail immediately on missing source files (`ensure_exists` pattern)
|
- Fail immediately on missing source files (`ensure_exists` pattern)
|
||||||
- Clean up temp files on exit (use `trap cleanup EXIT`)
|
- Clean up temp files on exit (use `trap cleanup EXIT`)
|
||||||
- Accept `--release [<version>|alpha|beta]` — explicit version or channel name; otherwise produce a dev build
|
- Accept `--release [<version>]` for stable cuts or `--release beta` for snapshot cuts; otherwise produce a dev build
|
||||||
|
|
||||||
### HTML Embedding Safety
|
### HTML Embedding Safety
|
||||||
|
|
||||||
|
|
|
||||||
48
CLAUDE.md
48
CLAUDE.md
|
|
@ -35,15 +35,21 @@ This is a **monorepo of independent tools**, not one application:
|
||||||
# zddc-server. Does NOT touch dist/release-output/ or the live site.
|
# zddc-server. Does NOT touch dist/release-output/ or the live site.
|
||||||
./build
|
./build
|
||||||
|
|
||||||
# Channel/release cuts — produce a complete release bundle in
|
# ./build beta — internal SHA snapshot for the BMC dev chart pipeline.
|
||||||
# dist/release-output/ (gitignored). Cuts seed from the live site
|
# Regenerates zddc/internal/apps/embedded/* and makes a
|
||||||
# (/srv/zddc/releases/) so the bundle is a complete intended-live
|
# `chore(embedded): cut v<X.Y.Z>-beta` commit. NO public artifacts.
|
||||||
# snapshot, not a sparse diff. Run ./deploy to publish.
|
# The chart's appVersion pins to "<X.Y.Z>-beta-<sha>"; its Dockerfile
|
||||||
./build alpha # cut alpha (cascades nothing)
|
# parses the suffix and fetches that SHA from git.
|
||||||
./build beta # cut beta (cascades alpha → beta)
|
./build beta
|
||||||
./build release # cut stable, coordinated next version
|
#
|
||||||
# (cascades alpha + beta → new stable; tags all nine artifacts)
|
# ./build release — coordinated stable cut. Regenerates embedded/,
|
||||||
./build release X.Y.Z # cut stable at explicit version
|
# makes a release commit, tags all 8 artifacts, writes per-tool
|
||||||
|
# <tool>_v<X.Y.Z>.html + <tool>.html canonical symlink, and zddc-server
|
||||||
|
# per-platform binaries + canonical symlinks into dist/release-output/.
|
||||||
|
# Bundle seeded from /srv/zddc/releases/ so prior immutable per-version
|
||||||
|
# artifacts survive.
|
||||||
|
./build release # coordinated next-stable version
|
||||||
|
./build release X.Y.Z # explicit stable version
|
||||||
./build help # usage
|
./build help # usage
|
||||||
|
|
||||||
# Deploy — atomic-ish rsync of the build output + content repo to
|
# Deploy — atomic-ish rsync of the build output + content repo to
|
||||||
|
|
@ -53,8 +59,7 @@ This is a **monorepo of independent tools**, not one application:
|
||||||
./deploy --releases # only dist/release-output/ → /srv/zddc/releases/
|
./deploy --releases # only dist/release-output/ → /srv/zddc/releases/
|
||||||
|
|
||||||
sh tool/build.sh # iterate on one HTML tool's dist/
|
sh tool/build.sh # iterate on one HTML tool's dist/
|
||||||
sh tool/build.sh --release [...] # single-tool release (rare; prefer the lockstep ./build)
|
sh tool/build.sh --release [X.Y.Z] # single-tool stable cut (rare; prefer ./build release)
|
||||||
./freshen-channel <tool> <channel> # rebuild one tool's alpha/beta from its current stable tag
|
|
||||||
|
|
||||||
npm test # all Playwright specs (build first!)
|
npm test # all Playwright specs (build first!)
|
||||||
npx playwright test <tool> # one spec
|
npx playwright test <tool> # one spec
|
||||||
|
|
@ -68,16 +73,17 @@ No lint/typecheck/format commands exist for the HTML tools — vanilla JS + POSI
|
||||||
|
|
||||||
## Things that bite if you forget
|
## 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. `dist/release-output/` is the local-only release bundle written by `./build alpha|beta|release`. Never hand-edit a `dist/` file.
|
- **`dist/` is gitignored.** `tool/dist/<tool>.html` is the canonical built artifact for testing and the source for `./build release` writes. `dist/release-output/` is the local-only release bundle. Never hand-edit a `dist/` file.
|
||||||
- **Build vs deploy are separate verbs.** `./build` and `./build alpha|beta|release` produce artifacts under `dist/release-output/`. Nothing escapes the source tree until the operator runs `./deploy`, which rsyncs into `/srv/zddc/` (Caddy's bind-mount). This decouples local iteration from live state.
|
- **Build vs deploy are separate verbs.** `./build` and `./build release` produce artifacts under `dist/release-output/`. Nothing escapes the source tree until the operator runs `./deploy`, which rsyncs into `/srv/zddc/` (Caddy's bind-mount). This decouples local iteration from live state.
|
||||||
- **Channel/release cuts seed from live state.** Before running per-tool promote, `./build alpha|beta|release` clears `dist/release-output/` and copies `/srv/zddc/releases/` into it (preserving symlinks). The cut then mutates the channels being cut on top. Result: `dist/release-output/` is always a complete intended-live snapshot, the verifier sees a complete world, and `./deploy --releases` (rsync `--delete-after`) replaces live state cleanly.
|
- **Stable cuts seed from live state.** Before running per-tool promote, `./build release` clears `dist/release-output/` and copies only the per-version immutable files (`<tool>_v<X.Y.Z>.html`, `zddc-server_v<X.Y.Z>_<plat>`) plus their `.sig` sidecars from `/srv/zddc/releases/`. The cut writes this version's per-version files + refreshes the canonical `<tool>.html` / `zddc-server_<plat>` symlinks on top. `./deploy --releases` (rsync `--delete-after`) cleanses any stale files in the live tree that this cut didn't include.
|
||||||
- **Lockstep releases.** Every release cut bumps all nine artifacts (8 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. Stable cuts atomically (1) regenerate `zddc/internal/apps/embedded/` with stable-labeled bytes, (2) make a `release: vX.Y.Z lockstep` commit, (3) tag all nine artifacts at that commit. Tags ALWAYS point at a clean release commit — never at a source-side commit with alpha-dirty embedded files. (Fixed in May 2026; see git log around the v0.0.9 re-anchor.)
|
- **Lockstep releases.** Every release cut bumps all 8 artifacts (7 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 gone — `./build release` is the canonical path. Stable cuts atomically (1) regenerate `zddc/internal/apps/embedded/` with stable-labeled bytes, (2) make a `release: vX.Y.Z lockstep` commit, (3) tag all 8 artifacts at that commit. Tags always point at a clean release commit. (Anchor fix May 2026; see git log around the v0.0.9 re-anchor.)
|
||||||
- **Bake-in invariant.** What zddc-server's binary embeds via `//go:embed`: prod images (built from `ZDDC_REF=stable`) ship the latest stable cut's bytes. Dev images (built from `ZDDC_REF=main`) ship whatever the last beta-or-stable cut wrote — no alpha. **Alpha is never baked in.** Active dev iteration uses `tool/dist/<tool>.html` opened directly, not the binary's embedded copy. The `./build` (no arg) and `./build alpha` paths intentionally leave `embedded/` untouched.
|
- **Bake-in invariant.** What zddc-server's binary embeds via `//go:embed`: prod images (chart's Dockerfile.prod fetches the latest stable tag) ship that cut's bytes. Dev images (chart's Dockerfile fetches `appVersion`, which is either a stable tag or a `<X.Y.Z>-beta-<sha>` snapshot SHA) ship the bytes that ref carries. Plain `./build` (no arg) leaves `embedded/` untouched — local dev iteration uses `tool/dist/<tool>.html` opened directly, not the baked binary copy.
|
||||||
- **Release artifact layout** (in `dist/release-output/`, mirrored to `/srv/zddc/releases/`). HTML tools: per-version `<tool>_v<X.Y.Z>.html` (real immutable files) + partial-version pins (`<tool>_v<X.Y>.html`, `_v<X>.html`) + channel mirrors (`<tool>_{stable,beta,alpha}.html`) — all symlinks except per-version. zddc-server: `zddc-server_v<X.Y.Z>_<platform>` per-version binaries (raw bytes, no LFS), `_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.
|
- **Release artifact layout** (in `dist/release-output/`, mirrored to `/srv/zddc/releases/`):
|
||||||
- **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 (nine tags per cut, all sharing the same X.Y.Z).
|
- HTML tools: `<tool>_v<X.Y.Z>.html` (real immutable file) + `<tool>.html` (symlink → current stable's per-version file). Each carries a sibling `.sig` (real for per-version, symlink for canonical).
|
||||||
- **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.
|
- zddc-server: `zddc-server_v<X.Y.Z>_<platform>` (real immutable binary, no LFS) + `zddc-server_<platform>` (symlink → current stable's per-version binary). Same `.sig` pairing. Plus a single `zddc-server.html` stub page that surfaces the four-platform downloads of the current stable.
|
||||||
- **Channel-link verifier.** Every `./build alpha|beta|release` ends with a check that every `<tool>_{stable,beta,alpha}.html` (and zddc-server's per-platform binary mirrors + stub pages) resolves. Because cuts seed from live state, the verifier always sees a complete world; missing-link errors mean a real problem, not a sparse-bundle artifact.
|
- No channel mirrors (`_alpha`, `_beta`, `_stable`), no partial-version pins (`_v<X.Y>`, `_v<X>`). Dropped in the May 2026 simplification.
|
||||||
- **`./build` (no arg) is a source-side dev build.** Assembles `tool/dist/` + cross-compiled binaries; does NOT touch `dist/release-output/` or the live site. Use it to iterate without affecting anything. To produce a deployable bundle, run `./build alpha|beta|release`. To publish, run `./deploy`. Nothing is pushed to Codeberg automatically.
|
- **On-page build label.** Plain dev builds: `v<X.Y.Z>-dev · <full-ts> · <sha>[-dirty]` (red), where X.Y.Z is the next-stable target. `./build beta`: `v<X.Y.Z>-beta · <full-ts> · <sha>` (red) — only seen on the dev chart's compiled binary. Stable cuts: clean `v<X.Y.Z>`.
|
||||||
|
- **`./build` (no arg) is a source-side dev build.** Assembles `tool/dist/` + cross-compiled binaries; does NOT touch `dist/release-output/`, embedded files, or the live site. Use it to iterate without affecting anything. `./build beta` adds the embedded regen + chore commit (BMC dev chart consumes the SHA via appVersion). `./build release` produces the deployable bundle. `./deploy` publishes. Nothing is pushed to Codeberg automatically.
|
||||||
- **Always build before running tests** — Playwright opens `dist/tool.html` via `file://`.
|
- **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.
|
- **`</` 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.
|
- **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.
|
||||||
|
|
|
||||||
|
|
@ -1189,13 +1189,14 @@ sidesteps the operator entirely:
|
||||||
|
|
||||||
**Implementation has three parts** that interlock:
|
**Implementation has three parts** that interlock:
|
||||||
|
|
||||||
1. **Signing in the build pipeline.** `./build alpha|beta|release` runs
|
1. **Signing in the build pipeline.** `./build release` runs
|
||||||
`sign_release_artifacts` (in `./build`) after promote: walks
|
`sign_release_artifacts` (in `./build`) after promote: walks
|
||||||
`dist/release-output/` and produces a detached Ed25519 signature
|
`dist/release-output/` and produces a detached Ed25519 signature
|
||||||
(`<artifact>.sig`) alongside every real file. Private key path comes
|
(`<artifact>.sig`) alongside every real file. Private key path comes
|
||||||
from `ZDDC_SIGNING_KEY`; absent or unreadable → release fails.
|
from `ZDDC_SIGNING_KEY`; absent or unreadable → release fails.
|
||||||
Symlinks (channel mirrors, partial-version pins) skip — the .sig
|
Symlinks (the canonical `<tool>.html` and `zddc-server_<platform>`
|
||||||
at the symlink target is what counts.
|
URLs) skip — the .sig at the symlink target is what counts; a
|
||||||
|
companion `.sig` symlink chains the canonical URL to that target.
|
||||||
|
|
||||||
2. **Public key on the website.** `pubkey.pem` is a real file in
|
2. **Public key on the website.** `pubkey.pem` is a real file in
|
||||||
`~/src/zddc-website/`, deployed to `zddc.varasys.io/pubkey.pem`.
|
`~/src/zddc-website/`, deployed to `zddc.varasys.io/pubkey.pem`.
|
||||||
|
|
@ -1543,8 +1544,8 @@ For any path, the resolution order is:
|
||||||
into a directory; the static handler serves it. Beats everything below.
|
into a directory; the static handler serves it. Beats everything below.
|
||||||
2. **Closer-to-leaf `.zddc apps:` entry** — walks `.zddc` files leaf→root
|
2. **Closer-to-leaf `.zddc apps:` entry** — walks `.zddc` files leaf→root
|
||||||
for an `apps.<app>` entry. The first match wins. Spec is one of:
|
for an `apps.<app>` entry. The first match wins. Spec is one of:
|
||||||
- `stable` / `beta` / `alpha` (canonical upstream channel)
|
- `stable` (canonical upstream "current stable")
|
||||||
- `v0.0.4` / `v0.0` / `v0` (canonical upstream version pin)
|
- `v0.0.4` (canonical upstream exact-version pin)
|
||||||
- `https://...` (full URL to a custom mirror)
|
- `https://...` (full URL to a custom mirror)
|
||||||
- `./local.html` / `/abs/path.html` (local file)
|
- `./local.html` / `/abs/path.html` (local file)
|
||||||
3. **Embedded** — the build-time HTML compiled into the binary.
|
3. **Embedded** — the build-time HTML compiled into the binary.
|
||||||
|
|
@ -1566,7 +1567,7 @@ to the embedded copy and emits a one-time WARN log per source. The
|
||||||
```yaml
|
```yaml
|
||||||
# <ZDDC_ROOT>/Project-A/.zddc
|
# <ZDDC_ROOT>/Project-A/.zddc
|
||||||
apps:
|
apps:
|
||||||
classifier: alpha # track alpha for this project
|
classifier: v0.0.4 # pin classifier to v0.0.4 for this project
|
||||||
archive: https://my-mirror.internal/zddc/archive_v0.0.4.html # custom mirror, pinned
|
archive: https://my-mirror.internal/zddc/archive_v0.0.4.html # custom mirror, pinned
|
||||||
browse: ./our-browse.html # local fork
|
browse: ./our-browse.html # local fork
|
||||||
```
|
```
|
||||||
|
|
@ -1756,7 +1757,7 @@ https://codeberg.org/VARASYS/ZDDC/releases/download/zddc-server-vX.Y.Z/zddc-serv
|
||||||
|
|
||||||
Browse all releases at <https://codeberg.org/VARASYS/ZDDC/releases>.
|
Browse all releases at <https://codeberg.org/VARASYS/ZDDC/releases>.
|
||||||
|
|
||||||
There is no alpha/beta channel for binary distribution. Active dev/soak happens via the [`helm/zddc-server-dev/`](../helm/zddc-server-dev/) chart, which builds zddc-server from source on every pod restart against any commit you point it at. There is no container image; if you want your own, copy the static binary into a `FROM scratch` or `FROM alpine` base in a few lines, or use one of the helm charts which compile from source via init container.
|
Each release publishes one canonical "current stable" URL and a set of immutable per-version URLs — no preview channels for binary distribution. Active dev/soak happens via the [`helm/zddc-server-dev/`](../helm/zddc-server-dev/) chart, which builds zddc-server from source on every pod restart against any commit you point it at. The BMC `tnd-zddc-chart` follows the same model — its dev branch can pin to a `<X.Y.Z>-beta-<sha>` snapshot produced by `./build beta`. There is no container image; if you want your own, copy the static binary into a `FROM scratch` or `FROM alpine` base in a few lines, or use one of the helm charts which compile from source via init container.
|
||||||
|
|
||||||
### Env-var contract (for chart consumers)
|
### Env-var contract (for chart consumers)
|
||||||
|
|
||||||
|
|
@ -1794,13 +1795,12 @@ To run unit tests:
|
||||||
|
|
||||||
## Release tagging
|
## Release tagging
|
||||||
|
|
||||||
zddc-server has no separate release script. The repo's top-level `./build alpha|beta|release [version]` is the canonical path: it cross-compiles the four binaries inside the containerized Go toolchain, copies them into `dist/release-output/` with the lockstep symlink chain (one set per platform), regenerates the per-version + per-channel stub pages, refreshes the index, and (on stable cuts) tags `zddc-server-v<X.Y.Z>` alongside the eight HTML-tool tags.
|
zddc-server has no separate release script. The repo's top-level `./build release [version]` is the canonical path: it cross-compiles the four binaries inside the containerized Go toolchain, copies them into `dist/release-output/` with the per-platform canonical symlinks, regenerates the per-version + canonical stub pages, refreshes the index, and tags `zddc-server-v<X.Y.Z>` alongside the seven HTML-tool tags.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./build release # lockstep stable, coordinated next version
|
./build release # lockstep stable, coordinated next version
|
||||||
./build release 1.2.0 # lockstep stable, explicit version
|
./build release 1.2.0 # lockstep stable, explicit version
|
||||||
./build alpha # lockstep alpha cut
|
./build beta # internal SHA snapshot for the BMC dev chart pipeline
|
||||||
./build beta # lockstep beta cut
|
|
||||||
./deploy --releases # publish dist/release-output/ to /srv/zddc/releases/
|
./deploy --releases # publish dist/release-output/ to /srv/zddc/releases/
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -1815,9 +1815,9 @@ Single-developer / solo-release flow by design — no CI babysitting, no separat
|
||||||
|
|
||||||
### Versioning
|
### Versioning
|
||||||
|
|
||||||
Clean semver, lockstep across all nine artifacts (8 HTML + zddc-server). Stable cuts get `<tool>-vX.Y.Z` tags for every tool, all nine sharing the same X.Y.Z. There are no alpha/beta tags — channel URLs are stable URLs by design (counters defeat that). Active dev runs via `helm/zddc-server-dev/`, which builds from source on each rollout.
|
Clean semver, lockstep across all 8 artifacts (7 HTML + zddc-server). Stable cuts get `<tool>-vX.Y.Z` tags for every tool, all 8 sharing the same X.Y.Z. There are no alpha/beta tags — the canonical URL `<tool>.html` is the "always latest stable" URL; counters would defeat that. Active dev runs via `helm/zddc-server-dev/`, which builds from source on each rollout. The BMC chart pipeline pins to a `<X.Y.Z>-beta-<sha>` snapshot (produced by `./build beta`) when it wants to test pre-stable code.
|
||||||
|
|
||||||
The two existing `zddc-server-v0.0.8-alpha.1` and `zddc-server-v0.0.8-alpha.2` tags from a previous experiment stay as historical artifacts; no new alpha/beta tags are created going forward.
|
Historical tags like `zddc-server-v0.0.8-alpha.1` from earlier experiments stay as artifacts; no new alpha/beta tags are created going forward.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue