ci: publish the site as the sites/zddc OCI content image, retire the sftp deploy #1

Merged
casey merged 1 commit from ctrl-agent/zddc-website:ci/oci-image into main 2026-10-15 22:21:39 +00:00
Collaborator

Moves zddc.varasys.io's website to the lab's standard OCI content-image model — the same image.yml pattern as varasys/metronome and varasys/renew — and retires the sftp deploy.

What changes

  • Adds .forgejo/workflows/image.yml (push to main + workflow_dispatch, the same triggers the old deploy had; it had no path filter). It stages exactly what ci/deploy.sh uploaded (cp -a ./. then drops /.git*, /.forgejo*, /ci, /README.md, /LICENSE, /releases — the same rm line), refuses to publish if the staged tree has no index.html (the old post-upload check, moved before the push), builds FROM scratch with buildah (BUILDAH_ISOLATION=chroot STORAGE_DRIVER=vfs), logs in with vars.REGISTRY_USER + secrets.REGISTRY_TOKEN (password on stdin), pushes sites/zddc:<YYYYMMDD>-<short-sha> and :latest, then rings ssh … "$DEPLOY_ORIGIN" "$DEPLOY_COMMAND $SITE".
  • The refresh is SKIPPED with a clear log line (DEPLOY_ORIGIN/DEPLOY_COMMAND unset — … pushed, origin NOT refreshed) while those vars are unset (renew's behaviour), so the image can be published before the origin serves it.
  • Removes .forgejo/workflows/deploy.yml and ci/deploy.sh. After this merges the site is published only as an image. The origin keeps serving its current /var/www/zddc copy until the hub's cutover switches it to mount sites/zddc; edits merged in between are in the image but not live until then.
  • README and CLAUDE.md describe the new publish path.

Vars/secrets the workflow expects (for the hub)

kind name value
var REGISTRY the zot registry host
var IMAGE_REPO sites/zddc
var SITE_NAME zddc
var REGISTRY_USER push-zddc
var DEPLOY_ORIGIN set at cutover
var DEPLOY_COMMAND set at cutover (refresh-site)
secret REGISTRY_TOKEN push-zddc's password
secret STATIC_DEPLOY_KEY the per-site key the origin pins to refresh-site zddc

Watch before merging

  • Org-level inheritance. The refresh is gated only on DEPLOY_ORIGIN + DEPLOY_COMMAND being non-empty, and Actions cannot tell an org value from a repo value. The old deploy already read vars.DEPLOY_ORIGIN and secrets.STATIC_DEPLOY_KEY, probably org-level. If DEPLOY_COMMAND is also visible at org level, this merge rings refresh-site zddc pre-cutover with the old shared key. Check what this repo inherits before merging.
  • Same published set as today, including CLAUDE.md. The old excludes never dropped it, and https://zddc.varasys.io/CLAUDE.md returns 200 today. The image keeps that behaviour on purpose (the brief was "stage exactly what deploy.sh uploads"); dropping it is a one-word follow-up.
  • Tag shape is the siblings' <date>-<short-sha> (it contains the short sha); :latest is what refresh-site serves.

Tests

  • Simulated the staging block against this repo's tree: the result is CLAUDE.md css img index.html js next pubkey.pem reference.html spec workflow.html, the same set ci/deploy.sh uploaded.
  • The workflow YAML parses, and the run: script passes shellcheck -s bash -S warning clean.
  • The buildah/push/ssh lines are copied from varasys/renew's working image.yml. They were not run here: no registry access from the authoring side.

Hub notes

  1. The repo vars and secrets are already set by the hub: REGISTRY_TOKEN (a repo secret), REGISTRY_USER (push-zddc), IMAGE_REPO and SITE_NAME. REGISTRY, DEPLOY_ORIGIN and DEPLOY_COMMAND are inherited org vars. STATIC_DEPLOY_KEY is still the inherited (gated) org key until cutover. All of the refresh inputs are therefore present, so the refresh will be attempted on merge.
  2. The merge's refresh will therefore FAIL red before cutover: the origin's refresh-site rejects zddc, which it does not serve yet. The image push happens before the refresh and is unaffected. The hub cuts over right after the merges and re-runs the workflow.

🤖 Generated with Claude Code

Moves zddc.varasys.io's **website** to the lab's standard OCI content-image model — the same `image.yml` pattern as `varasys/metronome` and `varasys/renew` — and retires the sftp deploy. ## What changes - **Adds `.forgejo/workflows/image.yml`** (push to `main` + `workflow_dispatch`, the same triggers the old deploy had; it had no path filter). It stages exactly what `ci/deploy.sh` uploaded (`cp -a ./.` then drops `/.git*`, `/.forgejo*`, `/ci`, `/README.md`, `/LICENSE`, `/releases` — the same `rm` line), refuses to publish if the staged tree has no `index.html` (the old post-upload check, moved before the push), builds `FROM scratch` with buildah (`BUILDAH_ISOLATION=chroot STORAGE_DRIVER=vfs`), logs in with `vars.REGISTRY_USER` + `secrets.REGISTRY_TOKEN` (password on stdin), pushes `sites/zddc:<YYYYMMDD>-<short-sha>` and `:latest`, then rings `ssh … "$DEPLOY_ORIGIN" "$DEPLOY_COMMAND $SITE"`. - **The refresh is SKIPPED** with a clear log line (`DEPLOY_ORIGIN/DEPLOY_COMMAND unset — … pushed, origin NOT refreshed`) while those vars are unset (renew's behaviour), so the image can be published before the origin serves it. - **Removes `.forgejo/workflows/deploy.yml` and `ci/deploy.sh`.** After this merges the site is published **only** as an image. The origin keeps serving its current `/var/www/zddc` copy until the hub's cutover switches it to mount `sites/zddc`; edits merged in between are in the image but not live until then. - README and CLAUDE.md describe the new publish path. ## Vars/secrets the workflow expects (for the hub) | kind | name | value | |---|---|---| | var | `REGISTRY` | the zot registry host | | var | `IMAGE_REPO` | `sites/zddc` | | var | `SITE_NAME` | `zddc` | | var | `REGISTRY_USER` | `push-zddc` | | var | `DEPLOY_ORIGIN` | set **at cutover** | | var | `DEPLOY_COMMAND` | set **at cutover** (`refresh-site`) | | secret | `REGISTRY_TOKEN` | `push-zddc`'s password | | secret | `STATIC_DEPLOY_KEY` | the per-site key the origin pins to `refresh-site zddc` | ## Watch before merging - **Org-level inheritance.** The refresh is gated only on `DEPLOY_ORIGIN` + `DEPLOY_COMMAND` being non-empty, and Actions cannot tell an org value from a repo value. The old deploy already read `vars.DEPLOY_ORIGIN` and `secrets.STATIC_DEPLOY_KEY`, probably org-level. If `DEPLOY_COMMAND` is also visible at org level, this merge **rings `refresh-site zddc` pre-cutover with the old shared key**. Check what this repo inherits before merging. - **Same published set as today, including `CLAUDE.md`.** The old excludes never dropped it, and `https://zddc.varasys.io/CLAUDE.md` returns 200 today. The image keeps that behaviour on purpose (the brief was "stage exactly what deploy.sh uploads"); dropping it is a one-word follow-up. - Tag shape is the siblings' `<date>-<short-sha>` (it contains the short sha); `:latest` is what refresh-site serves. ## Tests - Simulated the staging block against this repo's tree: the result is `CLAUDE.md css img index.html js next pubkey.pem reference.html spec workflow.html`, the same set `ci/deploy.sh` uploaded. - The workflow YAML parses, and the `run:` script passes `shellcheck -s bash -S warning` clean. - The buildah/push/ssh lines are copied from `varasys/renew`'s working `image.yml`. They were not run here: no registry access from the authoring side. ## Hub notes 1. **The repo vars and secrets are already set by the hub:** `REGISTRY_TOKEN` (a repo secret), `REGISTRY_USER` (`push-zddc`), `IMAGE_REPO` and `SITE_NAME`. `REGISTRY`, `DEPLOY_ORIGIN` and `DEPLOY_COMMAND` are inherited org vars. `STATIC_DEPLOY_KEY` is still the inherited (gated) org key until cutover. All of the refresh inputs are therefore present, so the refresh **will be attempted** on merge. 2. **The merge's refresh will therefore FAIL red before cutover**: the origin's `refresh-site` rejects `zddc`, which it does not serve yet. The image push happens **before** the refresh and is unaffected. The hub cuts over right after the merges and re-runs the workflow. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The site was published by ci/deploy.sh: sftp of a staged copy into
/var/www/zddc on the origin over a shared deploy key. It moves to the lab's
standard content-image model, the same as varasys/metronome and
varasys/renew:

- .forgejo/workflows/image.yml (push to main + workflow_dispatch, as the
  old deploy): stages exactly what ci/deploy.sh uploaded (drops /.git*,
  /.forgejo*, /ci, /README.md, /LICENSE, /releases), refuses to publish
  without index.html, builds FROM scratch with buildah (vfs + chroot),
  pushes sites/zddc:<date>-<short-sha> and :latest, and rings
  `$DEPLOY_COMMAND zddc` on the origin -- skipped with a log line while
  DEPLOY_ORIGIN/DEPLOY_COMMAND are unset.
- Removes .forgejo/workflows/deploy.yml and ci/deploy.sh. After this merge
  the site is published only as an image; the origin keeps serving its
  current copy until it is switched to mount the image.
- README/CLAUDE.md describe the new publish path.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
casey merged commit 16605d9563 into main 2026-10-15 22:21:39 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
varasys/zddc-website!1
No description provided.