diff --git a/README.md b/README.md index 0a67a79..87ff039 100644 --- a/README.md +++ b/README.md @@ -38,9 +38,10 @@ it special-cases none of it. ## Binaries - `portal` — the server (Leptos SSR + hydrate, Axum underneath). -- `question_lint` — headless content validation, run by the - `questions` repo's CI against a prebuilt copy this repo's deploy - publishes; also works offline: `question_lint --path `. +- `question_lint` — headless content validation, shipped inside every + release artifact so each content repo's CI lints with the exact + portal version its instance runs; also works offline: + `question_lint --path `. ## Development @@ -50,17 +51,55 @@ cargo test --features ssr # engine tests cargo build --features ssr --bin question_lint ``` -Runtime configuration is env vars (see `src/main.rs` and -`.gitea/workflows/deploy.yml`): `NATS_URL`, `CONTENT_REPO`/ -`CONTENT_BRANCH`, Kanidm OIDC (`KANIDM_URL`, `OAUTH2_CLIENT_*`), -optional `GARAGE_*` for uploads, `GITEA_API_TOKEN` for authenticated -resource pulls, `AUTOMATION_READ_TOKEN` for the automation KV read -endpoint. +Runtime configuration is env vars (see `src/main.rs`, and each +content repo's `.gitea/workflows/deploy.yml` for the values in +production): `NATS_URL`, `CONTENT_REPO`/`CONTENT_BRANCH`, Kanidm OIDC +(`KANIDM_URL`, `OAUTH2_CLIENT_*`), optional `GARAGE_*` for uploads, +`GITEA_API_TOKEN` for authenticated resource pulls, +`AUTOMATION_READ_TOKEN` for the automation KV read endpoint. -## Deploy +## Release and deploy -Pushing `main` triggers `.gitea/workflows/deploy.yml` on the -bare-metal runner: release build, ship to -`/srv/app/uhhm-portal/releases/`, flip the `current` symlink, -restart `app@uhhm-portal`, reload Caddy. Content changes never come -through here — they hot-reload live from the `questions` repo. +Portal doesn't deploy itself — it publishes versions, and each site +decides when to take one. The whole day-to-day surface is two +commands: + +**Cut a release** (here): + +```sh +cargo release patch # or minor / major +``` + +That bumps `Cargo.toml`, tags `v`, and pushes; CI +(`.gitea/workflows/publish.yml`) reacts to the tag, builds once, and +attaches `portal-v.tar.gz` (`portal` + `question_lint` + +`site/`) to the Gitea release. Plain pushes to `main` only run the +tests (`test.yml`) — nothing reaches production from this repo. + +**Roll it out** (in a content repo): edit one line in that repo's +`.gitea/workflows/deploy.yml` — + +```yaml +env: + PORTAL_RELEASE: v0.1.1 # <- bump, commit, push +``` + +Its CI downloads the pinned artifact, ships +`/srv/app//releases/`, flips `current`, rewrites the +instance env from that repo's own Actions variables/secrets, restarts +`app@`, and refreshes the Caddy route. Every rollout is a +commit, so reverting a bad version is `git revert` + push. Sites +upgrade independently: uhhm.no (uhhm/questions → `app@uhhm-portal`, +:3010) and redoal.com (redoal/questions → `app@redoal-portal`, +:3020) can pin different versions. + +Content changes never come through any of this — they hot-reload +live from the content repos over NATS. + +**Add a site**: new content repo with a copy of an existing +`deploy.yml` (change `INSTANCE`, port, domains), Actions variables +(`KANIDM_URL`, `OAUTH2_CLIENT_ID`, `PUBLIC_URL`, `SITE_NAME`) and +secrets (`NATS_URL`, `OAUTH2_CLIENT_SECRET`, +`PORTAL_GITEA_API_TOKEN` — Gitea reserves the `GITEA_` prefix for +secret names), a Kanidm OAuth2 client, and DNS. `site.yaml` in the +content repo handles all branding; no portal changes needed.