Files
github-action/docs/adr/adr-0004-shared-wiki-publishing-opt-in.md
Tirsvad 92396e23c9
Validate workflows / validate (pull_request) Successful in 15s
Resolve pending commit links in ADR-0004, RC-018 and TM-001
2026-10-10 11:34:14 +08:00

118 lines
5.2 KiB
Markdown

# ADR-0004: Opt-in rule and secret handling of the shared wiki publisher
## Metadata
| Key | Value |
| --- | --- |
| ID | ADR-0004 |
| CrossReference | [MIL-006], [ADR-0003], [ADR-0002] |
## Version History
| Date | Status | Author | Reviewer | Change | Commit |
| --- | --- | --- | --- | --- | --- |
| 2026-10-10 | Deprecated | Jens Tirsvad Nielsen | S01 | Initial version | [b22a2cd] |
| 2026-10-10 | Accepted | Jens Tirsvad Nielsen | S01 | Reviewed (RC-018): the `prune` variant added to the evaluated options | [b22a2cd] |
Allowed Status values: `Proposed`, `Accepted`, `Rejected`, `Deprecated`, `Superseded by ADR-NNNN`.
---
## Context
MIL-006 turns the Publish wiki workflow into a scoped workflow, which Gitea
runs in every repository of every organisation on the instance (verified,
issue #9). The publisher writes to a repository's wiki and removes pages that
are not in `wiki/`. Without a gate, any of the 26 repositories of
`Tirsvad-Udemy-100-days-of-code`, or any other repository, that happens to
have a `wiki/` folder would have its wiki overwritten or emptied by a
workflow it never asked for. The secret is also per organisation, so the
shared workflow must say what happens where it is missing, and
[ADR-0003] let this repository fall back to `TOKEN_FOR_GITEA`.
Options for how a repository opts in:
1. **A marker file `wiki/.publish`** on the default branch. Visible in the
repository, reviewed in a pull request, and nothing to configure in an
organisation. It comes in two forms:
- **(a) the marker alone** makes the wiki equal `wiki/`, so pages that are
not in the folder are deleted, as in ADR-0003;
- **(b) the marker plus the word `prune`** in it: without the word the
workflow only creates and updates pages, and deleting is a second,
explicit choice.
2. **A repository variable** (for example `PUBLISH_WIKI=true`). Not part of
the repository content, so it is not reviewed or versioned, and it has to
be set in the web interface once per repository.
3. **An allow list** in this repository. One place to read, but every
repository in every organisation has to ask this repository for a change.
4. **Publish whenever `wiki/` exists.** No setup, which is the risk the gate
is meant to remove.
Option 1(b) is chosen for the reason in the first paragraph: a repository
that adds `wiki/` to a wiki it wrote by hand should not lose that wiki by
opting in.
Options for the secret:
1. **`TOKEN_FOR_GITEA_WIKI` of the organisation only.** The sync token stays
read-only everywhere.
2. **Fall back to `TOKEN_FOR_GITEA`** as in ADR-0003. A missing wiki secret is
hidden until a write is refused (HTTP 403).
## Decision
A repository opts in by committing `wiki/.publish` on its default branch; the
file may contain the single word `prune`, which is the only thing that lets the
workflow delete wiki pages that are not in `wiki/`, and without the marker the
workflow ends successfully without any request. The shared workflow uses the
organisation's `TOKEN_FOR_GITEA_WIKI` only, and fails with a configuration
error when a repository has opted in and the secret is missing.
The rules that follow from it:
- Without `prune` the workflow only creates and updates pages.
- An empty `wiki/` (no Markdown page) never deletes anything, with or without
`prune`.
- A repository that has not opted in is skipped with one log line, so its
runs stay green.
- This repository commits `wiki/.publish` containing `prune`, because its wiki
must equal `wiki/` (ADR-0001, ADR-0003).
- The fallback to `TOKEN_FOR_GITEA` of ADR-0003 is removed from the shared
workflow; the sync token is read-only everywhere.
## Consequences
**Positive:**
- A repository that did not opt in is never written to, and the marker is a
reviewed change in the repository that wants it.
- Deleting pages is a second, explicit choice, so adopting the workflow in a
repository with hand-written wiki pages loses nothing.
- A missing wiki secret is reported where it happens, in the repository that
opted in, and the sync token never gets write access.
**Negative:**
- Each organisation that wants this needs its own `TOKEN_FOR_GITEA_WIKI`; it
cannot borrow the sync token.
- A repository that opts in without `prune` keeps pages that were removed from
`wiki/`, so its wiki can drift from the folder until someone adds `prune`.
- Anyone with write access to a repository can opt it in and, with `prune`,
make the workflow delete its wiki pages; that is the intended scope of write
access, but it is not a separate approval.
- The change supersedes the fallback part of [ADR-0003], so the credentials
guide and the wiki pages that mention it need an update (MIL-006 task 5).
## Affected Artifacts
- [MIL-006] — tasks 2, 3 and 4 (issues #57 to #59) implement and pilot this
decision.
- [ADR-0003] — its fallback to `TOKEN_FOR_GITEA` no longer applies to the
shared workflow.
- [ADR-0002] — the stand-in rule applies to the review of this ADR.
---
[MIL-006]: ../milestones/mil-006-shared-wiki-publishing.md
[ADR-0003]: ./adr-0003-wiki-publish-token.md
[ADR-0002]: ./adr-0002-s01-approves-as-stand-in.md
[b22a2cd]: https://git.tirsystem.com/TirSystem/github-action/commit/b22a2cd59235078656c4440b945b787f88fbd345