mikkeli 34a278870d feat: side-by-side columns shorthand (```columns fence)
Authors write a ```columns fenced block (columns separated by a line of
===); Pandoc passes the body through verbatim as <pre class="columns">,
and a new post-Pandoc transform in lib.wiki.expand_columns expands it
into a flex <div> of <poem> columns. Runs entirely Pi-side before the
MediaWiki API write — no wiki template or PHP extension required.

The transform lives in shared lib/wiki.py (called from markdown_to_wikitext),
so it is universal across all pipelines. Stdlib only; no new deps.

Docs: SCHEMA.md author contract + songs/root decision logs.
Also ignore __pycache__/.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 21:02:24 +09:00
2026-06-11 11:20:59 +09:00
2026-06-11 00:00:18 +09:00
2026-06-09 00:03:55 +00:00

novoyuuparosk-auto-wiki

CI/CD pipelines that auto-apply commits to https://wiki.novoyuuparosk.org from upstream content repos.

Pipelines

Path Source repo Purpose Status
pipelines/songs/ mikkeli/ncmr-songs Song lyric pages v1 live
pipelines/ses/ mikkeli/ses-light-novel SES light novel pages v1 in development
pipelines/tech/ mikkeli/tech-blogs Tech blog posts v1 live

Per-pipeline READMEs cover everything specific to that pipeline (source schema, renderer, runtime, decisions). This root README covers only what's cross-cutting.

Architecture

Hybrid layout. The Gitea Actions trigger must live in the source repo (Gitea only fires workflows from .gitea/workflows/ of the pushed-to repo); the rendering logic lives here. The source-repo workflow is self-contained but clones this repo at runtime to get the renderer.

<source-repo>/
  .gitea/workflows/<name>.yml       <- workflow: clones this repo, runs renderer (deps pre-baked in job image)

novoyuuparosk-auto-wiki/             <- this repo
  .gitea/workflows/<pipeline>.yml    <- reusable workflow stubs (kept for reference; not actively called; may be stale)
  pipelines/<pipeline>/              <- per-pipeline code, schema, templates
  lib/                               <- shared modules (MediaWiki client, etc.)

Note: workflow_call across private repos was abandoned — the auto-generated run token is scoped to the triggering repo only and cannot clone a private callee. The source-repo workflow clones this repo directly using FAPAT.

Wiki

Bot identity

MediaWiki BotPassword issued for user Dubrowski, bot name giteaAutomaton. Login form: Dubrowski@giteaAutomaton.

Credentials are stored in the Gitea user-scope secret vault under mikkeli (WIKI_BOT_USER, WIKI_BOT_PASSWORD). Not stored in this repo.

Runner infrastructure

One act_runner instance serves all pipelines. Runs on a Pi 5 (Raspberry Pi OS Bookworm, aarch64) inside the same docker-compose stack that hosts the Gitea instance. Job execution is via the host Docker socket — runner is a container, jobs spawn as sibling containers.

act_runner build: linux-arm64, from the gitea/act_runner Docker image.

Container network mode: host — required so job containers can reach localhost:3005 (Gitea) and resolve mDNS hostnames.

Job container image

All pipelines share a single pre-built Docker image, served from the Gitea registry at pi5-16.local:3005/mikkeli/novoyuuparosk-wiki-runner. The Dockerfile is at the repo root. It bakes in system deps (git, pandoc, ca-certificates) and all pipeline Python packages so job containers start instantly with no install steps.

The image builds automatically via .gitea/workflows/build-image.yml, which triggers on pushes that touch the Dockerfile, any pipeline requirements.txt, or that workflow itself. It uses kaniko (daemonless, unprivileged) to build and push two tags: an immutable :<short-sha> and a moving :latest.

A follow-up pin job then rewrites the image: pin in each publish-*.yml to the new :<short-sha> and commits it back to master (using FAPAT for contents write). The publish workflows therefore always reference an immutable tag, kept current automatically — no manual bump. The pin commit only touches workflow_call files, so it triggers no further runs.

Gitea Actions setup (cross-cutting)

Secrets and variables are scoped to user mikkeli (no orgs on this instance), inherited by all repos under that account.

Secrets:

  • WIKI_BOT_USER = Dubrowski@giteaAutomaton
  • WIKI_BOT_PASSWORD = the value from Bot identity above
  • FAPAT = Full-Access PAT under mikkeli, used by source-repo workflows to clone this repo at runtime

Variables:

  • WIKI_BASE_URL = https://wiki.novoyuuparosk.org
  • WIKI_API_URL = https://wiki.novoyuuparosk.org/api.php
  • URL_TO_GITEA = Gitea instance base URL (e.g. http://localhost:3005). Named with URL_TO_ prefix — Gitea blocks variable names starting with GITEA_ or GITHUB_.

Branch naming

  • This repo: automation/<pipeline-name> for pipeline-development branches (e.g., automation/songs).
  • Source repos: each pipeline's README defines the source-side branch convention (e.g., autowiki/<song-slug> in ncmr-songs).

Decisions log (cross-cutting)

Decision Value Date
Architecture Hybrid: source-repo workflow clones this repo at runtime for the renderer 2026-06-09
Workflow pattern Self-contained (not workflow_call) — cross-repo workflow_call blocked by token scoping on private repos 2026-06-09
Runner execution Docker, added as a service to the existing Gitea docker-compose 2026-06-09
Runner network mode host — job containers need to reach Gitea on localhost 2026-06-09
Secret/runner scope User-level on mikkeli (no orgs on this instance) 2026-06-09
MediaWiki API path api.php (classic action API) 2026-06-09
Branch naming (this repo) automation/<pipeline> for pipeline-development branches 2026-06-09
Variable naming URL_TO_GITEA not GITEA_URL — Gitea blocks GITEA_/GITHUB_ prefixes 2026-06-09
Columns shorthand Side-by-side columns authored as a ```columns fenced block, expanded post-Pandoc in shared lib/wiki.py (universal across pipelines). No wiki template or PHP extension — runs Pi-side before the API call 2026-06-14

Per-pipeline decisions live in each pipeline's README.

Setup checklist (cross-cutting)

Via the Gitea web UI logged in as mikkeli:

  • User-scoped secrets and variables set per Gitea Actions setup above
    • WIKI_BOT_USER
    • WIKI_BOT_PASSWORD
    • FAPAT (Full-Access PAT — value not stored in this README; saved directly into the Gitea secret. Regenerate if lost.)
    • WIKI_BASE_URL
    • WIKI_API_URL
    • URL_TO_GITEA

With Pi access:

  • Add act_runner service to the existing Gitea docker-compose
  • Generate a runner registration token at /-/admin/actions/runners, bake into the compose env, docker compose up -d act_runner, confirm "online" in the Gitea UI

Per-pipeline setup lives in each pipeline's README. Start with pipelines/songs/.

S
Description
CI/CD or in English auto-apply pipelines for the wiki
Readme WTFPL 270 KiB
Languages
Python 97.7%
Dockerfile 2.3%