feat(rigging): service containers — closes #26 (increment 3 of 3) - #38
Merged
Conversation
Four tasks closing #26: a SERVICE_REGISTRY (postgres/mysql/redis) owning image, port, credentials, health check, and URL template; config validation of stacks.<id>.services into StackConfig; render of a job-level services: block and env: with the composed connection URL; docs + changelog. Health commands are externally verified against GitHub's docs (byte-identity tests can't catch a wrong one), and two goldens (postgres, redis) pin the rendering including redis's empty-env + escaped-quote health command. services is manual-only, so it does not touch propose_config/SIGNAL_KEYS. Job-level env placement per the user's choice. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Externally verified against GitHub's own service-container docs (postgres, redis) and the docker-library/healthcheck mysql script (mysqladmin ping) -- health commands, env var names, and ports match the documented canonical forms exactly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0119qj5F9NnGhQCxHehLy99E
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ers (#26) Final whole-branch review (runtime correctness confirmed against GitHub's docs) returned only Minors; applied: - Add node-mysql.yml golden -- mysql was the one service with no render test, and it is the only one exercising a container env: block AND a quoted health-cmd together. Generated via sync_action_pins.py; the nine other goldens and the dogfooded workflows are unchanged. - Note in services.py that `mysqladmin ping` is a liveness, not readiness, probe (the standard GHA idiom; --health-retries covers the gap). - Drop an unused `import re` in test_services.py. - Type _build_job's `services` parameter as tuple[config.ResolvedService, ...]. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
submtd
commented
Jul 23, 2026
submtd
left a comment
Owner
Author
There was a problem hiding this comment.
Self-review (author) — satisfies keel's reviewPolicy: review gate.
Increment 3 of 3, closing #26. rigging now renders GitHub Actions service containers (postgres/mysql/redis) alongside the test job, with each service's connection URL exposed under its configured urlEnv.
Reviewed:
- Correctness — the whole-branch opus review confirmed runtime correctness against GitHub's service-container docs; health commands were externally verified twice (implementer + reviewer), including the mysqladmin liveness-not-readiness caveat documented in
services.py. - Tests —
test_services.pycovers the registry (URL composed from registry constants not the version tag, every service carries a health check, no Actions expressions in health options). Four goldens exercise the render paths: postgres, redis (empty container env), mysql (env block + quoted health-cmd combined). Suite 1404 → 1436. - Scope — diff is confined to services.py (new), config/plan/render, goldens, sync script, and docs/changelog. Nothing extraneous.
- Injection safety — service images tag-pinned by design (ephemeral fixture on a private network); health options are registry constants, never user input;
urlEnvis a strict identifier. Does not enlarge #30. - Changelog — Unreleased
Addedentry is accurate and user-facing.
Ready to land.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #26 — the third and final increment. A repo whose tests need a live database can now use rigging end to end.
What
.rigging.json's per-stack config gainsservices:Supported:
postgres,mysql,redis. rigging renders a job-levelservices:block and sets the composed connection URL in a job-levelenv:var the repo names — so every step (including migrations) sees it.The design in one line
A
SERVICE_REGISTRYowns everything except the two things the repo picks — the imageversion(a tag) and theurlEnvname. It owns the image, port, credentials, the connection-URL template, and — crucially — the health check, so the job waits for the container to be ready instead of racing it and flaking. No user string ever reaches a Dockeroptions:line.Why it's safe, and why it runs
version(charset-constrained, lands in a quoted tag) andurlEnv(a strict^[A-Za-z_][A-Za-z0-9_]*$identifier, refused at load). Health options and URLs are registry constants.options:rendering (--health-cmd \"redis-cli ping\") round-trips through YAML correctly.Scope & tests
servicesis a hand-authored declaration, so it does not flow throughpropose_config—scaffold.py/SIGNAL_KEYSuntouched.services:/env:emit only when non-empty). Three new goldens — postgres, redis, and mysql — pin the rendering; redis covers the empty-container-env path and mysql the env-block + quoted-health-command combination.🤖 Generated with Claude Code