feat(schema): support ignore_namespaces in schemabot.yaml - #1073
Conversation
Some schema roots carry a namespace directory that must never be reconciled against a live database, such as a Vitess keyspace that only exists in local test infrastructure. Without an exclusion, every plan proposes creating those tables. schemabot.yaml gains an ignore_namespaces list. Ignored namespaces are dropped after grouping, so they are excluded from plans, applies, and checks in both the GitHub PR flow and the CLI, while layout validation still sees the full tree. Entries get the same $ENV substitution as directory names and are validated to be bare namespace names, not paths. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds ignore_namespaces support to schemabot.yaml so repository-only namespace directories (commonly local-test Vitess keyspaces) are excluded at the namespace-grouping choke point, preventing them from affecting plans, applies, and merge-gate checks in both the GitHub webhook flow and the CLI.
Changes:
- Extend namespace grouping to accept and apply an
ignore_namespaceslist (with$ENVsubstitution) and validate the config entries at load time. - Wire
ignore_namespacesthrough the GitHub schema fetch/group path and the CLI plan/apply path. - Add integration/unit tests plus documentation for the new configuration field.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/webhook/webhook_integration_test.go | Enhances plan test fixture handling to allow multiple namespace subdirectories under schema/. |
| pkg/webhook/plan_integration_test.go | Adds E2E webhook plan test asserting ignored namespaces don’t appear in comments/storage. |
| pkg/schema/namespace.go | Updates grouping API to support ignore_namespaces and adds validation helper. |
| pkg/schema/namespace_test.go | Updates existing tests for new signature; adds tests for ignore behavior + validation. |
| pkg/github/schema.go | Threads ignore list into schema grouping; logs exclusion; improves empty-result error messaging. |
| pkg/github/schema_test.go | Updates grouping tests for new ignore list parameter. |
| pkg/github/config.go | Adds ignore_namespaces to parsed config and validates entries during fetch. |
| pkg/github/config_test.go | Adds YAML parse test for ignore_namespaces. |
| pkg/github/client_test.go | Updates grouping call for new signature. |
| pkg/cmd/commands/plan.go | Passes ignore list from CLI config into plan API call. |
| pkg/cmd/commands/onboard.go | Updates plan API call signature usage (passes nil ignores). |
| pkg/cmd/commands/common.go | Extends CLI config to read/validate ignore_namespaces. |
| pkg/cmd/commands/common_test.go | Adds CLI config load tests for ignore list parsing/validation. |
| pkg/cmd/commands/apply.go | Passes ignore list from CLI config into plan call used by apply. |
| pkg/cmd/client/client.go | Extends plan/read-schema APIs to accept ignore list and pass it into grouping. |
| pkg/cmd/client/client_test.go | Updates existing tests; adds ReadSchemaFiles ignore coverage. |
| e2e/testutil/apply.go | Updates helper call for new namespace grouping signature. |
| e2e/local/vitess_test.go | Updates plan API call sites for new signature (passes nil ignores). |
| docs/namespaces.md | Documents the new “Ignoring Namespaces” feature and rules. |
| docs/github-app-setup.md | Adds ignore_namespaces row to schemabot.yaml field table. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Reject ignore_namespaces entries padded with leading or trailing whitespace at config load — namespace keys are never padded, so such an entry would silently exclude nothing. Resolve $ENV substitution once via ResolveIgnoreNamespaces and use the resolved keys in the exclusion log and empty-result error, so operators see the namespace keys that were actually excluded rather than the unresolved config values. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
🤖 Review findings - created by Kiran's code review agent - for schemabot/pull/1073, 3a73422. Verdict: 9 findings — 3 blocking (on one engine shape "ignore" means "propose dropping", the config is read from the PR branch so a PR can unmanage a namespace itself, and a non-matching entry is a silent no-op that logs as a success), 4 non-blocking, 2 suggestions. Blocking1. On MySQL with a database-scoped target DSN, ignoring a namespace turns its live tables into DROP candidates — the exact inverse of the documented behavior. That shape routes every namespace to one 2. 3. An entry that matches nothing is a silent no-op, and the log and error both report it as though it worked. Non-blocking4. The base-schema freshness gate is namespace-blind, so a base commit touching only an ignored namespace blocks every open PR's apply. schema_freshness.go:104 passes 5. The CLI half of the feature has no test at all — nil'ing 6. The exclusion is disclosed only in a server-side log the PR author cannot read. 7. General suggestions8. Several new branches are dead to the test suite. The entire "no schema files after ignores" block can be deleted green — both the improved message and, more seriously, the 9. Three smaller ones. Filtering happens after the GitHub fetch, so an ignored namespace's files are still listed, still fetched, and still counted against the fail-closed 1000-entry Contents API cap — a large enough fixture directory fails every plan closed via The one thing that could have broken, verifiedThe PR's central claim is that Verified correct
This review was generated by Claude Code (claude-opus-5). |
…-scoped MySQL DSNs Address review feedback on ignore_namespaces: - Plumb the excluded namespaces through the plan request (CLI and webhook -> apitypes -> proto) so the server can refuse the one MySQL shape that cannot honor the exclusion: a target DSN that names a database diffs the whole database as one unit, and an ignored namespace's live tables would be planned as DROP TABLE. - Disclose exclusions where reviewers look: the PR plan comment renders an "excluded by ignore_namespaces" line on changes, no-changes, and multi-env paths (environments with differing exclusions no longer deduplicate), and the CLI prints the same disclosure for plan/apply. - Track the namespaces actually removed, and warn on configured entries that matched nothing, so a typo or stale entry is visible instead of silently reconciling the namespace it was meant to exclude. - Preserve an existing config's ignore_namespaces across onboard rewrites, and fail the plan when the exclusion removes every namespace. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
🤖 All findings addressed in de5c018 (plus 3a73422 earlier for the CLI apply-gate fix):
Deferred as tracked follow-ups rather than folded in here: finding 4 (namespace-scoped freshness gate) and finding 9's pre-fetch filtering. Reply by Claude (Fable 5). |
The exclusion line reads as part of the plan result: what was counted, then what was withheld. On no-changes and all-clean multi-env results it renders under the no-changes message. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Why this matters
Some schema roots carry a namespace that must never be reconciled against a live database — the common case is a namespace that exists only to back local test infrastructure. Today every plan diffs it like any other namespace and proposes creating its tables in real environments, and the only way out is restructuring the schema root. This PR adds
ignore_namespacestoschemabot.yamlso a repo declares those namespaces once and plans, applies, and merge-gate checks never see them.What it does
schema.GroupFilesByNamespace), so every consumer — GitHub PR flow and CLI, plan and apply and checks — sees the same filtered view.$ENVsubstitution as directory names, and are validated at config load to be bare namespace names, not paths.onboardrewrites preserve an existing config'signore_namespaces.Two safety properties worth calling out:
Exclusions are disclosed where reviewers look. The plan comment renders a disclosure line under the plan summary — on changes, no-changes, and multi-env paths (environments whose exclusions differ no longer deduplicate into one section) — and the CLI prints the same line for
plan/apply. A withheld namespace is distinguishable from an unchanged one, and a PR that introduces an entry is visible in review:📋 Plan: 2 tables to create, 1 table to alter
ℹ️ Namespaces excluded from this plan by
ignore_namespaces:local_fixturesOnly namespaces actually removed are disclosed; configured entries that matched nothing (typo, case mismatch, stale entry) produce a warning instead of silently reconciling the namespace they were meant to exclude, and ignoring every namespace is an error.
Docs: new "Ignoring Namespaces" section in
docs/namespaces.md(including disclosure behavior and the MySQL DSN requirement) and a field-table row indocs/github-app-setup.md.How it moves us toward the northstar
Git as the interface only works if the schema root can be the single source of truth for every repo layout that exists in the wild — and real repos share their schema root with local test harnesses. Without a first-class exclusion those repos either can't onboard or must accept plans that propose test fixtures in production. This removes that adoption blocker declaratively, in the same config file that already defines the database.
Opened by Claude (Fable 5).