e1810facd6
tests / pytest (push) Successful in 7s
Every auto-published page, in all three pipelines, carried a source link to
`localhost:3005`. The template was never at fault — it links `{{{source}}}`
verbatim; the bad URL was baked into each page's wikitext by the publisher.
Root cause was one variable serving two incompatible purposes. `URL_TO_GITEA`
has to be an address the runner container can clone from, and since the runner
uses host networking that is `http://localhost:3005`. All three workflows then
composed `GITEA_REPO_URL` — the base of the public banner link, written into
the wiki for anyone to read — out of that same loopback value.
Adds a second org variable, `PUBLIC_URL_TO_GITEA`, for the public base
(`https://git.novoyuuparosk.org`), and points the banner at it. Cloning keeps
using `URL_TO_GITEA`. The two are now documented as deliberately separate,
because collapsing them looks like tidying up.
`lib/wiki.public_source_base()` validates the banner base rather than trusting
it: unset, relative, loopback, mDNS (`*.local`) or private-range values raise
with the variable to set. A misconfiguration that would publish an unreachable
link now stops the run instead. Note the failure mode this creates on purpose:
until `PUBLIC_URL_TO_GITEA` exists, publishing aborts rather than proceeding
with a wrong URL.
Also builds the source path with `rel.as_posix()`, so the separator in a URL
does not depend on the OS the publisher runs on — it produced backslashes when
the renderer was exercised on Windows.
Prerequisites before this can publish:
1. Add the org variable `PUBLIC_URL_TO_GITEA` = https://git.novoyuuparosk.org
2. Flush the act_runner callee cache — `docker compose up -d --force-recreate
act_runner`. Per the cross-cutting decisions log, edits to `publish-*.yml`
keep executing the stale cached copy, and this change is in those files.
Pages already published still carry the old URL in their stored wikitext. They
are only corrected by re-publishing each pipeline in full.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
85 lines
4.2 KiB
Markdown
85 lines
4.2 KiB
Markdown
# pipelines/ses
|
|
|
|
Publishes SES light novel pages from `novoyuuparosk-wiki/ses-light-novel` to `https://wiki.novoyuuparosk.org` under the `SES:` namespace.
|
|
|
|
- Source-file contract (frontmatter and body conventions): [SCHEMA.md](SCHEMA.md)
|
|
- Cross-cutting setup (wiki URL, bot identity, runner, Gitea secrets/variables): [repo root README](../../README.md)
|
|
|
|
## v1 scope
|
|
|
|
- YAML frontmatter parsing per [SCHEMA.md](SCHEMA.md)
|
|
- `SES:` title prefix — all pages live in the SES MediaWiki namespace
|
|
- Pandoc-based markdown → wikitext body rendering
|
|
- Auto-generated banner (`{{Auto-generated|source=...|commit=<sha>}}`)
|
|
- Category injection: `[[Category:SES]]` + `[[Category:SES:<type>]]` on every page; type from `type:` field, falling back to the file's parent directory name
|
|
- Additional categories via optional `categories` list
|
|
- MediaWiki bot API write with idempotency — no-op if wiki content matches generated output
|
|
- Files without `wiki.publish: true` silently skipped
|
|
- Pages with existing non-auto-generated content skipped (logged to stderr)
|
|
|
|
Not in scope (intentional):
|
|
|
|
- Sibling/cross-page link resolution — write wikilinks directly in the markdown body
|
|
- Companion file uploads
|
|
|
|
## Source repo and branch convention
|
|
|
|
Source repo: `novoyuuparosk-wiki/ses-light-novel`. The pipeline triggers on push to `master`.
|
|
|
|
No branch convention enforced — work directly on `master` or use whatever branch workflow suits.
|
|
|
|
**Excluded paths** (won't trigger the pipeline):
|
|
|
|
- `README.md`, `.gitignore`, `.claude/**`
|
|
|
|
## Invocation
|
|
|
|
The pipeline runs as a self-contained Gitea Actions workflow in `novoyuuparosk-wiki/ses-light-novel` (`.gitea/workflows/publish.yml`). It clones this repo at runtime to get the renderer.
|
|
|
|
Triggers:
|
|
- `push` to `master` (path-filtered as above)
|
|
- `workflow_dispatch` — manual trigger from the Gitea Actions UI
|
|
|
|
### Environment (secrets and variables)
|
|
|
|
| Name | Kind | Source | Purpose |
|
|
|---|---|---|---|
|
|
| `WIKI_API_URL` | variable | Gitea (cross-cutting) | MediaWiki action API endpoint |
|
|
| `WIKI_BASE_URL` | variable | Gitea (cross-cutting) | Wiki base URL |
|
|
| `WIKI_BOT_USER` | secret | Gitea (cross-cutting) | Bot login |
|
|
| `WIKI_BOT_PASSWORD` | secret | Gitea (cross-cutting) | BotPasswords value |
|
|
| `URL_TO_GITEA` | variable | Gitea (cross-cutting) | Runner-internal Gitea base URL, for cloning only |
|
|
| `PUBLIC_URL_TO_GITEA` | variable | Gitea (cross-cutting) | Public Gitea base URL, for the banner source link only |
|
|
| `FAPAT` | secret | Gitea (cross-cutting) | Full-Access PAT for cloning private repos |
|
|
| `SOURCE_REF` | env (set in workflow) | `github.sha` | Pushed commit SHA, used in banner and edit summary |
|
|
| `GITEA_REPO_URL` | env (set in workflow) | `PUBLIC_URL_TO_GITEA` + repo path | Source-file URL base for the banner link. Validated by `public_source_base()`: a loopback, mDNS or private-range host aborts the run rather than publishing an unreachable link |
|
|
|
|
## Dependencies
|
|
|
|
Job container: `novoyuuparosk-wiki-runner:latest` (pre-built, stored in the local Docker daemon on the runner host). Bakes in Python 3.12, Pandoc, and all pipeline Python packages — no install steps at job runtime.
|
|
|
|
See the `Dockerfile` at the repo root and `requirements.txt` in this directory. Rebuild the image after changes to either.
|
|
|
|
Shared code lives in `lib/wiki.py` (repo root).
|
|
|
|
## One-off wiki setup
|
|
|
|
- [ ] **`Template:Auto-generated`** — must exist on the wiki (shared with songs pipeline; already created).
|
|
|
|
## Decisions log (ses pipeline)
|
|
|
|
| Decision | Value | Date |
|
|
|---|---|---|
|
|
| Namespace | All pages prefixed `SES:` — auto-applied by renderer, not written in source `title:` | 2026-06-10 |
|
|
| Type resolution | `type:` frontmatter field; falls back to immediate parent directory name | 2026-06-10 |
|
|
| Categories | `Category:SES` + `Category:SES:<type>` on every page | 2026-06-10 |
|
|
| Sibling links | Not implemented — write `[[SES:Page title]]` wikilinks directly in the body | 2026-06-10 |
|
|
| WIP exclusion | None — `wiki.publish: false` is the only gate | 2026-06-10 |
|
|
| Publish mode | Always `--all` | 2026-06-10 |
|
|
| Idempotency | Commit SHA in banner, not timestamp | 2026-06-10 |
|
|
| Manual-page protection | Bot skips pages without `{{Auto-generated` banner | 2026-06-10 |
|
|
|
|
## Status
|
|
|
|
v1 in development.
|