Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4e7d84d665 | |||
| e4ae304954 | |||
| bdca12837e | |||
| 4f134af7bc | |||
| 905a1051a8 | |||
| 4919ce9450 | |||
| 03be97799d | |||
| 01901b3821 | |||
| 6dc9f68b12 | |||
| 83a5d86115 | |||
| 2072db4980 | |||
| 00527e46b1 |
@@ -14,6 +14,9 @@ jobs:
|
|||||||
# Daemonless image builder: kaniko :debug plus the /bin/sleep symlink
|
# Daemonless image builder: kaniko :debug plus the /bin/sleep symlink
|
||||||
# act needs for job-container PID 1 (see ci/Dockerfile.kaniko-act).
|
# act needs for job-container PID 1 (see ci/Dockerfile.kaniko-act).
|
||||||
# No docker socket, no privileges.
|
# No docker socket, no privileges.
|
||||||
|
# Deliberately the `mikkeli` copy: the org rebuild of kaniko-act loses
|
||||||
|
# /tmp (kaniko does not persist the empty dir), which breaks the wget
|
||||||
|
# below. See build-kaniko-act.yml. Do not repoint without testing.
|
||||||
image: pi5-16.local:3005/mikkeli/kaniko-act:v1.23.2-r2
|
image: pi5-16.local:3005/mikkeli/kaniko-act:v1.23.2-r2
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -30,12 +33,12 @@ jobs:
|
|||||||
set -eu
|
set -eu
|
||||||
HOST="${URL_TO_GITEA#http://}"
|
HOST="${URL_TO_GITEA#http://}"
|
||||||
SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7)
|
SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7)
|
||||||
IMAGE="${HOST}/mikkeli/novoyuuparosk-wiki-runner"
|
IMAGE="${HOST}/novoyuuparosk-wiki/novoyuuparosk-wiki-runner"
|
||||||
|
|
||||||
# Source via Gitea archive API (no git/node in this image; repo is
|
# Source via Gitea archive API (no git/node in this image; repo is
|
||||||
# private — authenticate with the job's own per-run token)
|
# private — authenticate with the job's own per-run token)
|
||||||
wget -qO /tmp/src.tar.gz \
|
wget -qO /tmp/src.tar.gz \
|
||||||
"http://mikkeli:${JOB_TOKEN}@${HOST}/api/v1/repos/mikkeli/novoyuuparosk-auto-wiki/archive/${GITHUB_SHA}.tar.gz"
|
"http://mikkeli:${JOB_TOKEN}@${HOST}/api/v1/repos/novoyuuparosk-wiki/novoyuuparosk-auto-wiki/archive/${GITHUB_SHA}.tar.gz"
|
||||||
mkdir -p /tmp/src
|
mkdir -p /tmp/src
|
||||||
tar -xzf /tmp/src.tar.gz -C /tmp/src --strip-components=1
|
tar -xzf /tmp/src.tar.gz -C /tmp/src --strip-components=1
|
||||||
|
|
||||||
@@ -64,7 +67,7 @@ jobs:
|
|||||||
# Freshly built runner image: git + GNU sed baked in, and it has no
|
# Freshly built runner image: git + GNU sed baked in, and it has no
|
||||||
# non-shell ENTRYPOINT, so it works as a job container as-is (unlike the
|
# non-shell ENTRYPOINT, so it works as a job container as-is (unlike the
|
||||||
# kaniko image above). Pulls :latest that the build job just pushed.
|
# kaniko image above). Pulls :latest that the build job just pushed.
|
||||||
image: pi5-16.local:3005/mikkeli/novoyuuparosk-wiki-runner:latest
|
image: pi5-16.local:3005/novoyuuparosk-wiki/novoyuuparosk-wiki-runner:latest
|
||||||
steps:
|
steps:
|
||||||
- name: Repoint publish workflows at the new image tag
|
- name: Repoint publish workflows at the new image tag
|
||||||
env:
|
env:
|
||||||
@@ -77,7 +80,7 @@ jobs:
|
|||||||
HOST="${URL_TO_GITEA#http://}"
|
HOST="${URL_TO_GITEA#http://}"
|
||||||
SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7)
|
SHORT_SHA=$(echo "${GITHUB_SHA}" | cut -c1-7)
|
||||||
|
|
||||||
git clone "http://mikkeli:${FAPAT}@${HOST}/mikkeli/novoyuuparosk-auto-wiki" repo
|
git clone "http://mikkeli:${FAPAT}@${HOST}/novoyuuparosk-wiki/novoyuuparosk-auto-wiki" repo
|
||||||
cd repo
|
cd repo
|
||||||
|
|
||||||
for f in .gitea/workflows/publish-songs.yml \
|
for f in .gitea/workflows/publish-songs.yml \
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
# Rebuilds the kaniko-act builder image.
|
||||||
|
#
|
||||||
|
# Dispatch-only on purpose. This is the image build-image.yml runs inside, so
|
||||||
|
# an automatic trigger could push a broken builder and take the whole build
|
||||||
|
# path down with it. Bump deliberately, verify, then repoint build-image.yml.
|
||||||
|
#
|
||||||
|
# Self-hosting: builds the new kaniko-act using the *previous* kaniko-act, per
|
||||||
|
# the bootstrap note in ci/Dockerfile.kaniko-act.
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
VERSION:
|
||||||
|
description: "Tag to publish, e.g. v1.23.2-r2"
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
default: v1.23.2-r2
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
# The `mikkeli` copy is the only known-good kaniko-act: it was built on
|
||||||
|
# the host with docker. The org copy this workflow produced exits 0 but
|
||||||
|
# lacks /tmp, so it cannot build anything — do not point here at it.
|
||||||
|
#
|
||||||
|
# This workflow is consequently NOT usable as-is for a version bump. Fix
|
||||||
|
# ci/Dockerfile.kaniko-act to force /tmp to materialise first, or build
|
||||||
|
# on the host. Kept because the destination and auth wiring are correct.
|
||||||
|
image: pi5-16.local:3005/mikkeli/kaniko-act:v1.23.2-r2
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Fetch source, build, push
|
||||||
|
# kaniko image has no bash — busybox sh only
|
||||||
|
shell: sh
|
||||||
|
env:
|
||||||
|
# package r/w PAT (org-level secret) — registry push only
|
||||||
|
PKG_TOKEN: ${{ secrets.PKGRW_PAT }}
|
||||||
|
# per-run auto-token, read access to this repo only — source fetch
|
||||||
|
JOB_TOKEN: ${{ github.token }}
|
||||||
|
URL_TO_GITEA: ${{ vars.URL_TO_GITEA }}
|
||||||
|
VERSION: ${{ inputs.VERSION }}
|
||||||
|
run: |
|
||||||
|
set -eu
|
||||||
|
HOST="${URL_TO_GITEA#http://}"
|
||||||
|
IMAGE="${HOST}/novoyuuparosk-wiki/kaniko-act"
|
||||||
|
|
||||||
|
wget -qO /tmp/src.tar.gz \
|
||||||
|
"http://mikkeli:${JOB_TOKEN}@${HOST}/api/v1/repos/novoyuuparosk-wiki/novoyuuparosk-auto-wiki/archive/${GITHUB_SHA}.tar.gz"
|
||||||
|
mkdir -p /tmp/src
|
||||||
|
tar -xzf /tmp/src.tar.gz -C /tmp/src --strip-components=1
|
||||||
|
|
||||||
|
# Registry auth for the push
|
||||||
|
AUTH=$(printf '%s' "mikkeli:${PKG_TOKEN}" | base64 | tr -d '\n')
|
||||||
|
printf '{"auths":{"%s":{"auth":"%s"}}}' "${HOST}" "${AUTH}" \
|
||||||
|
> /kaniko/.docker/config.json
|
||||||
|
|
||||||
|
# --insecure: push target is the plain-HTTP Gitea registry.
|
||||||
|
# Base image pull (gcr.io) stays HTTPS — no --insecure-pull.
|
||||||
|
/kaniko/executor \
|
||||||
|
--context dir:///tmp/src \
|
||||||
|
--dockerfile /tmp/src/ci/Dockerfile.kaniko-act \
|
||||||
|
--destination "${IMAGE}:${VERSION}" \
|
||||||
|
--insecure
|
||||||
|
|
||||||
|
echo "Pushed ${IMAGE}:${VERSION}"
|
||||||
@@ -10,7 +10,7 @@ jobs:
|
|||||||
publish:
|
publish:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: pi5-16.local:3005/mikkeli/novoyuuparosk-wiki-runner:b2714ab
|
image: pi5-16.local:3005/novoyuuparosk-wiki/novoyuuparosk-wiki-runner:4f134af
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout ses-light-novel
|
- name: Checkout ses-light-novel
|
||||||
@@ -18,14 +18,14 @@ jobs:
|
|||||||
FAPAT: ${{ secrets.FAPAT }}
|
FAPAT: ${{ secrets.FAPAT }}
|
||||||
URL_TO_GITEA: ${{ vars.URL_TO_GITEA }}
|
URL_TO_GITEA: ${{ vars.URL_TO_GITEA }}
|
||||||
run: |
|
run: |
|
||||||
git clone "http://mikkeli:${FAPAT}@${URL_TO_GITEA#http://}/mikkeli/ses-light-novel" ses-light-novel
|
git clone "http://mikkeli:${FAPAT}@${URL_TO_GITEA#http://}/novoyuuparosk-wiki/ses-light-novel" ses-light-novel
|
||||||
git -C ses-light-novel checkout ${{ inputs.SOURCE_REF }}
|
git -C ses-light-novel checkout ${{ inputs.SOURCE_REF }}
|
||||||
|
|
||||||
- name: Checkout auto-wiki
|
- name: Checkout auto-wiki
|
||||||
env:
|
env:
|
||||||
FAPAT: ${{ secrets.FAPAT }}
|
FAPAT: ${{ secrets.FAPAT }}
|
||||||
URL_TO_GITEA: ${{ vars.URL_TO_GITEA }}
|
URL_TO_GITEA: ${{ vars.URL_TO_GITEA }}
|
||||||
run: git clone "http://mikkeli:${FAPAT}@${URL_TO_GITEA#http://}/mikkeli/novoyuuparosk-auto-wiki" auto-wiki
|
run: git clone "http://mikkeli:${FAPAT}@${URL_TO_GITEA#http://}/novoyuuparosk-wiki/novoyuuparosk-auto-wiki" auto-wiki
|
||||||
|
|
||||||
- name: Publish
|
- name: Publish
|
||||||
env:
|
env:
|
||||||
@@ -34,7 +34,7 @@ jobs:
|
|||||||
WIKI_BOT_USER: ${{ secrets.WIKI_BOT_USER }}
|
WIKI_BOT_USER: ${{ secrets.WIKI_BOT_USER }}
|
||||||
WIKI_BOT_PASSWORD: ${{ secrets.WIKI_BOT_PASSWORD }}
|
WIKI_BOT_PASSWORD: ${{ secrets.WIKI_BOT_PASSWORD }}
|
||||||
SOURCE_REF: ${{ inputs.SOURCE_REF }}
|
SOURCE_REF: ${{ inputs.SOURCE_REF }}
|
||||||
GITEA_REPO_URL: ${{ vars.URL_TO_GITEA }}/mikkeli/ses-light-novel
|
GITEA_REPO_URL: ${{ vars.URL_TO_GITEA }}/novoyuuparosk-wiki/ses-light-novel
|
||||||
run: |
|
run: |
|
||||||
python auto-wiki/pipelines/ses/publish.py \
|
python auto-wiki/pipelines/ses/publish.py \
|
||||||
--source-dir ses-light-novel \
|
--source-dir ses-light-novel \
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ jobs:
|
|||||||
publish:
|
publish:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: pi5-16.local:3005/mikkeli/novoyuuparosk-wiki-runner:b2714ab
|
image: pi5-16.local:3005/novoyuuparosk-wiki/novoyuuparosk-wiki-runner:4f134af
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout ncmr-songs
|
- name: Checkout ncmr-songs
|
||||||
@@ -27,14 +27,14 @@ jobs:
|
|||||||
FAPAT: ${{ secrets.FAPAT }}
|
FAPAT: ${{ secrets.FAPAT }}
|
||||||
URL_TO_GITEA: ${{ vars.URL_TO_GITEA }}
|
URL_TO_GITEA: ${{ vars.URL_TO_GITEA }}
|
||||||
run: |
|
run: |
|
||||||
git clone "http://mikkeli:${FAPAT}@${URL_TO_GITEA#http://}/mikkeli/ncmr-songs" ncmr-songs
|
git clone "http://mikkeli:${FAPAT}@${URL_TO_GITEA#http://}/novoyuuparosk-wiki/ncmr-songs" ncmr-songs
|
||||||
git -C ncmr-songs checkout ${{ inputs.SOURCE_REF }}
|
git -C ncmr-songs checkout ${{ inputs.SOURCE_REF }}
|
||||||
|
|
||||||
- name: Checkout auto-wiki
|
- name: Checkout auto-wiki
|
||||||
env:
|
env:
|
||||||
FAPAT: ${{ secrets.FAPAT }}
|
FAPAT: ${{ secrets.FAPAT }}
|
||||||
URL_TO_GITEA: ${{ vars.URL_TO_GITEA }}
|
URL_TO_GITEA: ${{ vars.URL_TO_GITEA }}
|
||||||
run: git clone "http://mikkeli:${FAPAT}@${URL_TO_GITEA#http://}/mikkeli/novoyuuparosk-auto-wiki" auto-wiki
|
run: git clone "http://mikkeli:${FAPAT}@${URL_TO_GITEA#http://}/novoyuuparosk-wiki/novoyuuparosk-auto-wiki" auto-wiki
|
||||||
|
|
||||||
- name: Detect changed files
|
- name: Detect changed files
|
||||||
id: diff
|
id: diff
|
||||||
@@ -62,7 +62,7 @@ jobs:
|
|||||||
WIKI_BOT_USER: ${{ secrets.WIKI_BOT_USER }}
|
WIKI_BOT_USER: ${{ secrets.WIKI_BOT_USER }}
|
||||||
WIKI_BOT_PASSWORD: ${{ secrets.WIKI_BOT_PASSWORD }}
|
WIKI_BOT_PASSWORD: ${{ secrets.WIKI_BOT_PASSWORD }}
|
||||||
SOURCE_REF: ${{ inputs.SOURCE_REF }}
|
SOURCE_REF: ${{ inputs.SOURCE_REF }}
|
||||||
GITEA_REPO_URL: ${{ vars.URL_TO_GITEA }}/mikkeli/ncmr-songs
|
GITEA_REPO_URL: ${{ vars.URL_TO_GITEA }}/novoyuuparosk-wiki/ncmr-songs
|
||||||
run: |
|
run: |
|
||||||
MODE="${{ steps.diff.outputs.mode }}"
|
MODE="${{ steps.diff.outputs.mode }}"
|
||||||
if [ "$MODE" = "all" ] || [ "${{ inputs.FULL_PUBLISH }}" = "true" ]; then
|
if [ "$MODE" = "all" ] || [ "${{ inputs.FULL_PUBLISH }}" = "true" ]; then
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ jobs:
|
|||||||
publish:
|
publish:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
container:
|
container:
|
||||||
image: pi5-16.local:3005/mikkeli/novoyuuparosk-wiki-runner:b2714ab
|
image: pi5-16.local:3005/novoyuuparosk-wiki/novoyuuparosk-wiki-runner:4f134af
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout tech-blogs
|
- name: Checkout tech-blogs
|
||||||
@@ -18,14 +18,14 @@ jobs:
|
|||||||
FAPAT: ${{ secrets.FAPAT }}
|
FAPAT: ${{ secrets.FAPAT }}
|
||||||
URL_TO_GITEA: ${{ vars.URL_TO_GITEA }}
|
URL_TO_GITEA: ${{ vars.URL_TO_GITEA }}
|
||||||
run: |
|
run: |
|
||||||
git clone "http://mikkeli:${FAPAT}@${URL_TO_GITEA#http://}/mikkeli/tech-blogs" tech-blogs
|
git clone "http://mikkeli:${FAPAT}@${URL_TO_GITEA#http://}/novoyuuparosk-wiki/tech-blogs" tech-blogs
|
||||||
git -C tech-blogs checkout ${{ inputs.SOURCE_REF }}
|
git -C tech-blogs checkout ${{ inputs.SOURCE_REF }}
|
||||||
|
|
||||||
- name: Checkout auto-wiki
|
- name: Checkout auto-wiki
|
||||||
env:
|
env:
|
||||||
FAPAT: ${{ secrets.FAPAT }}
|
FAPAT: ${{ secrets.FAPAT }}
|
||||||
URL_TO_GITEA: ${{ vars.URL_TO_GITEA }}
|
URL_TO_GITEA: ${{ vars.URL_TO_GITEA }}
|
||||||
run: git clone "http://mikkeli:${FAPAT}@${URL_TO_GITEA#http://}/mikkeli/novoyuuparosk-auto-wiki" auto-wiki
|
run: git clone "http://mikkeli:${FAPAT}@${URL_TO_GITEA#http://}/novoyuuparosk-wiki/novoyuuparosk-auto-wiki" auto-wiki
|
||||||
|
|
||||||
- name: Publish
|
- name: Publish
|
||||||
env:
|
env:
|
||||||
@@ -34,7 +34,7 @@ jobs:
|
|||||||
WIKI_BOT_USER: ${{ secrets.WIKI_BOT_USER }}
|
WIKI_BOT_USER: ${{ secrets.WIKI_BOT_USER }}
|
||||||
WIKI_BOT_PASSWORD: ${{ secrets.WIKI_BOT_PASSWORD }}
|
WIKI_BOT_PASSWORD: ${{ secrets.WIKI_BOT_PASSWORD }}
|
||||||
SOURCE_REF: ${{ inputs.SOURCE_REF }}
|
SOURCE_REF: ${{ inputs.SOURCE_REF }}
|
||||||
GITEA_REPO_URL: ${{ vars.URL_TO_GITEA }}/mikkeli/tech-blogs
|
GITEA_REPO_URL: ${{ vars.URL_TO_GITEA }}/novoyuuparosk-wiki/tech-blogs
|
||||||
run: |
|
run: |
|
||||||
python auto-wiki/pipelines/tech/publish.py \
|
python auto-wiki/pipelines/tech/publish.py \
|
||||||
--source-dir tech-blogs \
|
--source-dir tech-blogs \
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ CI/CD pipelines that auto-apply commits to https://wiki.novoyuuparosk.org from u
|
|||||||
|
|
||||||
| Path | Source repo | Purpose | Status |
|
| Path | Source repo | Purpose | Status |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| [`pipelines/songs/`](pipelines/songs/) | `mikkeli/ncmr-songs` | Song lyric pages | v1 live |
|
| [`pipelines/songs/`](pipelines/songs/) | `novoyuuparosk-wiki/ncmr-songs` | Song lyric pages | v1 live |
|
||||||
| [`pipelines/ses/`](pipelines/ses/) | `mikkeli/ses-light-novel` | SES light novel pages | v1 in development |
|
| [`pipelines/ses/`](pipelines/ses/) | `novoyuuparosk-wiki/ses-light-novel` | SES light novel pages | v1 in development |
|
||||||
| [`pipelines/tech/`](pipelines/tech/) | `mikkeli/tech-blogs` | Tech blog posts | v1 live |
|
| [`pipelines/tech/`](pipelines/tech/) | `novoyuuparosk-wiki/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.
|
Per-pipeline READMEs cover everything specific to that pipeline (source schema, renderer, runtime, decisions). This root README covers only what's cross-cutting.
|
||||||
|
|
||||||
@@ -35,9 +35,13 @@ Note: `workflow_call` across private repos was abandoned — the auto-generated
|
|||||||
|
|
||||||
## Bot identity
|
## Bot identity
|
||||||
|
|
||||||
MediaWiki BotPassword issued for user `Dubrowski`, bot name `giteaAutomaton`. Login form: `Dubrowski@giteaAutomaton`.
|
MediaWiki BotPassword issued for user `Mikkeli`, bot name `giteaBot`. Login form: `Mikkeli@giteaBot`.
|
||||||
|
|
||||||
Credentials are stored in the Gitea user-scope secret vault under `mikkeli` (`WIKI_BOT_USER`, `WIKI_BOT_PASSWORD`). Not stored in this repo.
|
`Mikkeli` holds the `bot` right, so pipeline edits are flagged as bot edits and stay out of default Recent Changes — `mwclient`'s `page.save()` requests the bot flag and the wiki honours it.
|
||||||
|
|
||||||
|
This section previously named `Dubrowski@giteaAutomaton`, but every bot-flagged revision in the wiki's history is attributed to `Mikkeli`, so that had been stale for some time — the live secret never matched the doc.
|
||||||
|
|
||||||
|
Credentials are stored in the Gitea org-scope secret vault under `novoyuuparosk-wiki` (`WIKI_BOT_USER`, `WIKI_BOT_PASSWORD`). Not stored in this repo.
|
||||||
|
|
||||||
## Runner infrastructure
|
## Runner infrastructure
|
||||||
|
|
||||||
@@ -49,7 +53,7 @@ Container network mode: `host` — required so job containers can reach `localho
|
|||||||
|
|
||||||
### Job container image
|
### 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.
|
All pipelines share a single pre-built Docker image, served from the Gitea registry at `pi5-16.local:3005/novoyuuparosk-wiki/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`](.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`.
|
The image builds automatically via [`.gitea/workflows/build-image.yml`](.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`.
|
||||||
|
|
||||||
@@ -57,12 +61,13 @@ A follow-up `pin` job then rewrites the `image:` pin in each `publish-*.yml` to
|
|||||||
|
|
||||||
## Gitea Actions setup (cross-cutting)
|
## 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 and variables are scoped to the `novoyuuparosk-wiki` org, inherited by all repos under it. Runs belong to the *caller* repo, so a source repo calling a reusable workflow here resolves secrets and variables from its own owner — which is why they live at org scope rather than on this repo.
|
||||||
|
|
||||||
**Secrets:**
|
**Secrets:**
|
||||||
- `WIKI_BOT_USER` = `Dubrowski@giteaAutomaton`
|
- `WIKI_BOT_USER` = `Mikkeli@giteaBot`
|
||||||
- `WIKI_BOT_PASSWORD` = the value from *Bot identity* above
|
- `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
|
- `FAPAT` = Full-Access PAT owned by `mikkeli`, used by source-repo workflows to clone this repo at runtime. The PAT stays personal; only its storage scope moved to the org — hence the `mikkeli:` basic-auth username in the clone URLs.
|
||||||
|
- `PKGRW_PAT` = package read/write PAT owned by `mikkeli`, used by `build-image.yml` to push to the container registry
|
||||||
|
|
||||||
**Variables:**
|
**Variables:**
|
||||||
- `WIKI_BASE_URL` = `https://wiki.novoyuuparosk.org`
|
- `WIKI_BASE_URL` = `https://wiki.novoyuuparosk.org`
|
||||||
@@ -83,6 +88,13 @@ Secrets and variables are scoped to user `mikkeli` (no orgs on this instance), i
|
|||||||
| Runner execution | Docker, added as a service to the existing Gitea docker-compose | 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 |
|
| 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 |
|
| Secret/runner scope | User-level on `mikkeli` (no orgs on this instance) | 2026-06-09 |
|
||||||
|
| Ownership | This repo and all three source repos moved to the `novoyuuparosk-wiki` org. Secrets/variables re-created at org scope; runner re-registered instance-level so it serves org-owned runs | 2026-08-11 |
|
||||||
|
| **This repo must stay public** | `act_runner` resolves a cross-repo `uses:` by cloning the callee **anonymously** — the job token is not applied. A private callee therefore 404s with `repository not found`, regardless of the caller sharing its owner. Shared ownership does **not** satisfy the read requirement. Alternative if it must be private again: Settings → Actions → General → collaborative owners (Gitea 1.26+), untested here | 2026-08-11 |
|
||||||
|
| Runner cache masks this | The resolved callee is cached at `/root/.cache/act/<owner>-<repo>@<ref>`. Changing owner changes the key, so a working pipeline can break on a clone that had been served from cache for months. Suspect the cache before suspecting permissions | 2026-08-11 |
|
||||||
|
| **Callee edits need a cache flush** | The cache is *not* refreshed per run. Edits to `publish-*.yml` on `master` — including the pin job's own commits — keep executing the stale cached copy until the key changes or the cache is cleared. Observed directly: a run used the previous namespace and tag despite `master` being current. Flush with `docker compose up -d --force-recreate act_runner`; the cache is in the container layer, while `.runner` is in the `/data` volume, so registration survives | 2026-08-11 |
|
||||||
|
| kaniko cannot rebuild kaniko-act | The org rebuild exits 0 but the resulting image has no `/tmp` — kaniko does not persist the empty dir from `mkdir -p -m 1777 /tmp`, so `wget -O /tmp/...` fails. The bootstrap note's claim that version bumps "can be built by the build-image workflow itself" does not hold as written. `kaniko-act` therefore still lives under `mikkeli`; a real bump needs a host `docker build` + push, or a Dockerfile that forces the dir to materialise (e.g. writing a file inside it) | 2026-08-11 |
|
||||||
|
| Container registry | Gitea cannot transfer packages, so images were *rebuilt* into `pi5-16.local:3005/novoyuuparosk-wiki/*` rather than moved. `kaniko-act` bootstrapped via the new dispatch-only `build-kaniko-act.yml`, running in the old `mikkeli` copy; `novoyuuparosk-wiki-runner` came from a normal `build-image.yml` run. Registry auth is still the `mikkeli`-owned `PKGRW_PAT`, hence the `mikkeli:` username in the auth blob | 2026-08-11 |
|
||||||
|
| Old images left in place | The `mikkeli/*` package versions are orphaned but retained — nothing references them, and deleting a container version is irreversible. Safe to purge once the org images have proven themselves | 2026-08-11 |
|
||||||
| MediaWiki API path | `api.php` (classic action API) | 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 |
|
| 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 |
|
| Variable naming | `URL_TO_GITEA` not `GITEA_URL` — Gitea blocks `GITEA_`/`GITHUB_` prefixes | 2026-06-09 |
|
||||||
@@ -92,9 +104,9 @@ Per-pipeline decisions live in each pipeline's README.
|
|||||||
|
|
||||||
## Setup checklist (cross-cutting)
|
## Setup checklist (cross-cutting)
|
||||||
|
|
||||||
Via the Gitea web UI logged in as `mikkeli`:
|
Via the Gitea web UI logged in as `mikkeli` (an owner of `novoyuuparosk-wiki`):
|
||||||
|
|
||||||
- [x] User-scoped secrets and variables set per *Gitea Actions setup* above
|
- [x] Org-scoped secrets and variables set per *Gitea Actions setup* above
|
||||||
- [x] `WIKI_BOT_USER`
|
- [x] `WIKI_BOT_USER`
|
||||||
- [x] `WIKI_BOT_PASSWORD`
|
- [x] `WIKI_BOT_PASSWORD`
|
||||||
- [x] `FAPAT` (Full-Access PAT — value not stored in this README; saved directly into the Gitea secret. Regenerate if lost.)
|
- [x] `FAPAT` (Full-Access PAT — value not stored in this README; saved directly into the Gitea secret. Regenerate if lost.)
|
||||||
|
|||||||
@@ -5,10 +5,11 @@
|
|||||||
# (busybox lives under /busybox; /bin/sh is already symlinked) nor /tmp.
|
# (busybox lives under /busybox; /bin/sh is already symlinked) nor /tmp.
|
||||||
# This wrapper adds exactly those two. Nothing else changes.
|
# This wrapper adds exactly those two. Nothing else changes.
|
||||||
#
|
#
|
||||||
# Bootstrap: the first build of this image is done manually on the host
|
# Bootstrap: the very first build of this image was done manually on the host
|
||||||
# (docker build -f ci/Dockerfile.kaniko-act -t <registry>/mikkeli/kaniko-act:<ver> .)
|
# (docker build -f ci/Dockerfile.kaniko-act -t <registry>/<owner>/kaniko-act:<ver> .)
|
||||||
# because no builder image exists yet. Later version bumps can be built by
|
# because no builder image existed yet. Version bumps are now built by
|
||||||
# the build-image workflow itself, using the previous kaniko-act.
|
# .gitea/workflows/build-kaniko-act.yml (dispatch-only), which runs in the
|
||||||
|
# previous kaniko-act — confirmed working when the image moved to the org.
|
||||||
FROM gcr.io/kaniko-project/executor:v1.23.2-debug
|
FROM gcr.io/kaniko-project/executor:v1.23.2-debug
|
||||||
SHELL ["/busybox/sh", "-c"]
|
SHELL ["/busybox/sh", "-c"]
|
||||||
RUN ln -sf /busybox/sleep /bin/sleep && mkdir -p -m 1777 /tmp
|
RUN ln -sf /busybox/sleep /bin/sleep && mkdir -p -m 1777 /tmp
|
||||||
|
|||||||
+20
-4
@@ -15,6 +15,20 @@ AUTO_BANNER_PREFIX = "{{Auto-generated"
|
|||||||
_COLUMNS_BLOCK_RE = re.compile(r'<pre class="columns">(.*?)</pre>', re.DOTALL)
|
_COLUMNS_BLOCK_RE = re.compile(r'<pre class="columns">(.*?)</pre>', re.DOTALL)
|
||||||
_COLUMN_SEP_RE = re.compile(r"^\s*===\s*$", re.MULTILINE)
|
_COLUMN_SEP_RE = re.compile(r"^\s*===\s*$", re.MULTILINE)
|
||||||
|
|
||||||
|
# Minimal Markdown emphasis → wikitext, for use inside a verbatim columns block
|
||||||
|
# (Pandoc doesn't process Markdown there). Asterisk style only, single line.
|
||||||
|
# Order matters: bold-italic (***) before bold (**) before italic (*).
|
||||||
|
_BOLD_ITALIC_RE = re.compile(r"\*\*\*(.+?)\*\*\*")
|
||||||
|
_BOLD_RE = re.compile(r"\*\*(.+?)\*\*")
|
||||||
|
_ITALIC_RE = re.compile(r"\*(.+?)\*")
|
||||||
|
|
||||||
|
|
||||||
|
def _md_emphasis_to_wikitext(text: str) -> str:
|
||||||
|
text = _BOLD_ITALIC_RE.sub(r"'''''\1'''''", text)
|
||||||
|
text = _BOLD_RE.sub(r"'''\1'''", text)
|
||||||
|
text = _ITALIC_RE.sub(r"''\1''", text)
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
def strip_first_h1(text: str) -> str:
|
def strip_first_h1(text: str) -> str:
|
||||||
"""Remove the first '# Heading' line and any immediately following blank line."""
|
"""Remove the first '# Heading' line and any immediately following blank line."""
|
||||||
@@ -35,13 +49,15 @@ def expand_columns(wikitext: str) -> str:
|
|||||||
through verbatim as ``<pre class="columns">…</pre>`` (line breaks and blank
|
through verbatim as ``<pre class="columns">…</pre>`` (line breaks and blank
|
||||||
lines preserved, inline markup entity-escaped). Columns within the block are
|
lines preserved, inline markup entity-escaped). Columns within the block are
|
||||||
separated by a line containing only ``===``. Each column is wrapped in
|
separated by a line containing only ``===``. Each column is wrapped in
|
||||||
<poem> so its line breaks survive MediaWiki parsing, and content is
|
<poem> so its line breaks survive MediaWiki parsing. Content is
|
||||||
HTML-unescaped so inline markup written in the fence (e.g. <b>…</b>) renders
|
HTML-unescaped (so inline markup such as <b>…</b> renders rather than
|
||||||
rather than appearing as literal text.
|
appearing as literal text) and Markdown emphasis (``*italic*``, ``**bold**``,
|
||||||
|
``***bold-italic***``) is converted to wikitext, since Pandoc does not
|
||||||
|
process Markdown inside the verbatim block.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def render(match: re.Match) -> str:
|
def render(match: re.Match) -> str:
|
||||||
body = html.unescape(match.group(1))
|
body = _md_emphasis_to_wikitext(html.unescape(match.group(1)))
|
||||||
columns = _COLUMN_SEP_RE.split(body)
|
columns = _COLUMN_SEP_RE.split(body)
|
||||||
poems = "".join("<poem>\n" + col.strip("\n") + "\n</poem>" for col in columns)
|
poems = "".join("<poem>\n" + col.strip("\n") + "\n</poem>" for col in columns)
|
||||||
return '<div style="display:flex; gap:3em; align-items:flex-start">' + poems + "</div>"
|
return '<div style="display:flex; gap:3em; align-items:flex-start">' + poems + "</div>"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# pipelines/ses
|
# pipelines/ses
|
||||||
|
|
||||||
Publishes SES light novel pages from `mikkeli/ses-light-novel` to `https://wiki.novoyuuparosk.org` under the `SES:` namespace.
|
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)
|
- 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)
|
- Cross-cutting setup (wiki URL, bot identity, runner, Gitea secrets/variables): [repo root README](../../README.md)
|
||||||
@@ -24,7 +24,7 @@ Not in scope (intentional):
|
|||||||
|
|
||||||
## Source repo and branch convention
|
## Source repo and branch convention
|
||||||
|
|
||||||
Source repo: `mikkeli/ses-light-novel`. The pipeline triggers on push to `master`.
|
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.
|
No branch convention enforced — work directly on `master` or use whatever branch workflow suits.
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ No branch convention enforced — work directly on `master` or use whatever bran
|
|||||||
|
|
||||||
## Invocation
|
## Invocation
|
||||||
|
|
||||||
The pipeline runs as a self-contained Gitea Actions workflow in `mikkeli/ses-light-novel` (`.gitea/workflows/publish.yml`). It clones this repo at runtime to get the renderer.
|
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:
|
Triggers:
|
||||||
- `push` to `master` (path-filtered as above)
|
- `push` to `master` (path-filtered as above)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# SCHEMA — SES light novel source files
|
# SCHEMA — SES light novel source files
|
||||||
|
|
||||||
Source-file contract for the SES pipeline. Files in `mikkeli/ses-light-novel` must follow this contract to be picked up by the auto-publisher.
|
Source-file contract for the SES pipeline. Files in `novoyuuparosk-wiki/ses-light-novel` must follow this contract to be picked up by the auto-publisher.
|
||||||
|
|
||||||
The schema lives entirely in the YAML frontmatter block at the top of each `.md` file. The body below the frontmatter is plain markdown, rendered to MediaWiki wikitext by Pandoc.
|
The schema lives entirely in the YAML frontmatter block at the top of each `.md` file. The body below the frontmatter is plain markdown, rendered to MediaWiki wikitext by Pandoc.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# pipelines/songs
|
# pipelines/songs
|
||||||
|
|
||||||
Publishes lyric pages from `mikkeli/ncmr-songs` to `https://wiki.novoyuuparosk.org`.
|
Publishes lyric pages from `novoyuuparosk-wiki/ncmr-songs` to `https://wiki.novoyuuparosk.org`.
|
||||||
|
|
||||||
- Source-file contract (frontmatter and body conventions): [SCHEMA.md](SCHEMA.md)
|
- 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)
|
- Cross-cutting setup (wiki URL, bot identity, runner, Gitea secrets/variables): [repo root README](../../README.md)
|
||||||
@@ -27,7 +27,7 @@ Not in scope (intentional):
|
|||||||
|
|
||||||
## Source repo and branch convention
|
## Source repo and branch convention
|
||||||
|
|
||||||
Source repo: `mikkeli/ncmr-songs`. The pipeline triggers on push to `master`.
|
Source repo: `novoyuuparosk-wiki/ncmr-songs`. The pipeline triggers on push to `master`.
|
||||||
|
|
||||||
**Branch convention in `ncmr-songs`**: per-song short-lived branches named `autowiki/<song-slug>` (e.g., `autowiki/pulse`). Create when staging edits, merge to master when ready to publish, delete after one cycle.
|
**Branch convention in `ncmr-songs`**: per-song short-lived branches named `autowiki/<song-slug>` (e.g., `autowiki/pulse`). Create when staging edits, merge to master when ready to publish, delete after one cycle.
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ Source repo: `mikkeli/ncmr-songs`. The pipeline triggers on push to `master`.
|
|||||||
|
|
||||||
## Invocation
|
## Invocation
|
||||||
|
|
||||||
The pipeline runs as a self-contained Gitea Actions workflow in `mikkeli/ncmr-songs` (`.gitea/workflows/publish.yml`). It clones this repo at runtime to get the renderer.
|
The pipeline runs as a self-contained Gitea Actions workflow in `novoyuuparosk-wiki/ncmr-songs` (`.gitea/workflows/publish.yml`). It clones this repo at runtime to get the renderer.
|
||||||
|
|
||||||
Triggers:
|
Triggers:
|
||||||
- `push` to `master` (path-filtered as above)
|
- `push` to `master` (path-filtered as above)
|
||||||
@@ -50,7 +50,7 @@ Triggers:
|
|||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| `WIKI_API_URL` | variable | Gitea (cross-cutting) | MediaWiki action API endpoint |
|
| `WIKI_API_URL` | variable | Gitea (cross-cutting) | MediaWiki action API endpoint |
|
||||||
| `WIKI_BASE_URL` | variable | Gitea (cross-cutting) | Wiki base URL |
|
| `WIKI_BASE_URL` | variable | Gitea (cross-cutting) | Wiki base URL |
|
||||||
| `WIKI_BOT_USER` | secret | Gitea (cross-cutting) | Bot login (`Dubrowski@giteaAutomaton`) |
|
| `WIKI_BOT_USER` | secret | Gitea (cross-cutting) | Bot login (`Mikkeli@giteaBot`) |
|
||||||
| `WIKI_BOT_PASSWORD` | secret | Gitea (cross-cutting) | BotPasswords value |
|
| `WIKI_BOT_PASSWORD` | secret | Gitea (cross-cutting) | BotPasswords value |
|
||||||
| `URL_TO_GITEA` | variable | Gitea (cross-cutting) | Gitea instance base URL for cloning |
|
| `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 |
|
| `FAPAT` | secret | Gitea (cross-cutting) | Full-Access PAT for cloning private repos |
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# SCHEMA — song source files
|
# SCHEMA — song source files
|
||||||
|
|
||||||
Source-file contract for the songs pipeline. Files in `mikkeli/ncmr-songs` must follow this contract to be picked up by the auto-publisher.
|
Source-file contract for the songs pipeline. Files in `novoyuuparosk-wiki/ncmr-songs` must follow this contract to be picked up by the auto-publisher.
|
||||||
|
|
||||||
The schema lives entirely in the YAML frontmatter block at the top of each `.md` file. The body below the frontmatter is plain markdown, rendered to MediaWiki wikitext by Pandoc — no special body conventions are enforced beyond the standard markdown grammar, except that `[[TAG]]` placeholders declared via `wiki.siblings` are substituted with resolved wikilinks after rendering.
|
The schema lives entirely in the YAML frontmatter block at the top of each `.md` file. The body below the frontmatter is plain markdown, rendered to MediaWiki wikitext by Pandoc — no special body conventions are enforced beyond the standard markdown grammar, except that `[[TAG]]` placeholders declared via `wiki.siblings` are substituted with resolved wikilinks after rendering.
|
||||||
|
|
||||||
@@ -136,12 +136,12 @@ For parallel content — e.g. an original and its translation — write a fenced
|
|||||||
|
|
||||||
````markdown
|
````markdown
|
||||||
```columns
|
```columns
|
||||||
<b>原題</b>
|
**原題**
|
||||||
|
|
||||||
一行目
|
一行目
|
||||||
二行目
|
二行目
|
||||||
===
|
===
|
||||||
<b>Title</b>
|
**Title**
|
||||||
|
|
||||||
first line
|
first line
|
||||||
second line
|
second line
|
||||||
@@ -152,7 +152,7 @@ The renderer turns this into a flexbox row of `<poem>` columns (one per `===`-de
|
|||||||
|
|
||||||
- **Line breaks and blank lines are preserved verbatim** — that's the point of using a fenced block; Pandoc passes the body through untouched, and each column is wrapped in `<poem>` so MediaWiki keeps the line breaks.
|
- **Line breaks and blank lines are preserved verbatim** — that's the point of using a fenced block; Pandoc passes the body through untouched, and each column is wrapped in `<poem>` so MediaWiki keeps the line breaks.
|
||||||
- **N columns**: use N−1 `===` separators. Two is the common case (original / translation).
|
- **N columns**: use N−1 `===` separators. Two is the common case (original / translation).
|
||||||
- **Inline markup is allowed**: HTML such as `<b>…</b>` or `<br>` written inside the block is HTML-unescaped on the way out, so it renders rather than showing as literal text.
|
- **Emphasis in Markdown**: write `*italic*`, `**bold**`, or `***bold-italic***` (asterisk style, single line) — these are converted to wikitext. Raw inline HTML such as `<b>…</b>` or `<br>` also still works (it's HTML-unescaped on the way out), but you shouldn't need it.
|
||||||
- This is a shared transform (`lib/wiki.py`), so it works for any pipeline, not just songs. Column width/gap styling currently lives in that transform.
|
- This is a shared transform (`lib/wiki.py`), so it works for any pipeline, not just songs. Column width/gap styling currently lives in that transform.
|
||||||
|
|
||||||
## Renderer behaviour
|
## Renderer behaviour
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# pipelines/tech
|
# pipelines/tech
|
||||||
|
|
||||||
Publishes tech blog posts from `mikkeli/tech-blogs` to `https://wiki.novoyuuparosk.org`.
|
Publishes tech blog posts from `novoyuuparosk-wiki/tech-blogs` to `https://wiki.novoyuuparosk.org`.
|
||||||
|
|
||||||
- Source-file contract (frontmatter and body conventions): [SCHEMA.md](SCHEMA.md)
|
- 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)
|
- Cross-cutting setup (wiki URL, bot identity, runner, Gitea secrets/variables): [repo root README](../../README.md)
|
||||||
@@ -18,7 +18,7 @@ Publishes tech blog posts from `mikkeli/tech-blogs` to `https://wiki.novoyuuparo
|
|||||||
|
|
||||||
## Source repo
|
## Source repo
|
||||||
|
|
||||||
Source repo: `mikkeli/tech-blogs` (not yet initialised — pipeline code is ready).
|
Source repo: `novoyuuparosk-wiki/tech-blogs` (not yet initialised — pipeline code is ready).
|
||||||
|
|
||||||
The pipeline triggers on push to `master` and supports `workflow_dispatch` for manual runs.
|
The pipeline triggers on push to `master` and supports `workflow_dispatch` for manual runs.
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ The pipeline triggers on push to `master` and supports `workflow_dispatch` for m
|
|||||||
|
|
||||||
## Invocation
|
## 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.
|
The pipeline runs as a self-contained Gitea Actions workflow in `novoyuuparosk-wiki/tech-blogs` (`.gitea/workflows/publish.yml`). It clones this repo at runtime to get the renderer.
|
||||||
|
|
||||||
Triggers:
|
Triggers:
|
||||||
- `push` to `master` (path-filtered as above)
|
- `push` to `master` (path-filtered as above)
|
||||||
@@ -71,8 +71,8 @@ Shared code lives in `lib/wiki.py` (repo root).
|
|||||||
| Publish mode | Always `--all` | 2026-06-10 |
|
| Publish mode | Always `--all` | 2026-06-10 |
|
||||||
| Idempotency | Commit SHA in banner | 2026-06-10 |
|
| Idempotency | Commit SHA in banner | 2026-06-10 |
|
||||||
| Manual-page protection | Bot skips pages without `{{Auto-generated` 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 |
|
| Source repo | `novoyuuparosk-wiki/tech-blogs` — pipeline ships before repo is initialised | 2026-06-10 |
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
v1 pipeline ready. Source repo (`mikkeli/tech-blogs`) not yet initialised.
|
v1 pipeline ready. Source repo (`novoyuuparosk-wiki/tech-blogs`) not yet initialised.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# SCHEMA — tech blog source files
|
# SCHEMA — tech blog source files
|
||||||
|
|
||||||
Source-file contract for the tech blog pipeline. Files in `mikkeli/tech-blogs` must follow this contract to be picked up by the auto-publisher.
|
Source-file contract for the tech blog pipeline. Files in `novoyuuparosk-wiki/tech-blogs` must follow this contract to be picked up by the auto-publisher.
|
||||||
|
|
||||||
The schema lives entirely in the YAML frontmatter block at the top of each `.md` file. The body is plain markdown, rendered to MediaWiki wikitext by Pandoc.
|
The schema lives entirely in the YAML frontmatter block at the top of each `.md` file. The body is plain markdown, rendered to MediaWiki wikitext by Pandoc.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user