Files
FabledSteward/ci-requirements.md
T
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

59 lines
2.9 KiB
Markdown

# 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
- **lint** — `ruff check steward/ plugins/ tests/`, no dep install.
- **unit** — `pytest -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.
- **integration** — `pytest 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_app``run_core_migrations`, async
through `asyncpg`), so the integration lane needs no separate `alembic upgrade`
step and no psycopg/sync driver.