Publishes mikkeli/tech-blogs to the wiki at bare titles (no prefix). Every page gets Category:Tech blog; Category:Blog:<year> from the date field; Category:<tag> per tag entry (no prefix). Fields: title (required), wiki.publish (required), date (optional, YYYY-MM-DD), tags (optional list). Source repo tech-blogs not yet initialised — pipeline ships first. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
pipelines/tech
Publishes tech blog posts from mikkeli/tech-blogs to https://wiki.novoyuuparosk.org.
- Source-file contract (frontmatter and body conventions): SCHEMA.md
- Cross-cutting setup (wiki URL, bot identity, runner, Gitea secrets/variables): repo root README
v1 scope
- YAML frontmatter parsing per SCHEMA.md
- Pandoc-based markdown → wikitext body rendering
- First-line h1 stripping
- Auto-generated banner (
{{Auto-generated|source=...|commit=<sha>}}) - Category injection:
[[Category:Tech blog]]on every page;[[Category:Blog:<year>]]fromdatefield;[[Category:<tag>]]per tag entry - No title prefix — pages live at their bare title
- MediaWiki bot API write with idempotency — no-op if wiki content matches generated output
- Files without
wiki.publish: truesilently skipped - Pages with existing non-auto-generated content skipped (logged to stderr)
Source repo
Source repo: mikkeli/tech-blogs (not yet initialised — pipeline code is ready).
The pipeline triggers on push to master and supports workflow_dispatch for manual runs.
Excluded paths (won't trigger the pipeline):
README.md,.gitignore,.claude/**
Invocation
The pipeline runs as a self-contained Gitea Actions workflow in mikkeli/tech-blogs (.gitea/workflows/publish.yml). It clones this repo at runtime to get the renderer.
Triggers:
pushtomaster(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) | Gitea instance base URL for cloning |
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) | composed from vars | Source-file URL base for the banner 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 all pipelines; already created).
Decisions log (tech pipeline)
| Decision | Value | Date |
|---|---|---|
| No title prefix | Tech posts live at bare titles — no namespace needed | 2026-06-10 |
| Fixed category | Every post gets Category:Tech blog |
2026-06-10 |
| Year category | Category:Blog:<year> from date field; omitted if no date |
2026-06-10 |
| Tag categories | Each tag → [[Category:<tag>]] with no prefix |
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 | 2026-06-10 |
| Manual-page protection | Bot skips pages without {{Auto-generated banner |
2026-06-10 |
| Source repo | mikkeli/tech-blogs — pipeline ships before repo is initialised |
2026-06-10 |
Status
v1 pipeline ready. Source repo (mikkeli/tech-blogs) not yet initialised.