feat(tech): add tech blog pipeline
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>
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
# pipelines/tech
|
||||
|
||||
Publishes tech blog posts from `mikkeli/tech-blogs` to `https://wiki.novoyuuparosk.org`.
|
||||
|
||||
- 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)
|
||||
- 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>]]` from `date` field; `[[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: true` silently 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:
|
||||
- `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) | 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.
|
||||
Reference in New Issue
Block a user