Do not merge yet — Agendula's docs/PRIVACY.md is not on its main (its commits are local on feat/caldav-sync, unpushed). The guardrail below means merging before that lands turns every deploy red, including unrelated ones. Calendula's side is already on main (PR #293 merged).
Each policy now has exactly one copy — docs/PRIVACY.md in the app repo. The pages keep their URLs (/calendula/privacy, /agendula/privacy) and their chrome, and render that file through a content collection, taking <h1> from title and the meta/OG description from description.
One correction to the brief. The checkout cannot live in Gitea CI: Coolify builds this site from the repo (multi-stage Dockerfile), and the Gitea workflow only pings a deploy hook. A checkout that ran only in CI would never reach the deployed page — the policy pages would deploy empty, which is the exact failure the design forbids. So scripts/sync-external.mjs runs from prebuild and predev, which covers Coolify, CI and local dev alike.
Shallow, single-branch, no credentials; refs default to main.
CALENDULA_REF / AGENDULA_REF build against a branch; AGENDULA_LOCAL=../agendula renders an unpushed working copy with no network.
Falls back to fetching the raw file if git fails. node:22-slim ships without git, so the Dockerfile now installs it — otherwise every deploy would quietly take the fallback path.
Guardrail, tested against the real image. A missing, empty or malformed policy fails the build. docker build stops at npm run build with [external] agendula: docs/PRIVACY.md is missing and exit 1, so no image is produced. Calendula clones and validates fine in the same run.
One thing to decide before this lands. Agendula's repo file is the short policy — 2.7k characters against the live page's 6.6k. Rendering it as-is drops: the controller's name and postal address, the permissions table, distribution channels, external links, the GDPR rights section, and the CalDAV specifics (RFC 6764 discovery, Nextcloud Login Flow, the user-CA trade-off). It also ends with mail@jeanlucmakiola.de, while the site and Calendula's policy use business@. Calendula's file is a verbatim transcription, so it loses nothing. Happy to port the missing sections into Agendula's file before its PR lands.
Also: a daily rebuild is the floor for picking up a policy edit; a Codeberg webhook per app repo pointing at the Coolify deploy URL makes it immediate. That is one-time setup in Codeberg, documented in the README.
**Do not merge yet** — Agendula's `docs/PRIVACY.md` is not on its `main` (its commits are local on `feat/caldav-sync`, unpushed). The guardrail below means merging before that lands turns every deploy red, including unrelated ones. Calendula's side is already on main (PR #293 merged).
Each policy now has exactly one copy — `docs/PRIVACY.md` in the app repo. The pages keep their URLs (`/calendula/privacy`, `/agendula/privacy`) and their chrome, and render that file through a content collection, taking `<h1>` from `title` and the meta/OG description from `description`.
**One correction to the brief.** The checkout cannot live in Gitea CI: Coolify builds this site from the repo (multi-stage `Dockerfile`), and the Gitea workflow only pings a deploy hook. A checkout that ran only in CI would never reach the deployed page — the policy pages would deploy empty, which is the exact failure the design forbids. So `scripts/sync-external.mjs` runs from `prebuild` and `predev`, which covers Coolify, CI and local dev alike.
- Shallow, single-branch, no credentials; refs default to `main`.
- `CALENDULA_REF` / `AGENDULA_REF` build against a branch; `AGENDULA_LOCAL=../agendula` renders an unpushed working copy with no network.
- Falls back to fetching the raw file if git fails. `node:22-slim` ships without git, so the Dockerfile now installs it — otherwise every deploy would quietly take the fallback path.
**Guardrail, tested against the real image.** A missing, empty or malformed policy fails the build. `docker build` stops at `npm run build` with `[external] agendula: docs/PRIVACY.md is missing` and exit 1, so no image is produced. Calendula clones and validates fine in the same run.
**One thing to decide before this lands.** Agendula's repo file is the short policy — 2.7k characters against the live page's 6.6k. Rendering it as-is drops: the controller's name and postal address, the permissions table, distribution channels, external links, the GDPR rights section, and the CalDAV specifics (RFC 6764 discovery, Nextcloud Login Flow, the user-CA trade-off). It also ends with `mail@jeanlucmakiola.de`, while the site and Calendula's policy use `business@`. Calendula's file is a verbatim transcription, so it loses nothing. Happy to port the missing sections into Agendula's file before its PR lands.
Also: a daily rebuild is the floor for picking up a policy edit; a Codeberg webhook per app repo pointing at the Coolify deploy URL makes it immediate. That is one-time setup in Codeberg, documented in the README.
Each policy now has exactly one copy: docs/PRIVACY.md in the app's own
repository. The pages keep their URLs and chrome and render that file
through a content collection, so the published page and the app's own
documentation cannot drift.
scripts/sync-external.mjs shallow-clones both repos into external/ from
prebuild and predev — not from CI: Coolify builds the site from the repo,
so a checkout that only ran in a Gitea job would never reach the deploy.
It falls back to the raw file if git is unavailable, and takes <APP>_REF
or <APP>_LOCAL for work against a branch or an unpushed working copy.
A missing, empty or malformed policy fails the build, verified against the
real image: the deploy stops rather than publishing an empty privacy page.
makiolaj
changed title from WIP: render the app privacy policies from the app repos to Render the app privacy policies from the app repos2026-09-09 14:53:28 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Do not merge yet — Agendula's
docs/PRIVACY.mdis not on itsmain(its commits are local onfeat/caldav-sync, unpushed). The guardrail below means merging before that lands turns every deploy red, including unrelated ones. Calendula's side is already on main (PR #293 merged).Each policy now has exactly one copy —
docs/PRIVACY.mdin the app repo. The pages keep their URLs (/calendula/privacy,/agendula/privacy) and their chrome, and render that file through a content collection, taking<h1>fromtitleand the meta/OG description fromdescription.One correction to the brief. The checkout cannot live in Gitea CI: Coolify builds this site from the repo (multi-stage
Dockerfile), and the Gitea workflow only pings a deploy hook. A checkout that ran only in CI would never reach the deployed page — the policy pages would deploy empty, which is the exact failure the design forbids. Soscripts/sync-external.mjsruns fromprebuildandpredev, which covers Coolify, CI and local dev alike.main.CALENDULA_REF/AGENDULA_REFbuild against a branch;AGENDULA_LOCAL=../agendularenders an unpushed working copy with no network.node:22-slimships without git, so the Dockerfile now installs it — otherwise every deploy would quietly take the fallback path.Guardrail, tested against the real image. A missing, empty or malformed policy fails the build.
docker buildstops atnpm run buildwith[external] agendula: docs/PRIVACY.md is missingand exit 1, so no image is produced. Calendula clones and validates fine in the same run.One thing to decide before this lands. Agendula's repo file is the short policy — 2.7k characters against the live page's 6.6k. Rendering it as-is drops: the controller's name and postal address, the permissions table, distribution channels, external links, the GDPR rights section, and the CalDAV specifics (RFC 6764 discovery, Nextcloud Login Flow, the user-CA trade-off). It also ends with
mail@jeanlucmakiola.de, while the site and Calendula's policy usebusiness@. Calendula's file is a verbatim transcription, so it loses nothing. Happy to port the missing sections into Agendula's file before its PR lands.Also: a daily rebuild is the floor for picking up a policy edit; a Codeberg webhook per app repo pointing at the Coolify deploy URL makes it immediate. That is one-time setup in Codeberg, documented in the README.
WIP: render the app privacy policies from the app reposto Render the app privacy policies from the app repos