diff --git a/AGENTS.md b/AGENTS.md index 755c7ef..1e2f3a8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -3,17 +3,17 @@ ## Commands ```bash -# Build all tools (writes to dist/ only) +# Build all tools (writes to dist/ only; also regenerates website/releases/{index.html,manifest.json}) sh build.sh # Build single tool sh tool/build.sh # archive | transmittal | classifier | mdedit | landing -# Cut a stable release (auto-increments patch version, tags, writes to website/releases/) +# Cut a stable release (auto-increments patch version, tags -vX.Y.Z, uploads _vX.Y.Z.html to Codeberg) sh tool/build.sh --release sh tool/build.sh --release 1.2.0 # explicit version -# Cut an alpha/beta channel build (mutable, no git tag) +# Cut an alpha/beta channel build (tags -vX.Y.Z-{alpha,beta}.N, uploads to Codeberg as a prerelease) sh tool/build.sh --release alpha sh tool/build.sh --release beta @@ -55,12 +55,10 @@ shared/ sourced by every tool's build.sh via: . "$root_dir/../shared/build-lib.sh" website/ - index.html current stable landing (root URL) + index.html hand-edited intro page (root URL) releases/ - _v...html immutable stable release archives - _stable.html -> ... symlink to current stable (highest semver) - _alpha.html mutable; overwritten by --release alpha - _beta.html mutable; overwritten by --release beta + index.html versions index, regenerated by build.sh from the Codeberg release list + manifest.json - → tag map (regenerated by build.sh; consumed by the level-2 stub at runtime) bootstrap/ level1/.html same-origin level-1 stubs (4 tools, no landing) track-stable/.html level-2 stubs that track the current-stable channel @@ -73,7 +71,9 @@ bootstrap/ README.md install / channel / pin docs ``` -**Critical:** `dist/` files are gitignored but force-committed (`git add -f`). Never edit them directly. +**Critical:** `dist/` files are gitignored. They're the canonical built artifact for testing and the source for `--release` uploads to Codeberg, but they aren't checked in. Never edit them directly. + +The per-version `_v.html` artifacts and zddc-server binaries also aren't checked in — they live on Codeberg as release assets attached to git tags. `website/releases/` only contains `index.html` (versions index) and `manifest.json` (channel → tag map), both regenerated by `build.sh` from a Codeberg API call. ## Shared CSS (`shared/base.css`) @@ -177,7 +177,7 @@ After cutting a release, run `git push --tags` to publish the tag. `$CODEBERG_TOKEN` must be exported before any `--release` invocation. The `promote_release` helper calls `publish_codeberg_release` which uses the token to create the release and upload the asset. -`landing/build.sh --release ` additionally writes `website/index.html` (the root URL of zddc.varasys.io) as a regular committed file — that page is hand-edited intro copy, not a release asset. +`website/index.html` (the root URL of zddc.varasys.io) is **hand-edited static content**, not built by `landing/build.sh`. The landing tool ships only as a Codeberg release asset; the self-contained install snippet curls `landing_v.html` to `/index.html` at customer-deployment time. ### Channel discipline (MUST rules) @@ -251,18 +251,30 @@ Go HTTP server sub-project living at `zddc/`. Replaces `caddy file-server --brow ### Build -```sh -# Build the container image (from the zddc/ directory) -podman build -t zddc-server zddc/ +zddc-server ships as a cross-compiled binary, not a container image. There's no Containerfile or compose file in this repo (the chart Dockerfiles in `tnd-zddc-chart` compile from source at deploy time, fetching the right tag from Codeberg). -# Or inside the zddc/ directory: -podman build -t zddc-server . +```sh +# Compile a local binary for the host platform (requires Go 1.24+) +(cd zddc && go build -o zddc-server ./cmd/zddc-server) + +# Or run directly without producing a binary +(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/` when Go is on PATH. It's silently skipped otherwise — the HTML tools build regardless. + ### Run (development) ```sh -ZDDC_DATA_DIR=/path/to/your/archive podman-compose -f zddc/podman-compose.yaml up --build +ZDDC_ROOT=/path/to/your/archive ZDDC_TLS_CERT=none ZDDC_ADDR=:8080 \ + go run ./cmd/zddc-server +``` + +For a release binary (downloaded from Codeberg or built via `sh build.sh`): + +```sh +ZDDC_ROOT=/path/to/your/archive ZDDC_TLS_CERT=none ZDDC_ADDR=:8080 \ + ./zddc/dist/zddc-server-linux-amd64 ``` ### Key environment variables @@ -342,7 +354,6 @@ local path that fails loudly and visibly on the developer's terminal. ### Notes - No external test framework yet — Go unit tests run with `go test ./...` inside `zddc/` (requires Go 1.24+) -- The container image does NOT require Go on the host — the Containerfile uses a multi-stage build - Portfolio files (`*.portfolio`) in the served tree appear as virtual group directories - Every folder exposes a `.archive` virtual directory backed by the same global index — the depth in the URL only matters so HTML produced for offline use can reach `.archive/` via `../.archive/` relative links and have the browser resolve them before the request hits the server. The flat listing emits two redirect entries per tracking number: `.html` (highest base rev) and `_.html` (each specific base rev). Both redirect to the first chronologically received copy of the named revision. Modifier files (`_+C1.html` etc.) remain reachable via the resolver but are not surfaced in the listing — they're return traffic, not primary documents. ACL is the only filter: the listing endpoint is gated by the contextPath's `.zddc` chain, and each entry is then filtered against the ACL of its resolved file's directory; per-target denials return 404 rather than 403 to avoid leaking that the tracking number exists in another subtree - ACL is enforced via cascading `.zddc` YAML files; authentication is delegated to the upstream proxy via the `X-Auth-Request-Email` header (configurable with `ZDDC_EMAIL_HEADER`) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 89c4ebe..5f1a661 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -33,21 +33,21 @@ tool/ tool.html # Generated output — never edit this manually ``` -Website files (what `zddc.varasys.io` serves) are organized by channel: +Website files (what `zddc.varasys.io` serves) — committed in this repo as static assets, but the actual built tool HTML and zddc-server binaries live on Codeberg as release assets: ``` website/ - index.html # current stable landing tool (root URL) + index.html # hand-edited intro page (root URL) releases/ - _v...html # immutable stable release archives - _stable.html -> ... # symlink to the highest-versioned stable - _alpha.html # mutable: overwritten on every --release alpha - _beta.html # mutable: overwritten on every --release beta + index.html # versions index, regenerated by build.sh from the Codeberg API + manifest.json # - → tag map, regenerated by build.sh; the level-2 stub fetches this bootstrap/ level1/.html # same-origin stubs for project subdirectories track-{alpha,beta,stable}/ # per-channel level-2 stubs (5 tools each) ``` +The per-version `_v.html` files and zddc-server binaries are **not** committed — they live on Codeberg as release assets attached to git tags. Caddy at `zddc.varasys.io` reverse-proxies `/releases//` to the corresponding Codeberg URL, so consumers (operators' bootstrap stubs, `zddc-use`, the chart Dockerfiles) only ever talk to `zddc.varasys.io`. + There is no `website/dev/`. To preview a build locally, open `dist/tool.html` directly via the dev server. To publish on `zddc.varasys.io`, cut a release. Vendor dependencies (bundled third-party libraries) live in `tool/vendor/` if present. The build script is responsible for inlining them into the output. @@ -69,7 +69,7 @@ Each topic has exactly one authoritative home; everything else links to it. | Architecture & internal patterns | `ARCHITECTURE.md` (this file) | `AGENTS.md` | | Per-tool internal design quirks | `/README.md` | (linked from website intro tool cards) | -`website/index.html` is **hand-edited static content** (analogous to `reference.html`), not the landing-tool output. The landing tool ships only via `website/releases/landing_v.html` — the self-contained install snippet copies `landing_stable.html` to `/index.html` for customer sites where the project picker UI is actually useful (it queries `zddc-server` for the project list). The public website at `zddc.varasys.io/` has nothing to pick, so its root URL is the introduction page. +`website/index.html` is **hand-edited static content** (analogous to `reference.html`), not the landing-tool output. The landing tool ships only as a Codeberg release asset (`landing-v` tag → `landing_v.html` asset) — the self-contained install snippet curls the current-stable asset through Caddy at `zddc.varasys.io/releases//landing_v.html` and saves it as `/index.html` for customer sites where the project picker UI is actually useful (it queries `zddc-server` for the project list). The public website at `zddc.varasys.io/` has nothing to pick, so its root URL is the introduction page. When updating documentation, prefer linking over duplicating. If you find yourself rewriting the file-naming convention in a tool's README, link to `reference.html` instead. @@ -85,35 +85,39 @@ Each tool's `build.sh`: 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 `