licence,ci: ship OFL with Plex fonts and guard release dispatch (P5)
test / test (push) Has been cancelled

IBM Plex WOFF2 files were shipped without the SIL OFL 1.1 text, NOTICE
told modifiers to edit layout.html for a Source URL that lives in
legal.go, and workflow_dispatch took GITHUB_REF_NAME as the version so a
run from main would publish ghcr.io/...:main.

Closes P5 of docs/plans/code-review.md. CHANGELOG updated.

Co-Authored-By: Cursor Grok 4.6 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-14 09:47:33 +03:00
parent efdc2d63fb
commit 97a0c7e508
15 changed files with 232 additions and 60 deletions
+21 -10
View File
@@ -93,8 +93,9 @@ mechanics → Haiku. Reviewers must not be the author of the code under review.
## External libraries
The project is **AGPL-3.0** ([LICENSE](../LICENSE)). Copyright holder and
third-party notices: [NOTICE](../NOTICE). New Go dependencies must be
permissive or GPL-family (see
third-party notices: [NOTICE](../NOTICE). The tree does not use per-file
`SPDX-License-Identifier` headers; AGPL-3.0 does not require them. New Go
dependencies must be permissive or GPL-family (see
[.cursor/rules/agent-rules.mdc](../.cursor/rules/agent-rules.mdc)).
### Main module (`go.mod`)
@@ -113,6 +114,7 @@ the tree are AGPL-3.0-compatible.
| Asset | Version | Repository | License |
|---|---|---|---|
| `internal/web/view/static/htmx.min.js` | 2.0.4 | <https://github.com/bigskysoftware/htmx> | 0BSD |
| `internal/web/view/static/ibm-plex-*.woff2` | latin subset | <https://github.com/IBM/plex> | SIL OFL 1.1 (`OFL.txt` beside the files) |
### E2e module (`test/e2e/go.mod`)
@@ -128,8 +130,10 @@ the image.
Postfix, OpenDKIM, `supervisord`, `sasl2-bin`, `logrotate`, and others come
from Debian bookworm repositories; licenses are in each package's `copyright`
file on <https://packages.debian.org/bookworm/>.
The image also ships [LICENSE](../LICENSE) and [NOTICE](../NOTICE) under
`/usr/share/doc/selfpost/`. The panel serves the AGPL text at `/license`.
The image also ships [LICENSE](../LICENSE), [NOTICE](../NOTICE), and the IBM
Plex [OFL.txt](../internal/web/view/static/OFL.txt) under
`/usr/share/doc/selfpost/`. The panel serves the AGPL text at `/license` and
the OFL text at `/static/OFL.txt`.
---
@@ -187,9 +191,11 @@ tag / push only on explicit request (see `release.yml`).
### Release image
The release image is published **only on tag** `vX.Y.Z` (not on every push to
`main`). The tag is the single source of version: it drives the image tag and
`-ldflags` in the binaries so they cannot drift apart.
The release image is published **only** for a SemVer version `X.Y.Z`: a pushed
tag `vX.Y.Z`, or a `workflow_dispatch` that supplies that version (or runs on
such a tag). Ordinary commits, and a dispatch from `main` without a version
input, do not publish. The version is the single source that drives the image
tag and `-ldflags` in the binaries so they cannot drift apart.
**Steps (on explicit request):**
@@ -284,12 +290,17 @@ Workflows in [.github/workflows/](../.github/workflows/). What each job runs —
`gofmt -l``go vet ./...``go test ./...` (main module, no e2e).
### `release.yml` — push of tag `vX.Y.Z` or `workflow_dispatch`
### `release.yml` — push of tag `vX.Y.Z`, or `workflow_dispatch` with SemVer
`prepare` takes the version from the tag (`v1.2.5``1.2.5`) or from the
`workflow_dispatch` `version` input. A dispatch whose ref is not a `vX.Y.Z`
tag and whose input is missing or not `X.Y.Z` fails in `prepare` — it must
not publish `ghcr.io/...:main`.
```
prepare (version from tag)
prepare (version from tag or workflow_dispatch input)
→ build [matrix: ubuntu-latest / ubuntu-24.04-arm]
→ docker build --load (VERSION from tag)
→ docker build --load (VERSION from prepare)
→ e2e (test/e2e)
→ push ghcr.io/...:X.Y.Z-amd64 | X.Y.Z-arm64
→ merge
+11 -6
View File
@@ -594,13 +594,18 @@ the override.
**Model: Sonnet** for OFL/NOTICE prose; **Opus** for `release.yml`; **Haiku**
for SPDX consistency and deleting the done logrotate plan.
- [ ] Add SIL OFL 1.1 text beside the Plex WOFF2 files; point `NOTICE` at it.
- [ ] `NOTICE` Source URL instructions → `internal/legal/legal.go`.
- [ ] `release.yml`: `workflow_dispatch` must not publish `main` as a version
- [x] Add SIL OFL 1.1 text beside the Plex WOFF2 files; point `NOTICE` at it.
IBM Plex `LICENSE.txt` as `internal/web/view/static/OFL.txt` (copyright
+ OFL 1.1). Copied into the image at `/usr/share/doc/selfpost/OFL.txt`;
served at `/static/OFL.txt`.
- [x] `NOTICE` Source URL instructions → `internal/legal/legal.go`.
- [x] `release.yml`: `workflow_dispatch` must not publish `main` as a version
(require `vX.Y.Z` or an explicit `version` input that matches SemVer).
- [ ] Delete [plans/logrotate-mode.md](logrotate-mode.md) (done; git keeps it).
- [ ] Decide SPDX-everywhere vs SPDX-nowhere; do not leave two files special
without a one-line note in development.md.
- [x] Delete [plans/logrotate-mode.md](logrotate-mode.md) (done; git keeps it).
- [x] Decide SPDX-everywhere vs SPDX-nowhere; do not leave two files special
without a one-line note in development.md. SPDX-nowhere: dropped the
two `cmd/` headers; development.md § External libraries records that
AGPL-3.0 does not require per-file SPDX.
**Done when:** OFL travels with the fonts; a dispatch from `main` cannot tag
`ghcr.io/...:main`.
-28
View File
@@ -1,28 +0,0 @@
# Plan: logrotate-mode (mail.log stops rotating in some images)
**Status:** done
**Version:** patch; no schema, no configuration surface.
---
## Summary
`mail.log` stopped rotating when `/etc/logrotate.d/mail` landed in the image
with group/other write permission (e.g. build context from a Windows tar sync).
logrotate ignores such configs but exits 0, so the loop looked healthy while
the log grew without bound.
## What shipped
- [`build/Dockerfile`](../../build/Dockerfile): `COPY --chmod` pins config
(`0644`) and script (`0755`) modes so the image no longer depends on checkout
file modes.
- [`build/logrotate-loop.sh`](../../build/logrotate-loop.sh): preflight and
per-iteration checks refuse group/other-writable configs; logrotate stderr
mentioning `Ignoring` is fatal.
- [`test/e2e/logrotate_check.go`](../../test/e2e/logrotate_check.go): asserts
mode `644`, forced `logrotate -f`, and that a group-writable context file
still produces `644` in the image.
`create 0640 postfix selfpost` in [`build/logrotate-mail.conf`](../../build/logrotate-mail.conf)
is unchanged — required for panel readability after rotation.
+3
View File
@@ -59,6 +59,9 @@ Not inbound-relay, not DMARC ingestion, not a layer rewrite.
**Done when:** see the criteria in
[plans/code-review.md](plans/code-review.md).
**Progress:** P0P5 done. Remaining: P6 (optional cleanup), P7 (Fable review
of the P0P1 diff).
**Dependencies / risks:** P0 is confidentiality between panel roles; it
jumps the feature queue. Implementation models are in the plan (Opus / Sonnet
/ Haiku / Fable per [development.md](development.md)).