Files
FabledSteward/ci-requirements.md
bvandeusen fe57dde57b
CI / lint (push) Successful in 3s
CI / unit (push) Successful in 7s
CI / integration (push) Successful in 2m13s
CI / publish (push) Successful in 1m12s
feat(ci): publish steward image to the registry + remote-deploy compose
Add the rule-46 image-publish lane: a `publish` job gated on
[lint, unit, integration] that builds the runtime Dockerfile in ci-builder
and pushes git.fabledsword.com/bvandeusen/steward:<sha> always, :dev on dev
and :latest on main. Authenticates with the REGISTRY_TOKEN repo secret
(the injected GITHUB_TOKEN lacks write:package). Steward is the first family
app to implement the publish lane; mechanics mirror CI-runner's
build-ci-python.yml.

Add compose.deploy.yml for a persistent remote instance that pulls :dev
(no source bind-mounts, persistent app_data+pgdata volumes, bundled Postgres),
plus a README "Remote dev instance" runbook and the POSTGRES_PASSWORD env key.
Fix .env.example's database URL var to the canonical STEWARD_DATABASE_URL
(single underscore) and document the publish lane in ci-requirements.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 11:08:43 -04:00

2.9 KiB

CI Requirements — Steward

Spec: https://git.fabledsword.com/bvandeusen/CI-runner/src/branch/main/docs/process.md

Runtime image

git.fabledsword.com/bvandeusen/ci-python:3.14

Image deps used

  • python 3.14
  • ruff (analyzer for steward/, plugins/, tests/)
  • docker CLI (integration lane: bridge-IP discovery of the Postgres service container)

Per-job tool installs

  • uv pip install --system -e '.[dev]' (pip fallback) — in the unit job.

  • uv pip install --system -e '.[dev,ansible]' (pip fallback) — in the integration job, which boots the real app and exercises the Ansible runner, so it needs the ansible extra (ansible>=10,<13) at import time.

    Steward declares its deps in pyproject.toml; the [dev] extra adds pytest + pytest-asyncio. No requirements.txt is tracked.

Lanes

  • lintruff check steward/ plugins/ tests/, no dep install.
  • unitpytest -m "not integration". The whole current suite runs here: it builds the app with testing=True, which mocks db_sessionmaker, so no DB is touched. First-party plugins are bundled in-tree under plugins/, so plugin unit tests import them directly — no cross-repo checkout.
  • integrationpytest tests/integration -m integration against a postgres:16-alpine service. The single test boots the real app (create_app(testing=False)), which runs core + every bundled plugin's migrations, then round-trips the DB. This is the guard that the folded-in plugin migration graph resolves.
  • publish — builds the runtime Dockerfile and pushes to the package registry. Runs in ci-builder:latest (docker + buildx, socket auto-mounted), gated on needs: [lint, unit, integration] so a red commit never ships an image. Publishes git.fabledsword.com/bvandeusen/steward:<sha> always, plus :dev on dev and :latest on main (FabledRulebook rule 46). Needs the REGISTRY_TOKEN repo Actions secret (read:package + write:package) — the injected GITHUB_TOKEN can't push packages.

Notes

  • Steward has no frontend and no Redis/Celery (no external workers), so there is no frontend-build lane and the only service container is Postgres.
  • Integration uses Forgejo Actions services: + a socket-discovered bridge IP because act_runner (swarm-runner v0.6+) puts services on the default bridge with no embedded DNS. FabledCurator's ci.yml is the canonical example of the pattern; Steward's is the same shape minus Redis and minus sharding.
  • The job name integration has no underscore — act_runner strips underscores from job names when building service-container labels, so the docker ps name filter uses the bare job name.
  • Migrations run via the app itself (create_apprun_core_migrations, async through asyncpg), so the integration lane needs no separate alembic upgrade step and no psycopg/sync driver.