Skip to content

feat(rigging): configurable service database name (#24 follow-up) - #43

Merged
submtd merged 1 commit into
mainfrom
feature/rigging-configurable-database
Jul 23, 2026
Merged

feat(rigging): configurable service database name (#24 follow-up)#43
submtd merged 1 commit into
mainfrom
feature/rigging-configurable-database

Conversation

@submtd

@submtd submtd commented Jul 23, 2026

Copy link
Copy Markdown
Owner

What & why

rigging's service containers hardcoded the database name to postgres/mysql and gave the consuming repo no way to change it — so the only TEST_DATABASE_URL rigging could emit ended in /postgres. Many projects guard their destructive test suite by database name (refusing to run unless the target DB name matches a safe pattern, e.g. ending in _test, so a misconfigured URL can't truncate dev or prod data). Such a repo couldn't use rigging without hand-editing the generated workflow — the same shape as the #24 blockers, one narrower gap.

This adds an optional per-service database key:

{"stacks": {"node": {"services": {
  "postgres": {"version": "16", "urlEnv": "TEST_DATABASE_URL", "database": "onelife_test"}
}}}}

renders POSTGRES_DB: "onelife_test" and TEST_DATABASE_URL: "postgresql://postgres:postgres@localhost:5432/onelife_test".

Design (follows the engine's existing patterns)

  • services.pyServiceSpec splits base_env from the database pair and gains database_env (POSTGRES_DB/MYSQL_DATABASE/None) and default_database (postgres/mysql/None); url becomes url(database). redis has neither field and its URL template ignores the argument.
  • config.pydatabase added to _SERVICE_KEYS, validated by a strict SERVICE_DATABASE_RE ([A-Za-z0-9_-]+, refuses whitespace/quotes/${{), rejected for redis (field-named ConfigError, like packageManager off a non-node stack), threaded onto ResolvedService.
  • plan.py_resolve_services picks rs.database or spec.default_database and composes it into both the container env and the URL.
  • init untouched — manual escape hatch like testCommand/services, so the Every plugin needs a round-trip property test: propose_config output must load through load_config #33 round-trip property test is unaffected.

Byte-identity (the hard constraint)

database is default-preserving: each service's default_database equals the value it hardcoded before, so an omitted database reproduces every existing golden byte-for-byte. git diff touches no existing golden — only the new node-postgres-database.yml is added.

Verify

Closes the organization-monorepo adoption of rigging (issue #24 follow-up): a Postgres repo with a name-guarded test database was the last case rigging couldn't render without a hand-edit.

🤖 Generated with Claude Code

rigging's service containers hardcoded the database to `postgres`/`mysql` and
gave the consuming repo no way to change it, so the only TEST_DATABASE_URL it
could emit ended in `/postgres`. A repo whose test harness guards on the DB
name (refusing to run unless it ends in `_test`, a common way to stop a stray
URL truncating dev/prod data) could not use rigging without hand-editing the
generated workflow.

Add an optional per-service `database` key. rigging composes the chosen name
into both the container's POSTGRES_DB/MYSQL_DATABASE and the connection URL.
The key is default-preserving: each service carries a default_database equal to
what it hardcoded before, so an omitted `database` reproduces every existing
golden byte-for-byte. It is rejected for redis (no database concept) rather
than silently ignored, and validated by a strict regex that refuses anything
needing YAML quoting or carrying a `${{` expression. Manual escape hatch like
testCommand/services -- init does not propose it, so the #33 round-trip
property test is untouched.

services.py: ServiceSpec splits base_env from the database pair, gains
database_env/default_database, and url becomes url(database). config.py: accept
and validate `database`, thread onto ResolvedService. plan.py: compose env+URL
from the chosen database. New golden node-postgres-database.yml; tests across
config/plan/render/services/injection. Suite 1441 -> 1456.

Closes the organization-monorepo adoption of rigging (issue #24 follow-up).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119qj5F9NnGhQCxHehLy99E

@submtd submtd left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self-review (author) — satisfies keel's reviewPolicy: review gate.

New optional per-service 'database' key for rigging service containers, closing the last #24-shaped adoption gap (a repo that guards its test DB by name).

Reviewed:

  • Correctness — database composed into both the container env (POSTGRES_DB/MYSQL_DATABASE) and the connection URL; redis (no database concept) rejects the key with a field-named ConfigError rather than silently ignoring it.
  • Byte-identity (the hard constraint) — default-preserving by construction: each service carries a default_database equal to what it hardcoded before, so the omitted path IS the default path. git diff touches no existing golden; a dedicated test asserts a set database moves only the POSTGRES_DB line and the URL segment.
  • Injection — SERVICE_DATABASE_RE ([A-Za-z0-9_-]+) refuses whitespace, quotes, and ${{ at load; a hostile database is refused before render (test_hostile_service_database_is_refused_before_render).
  • Scope/init — manual escape hatch like testCommand/services; init untouched, so SIGNAL_KEYS/propose_config and the #33 round-trip property test are unchanged.
  • Tests — 1441 to 1456 (15 new, TDD); purity green.
  • Changelog — Unreleased Added entry accurate and user-facing.

Ready to land.

@submtd
submtd merged commit 0d21ec7 into main Jul 23, 2026
4 checks passed
@submtd
submtd deleted the feature/rigging-configurable-database branch July 23, 2026 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant