ci: verify golangci config against a vendored schema - #997
Conversation
The action's built-in config-verify fetches the JSON schema from golangci-lint.run on every run, so a transient network failure fails the merge-gating lint job with no lint findings. Vendor the v2.11 schema and verify against it hermetically instead.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
1 similar comment
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
There was a problem hiding this comment.
Pull request overview
This PR makes the merge-gating lint workflow hermetic by removing the golangci-lint action’s network-dependent schema download during config verification, and instead validating .golangci.yaml against a vendored JSON schema checked into the repo.
Changes:
- Disable
golangci/golangci-lint-action’s built-inverifybehavior to avoid remote schema fetches. - Add an explicit
golangci-lint config verify --schema <vendored>step for the default matrix leg. - Vendor the golangci-lint v2.11 config JSON schema under
.github/for offline verification.
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| .github/workflows/lint.yaml | Disables action verify and adds a hermetic config verification step using a vendored schema. |
| .github/golangci.v2.11.jsonschema.json | Adds the vendored JSON schema used to validate .golangci.yaml without network access. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The standalone verify step relied on the lint action leaving the binary on PATH as a side effect. Add an install-only invocation of the same pinned action so the step's binary dependency is explicit under the action's documented contract.
morgo
left a comment
There was a problem hiding this comment.
🤖 Approving on Morgan's behalf (automated review, escalation rules apply).
CI-only change that makes the config-verify check hermetic: verify: false on the lint step kills the per-run schema download from golangci-lint.run (a real merge-gate flake source), and the vendored-schema config verify --schema step replaces it. Install-only step is SHA-pinned consistent with the repo's pinning policy, both new steps are gated to the default matrix leg so they run once, and the comments document exactly when to delete this (v2.12+ embeds the schema). The 5.3k-line vendored schema's worst case is mis-validating the lint config — CI-only blast radius.
…k' into kiran01bm/pg-backend-nucleus * origin/kiran01bm/sqlstore-joined-dml-13k: refactor(storage): reject bind placeholders in JoinedUpdate join conditions refactor(storage): tighten the JoinedUpdate dialect contract refactor(storage): render joined UPDATEs through the dialect feat(postgres): implement declarative planning via pg-sprite diffplan (#1008) refactor(storage): make remaining sqlstore SQL dialect-portable (#1007) test(e2e): deflake multi-table stop/start resume and MySQL cold starts (#1005) ci: verify golangci config against a vendored schema (#997) feat(api): fail-closed verdict gating for postgres plans (#1004) feat(tern): route postgres targets to the postgres engine (#1003) feat(storage): stamp remaining sqlstore timestamps explicitly (#1006) # Conflicts: # pkg/storage/internal/sqlstore/apply_comments.go # pkg/storage/internal/sqlstore/dialect.go # pkg/storage/internal/sqlstore/dialect_test.go # pkg/storage/internal/sqlstore/settings.go # pkg/storage/internal/sqlstore/storage.go # pkg/storage/internal/sqlstore/updated_at_lint_test.go
…-joined-dml-13l * origin/main: refactor(storage): render joined UPDATEs through the dialect (#1009) fix(planetscale): hold the cutover when the operator defers it (#978) fix(observability): make telemetry resource schema-tolerant (#1014) feat(postgres): implement declarative planning via pg-sprite diffplan (#1008) refactor(storage): make remaining sqlstore SQL dialect-portable (#1007) test(e2e): deflake multi-table stop/start resume and MySQL cold starts (#1005) ci: verify golangci config against a vendored schema (#997) feat(api): fail-closed verdict gating for postgres plans (#1004) feat(tern): route postgres targets to the postgres engine (#1003) feat(storage): stamp remaining sqlstore timestamps explicitly (#1006) # Conflicts: # pkg/storage/internal/sqlstore/apply_comments.go # pkg/storage/internal/sqlstore/dialect.go # pkg/storage/internal/sqlstore/dialect_test.go # pkg/storage/internal/sqlstore/settings.go # pkg/storage/internal/sqlstore/storage.go # pkg/storage/internal/sqlstore/updated_at_lint_test.go
…re-public-13n * origin/main: refactor(storage): portable lease-guarded joined DML for the operation store (#1011) fix(github): align lint warnings formatting with issues and fold long lists (#959) fix(github): lead with the database's operators on command-rejection comments (#960) docs: regenerate stale tables of contents (#968) fix(engine): heartbeat the row a local drive actually owns (#915) fix(github): scope auto-plan to the schema a pull request proposes (#1016) fix(vitess): dispatch task-less VSchema-only work operations over gRPC (#961) feat(storage): add PostgreSQL dialect nucleus to the shared store core (#1010) refactor(storage): render joined UPDATEs through the dialect (#1009) fix(planetscale): hold the cutover when the operator defers it (#978) fix(observability): make telemetry resource schema-tolerant (#1014) feat(postgres): implement declarative planning via pg-sprite diffplan (#1008) refactor(storage): make remaining sqlstore SQL dialect-portable (#1007) test(e2e): deflake multi-table stop/start resume and MySQL cold starts (#1005) ci: verify golangci config against a vendored schema (#997) feat(api): fail-closed verdict gating for postgres plans (#1004) feat(tern): route postgres targets to the postgres engine (#1003) feat(storage): stamp remaining sqlstore timestamps explicitly (#1006)
…lect-factory-14b * origin/main: feat(github): flag destructive changes to tables another open PR owns (#1017) feat(storage): add public postgresstore constructor (#1012) refactor(storage): portable lease-guarded joined DML for the operation store (#1011) fix(github): align lint warnings formatting with issues and fold long lists (#959) fix(github): lead with the database's operators on command-rejection comments (#960) docs: regenerate stale tables of contents (#968) fix(engine): heartbeat the row a local drive actually owns (#915) fix(github): scope auto-plan to the schema a pull request proposes (#1016) fix(vitess): dispatch task-less VSchema-only work operations over gRPC (#961) feat(storage): add PostgreSQL dialect nucleus to the shared store core (#1010) refactor(storage): render joined UPDATEs through the dialect (#1009) fix(planetscale): hold the cutover when the operator defers it (#978) fix(observability): make telemetry resource schema-tolerant (#1014) feat(postgres): implement declarative planning via pg-sprite diffplan (#1008) refactor(storage): make remaining sqlstore SQL dialect-portable (#1007) test(e2e): deflake multi-table stop/start resume and MySQL cold starts (#1005) ci: verify golangci config against a vendored schema (#997) feat(api): fail-closed verdict gating for postgres plans (#1004) feat(tern): route postgres targets to the postgres engine (#1003) feat(storage): stamp remaining sqlstore timestamps explicitly (#1006)
Summary
The lint job occasionally fails with no lint findings because the golangci-lint action's built-in
config verifyfetches the config JSON schema fromgolangci-lint.runon every run — a transient network failure on the runner fails this merge-gating job. This keeps the config-verify check but makes it hermetic.What
.github/golangci.v2.11.jsonschema.json.verify: false) and add an explicitgolangci-lint config verify --schema <vendored file>step (once, on the default matrix leg) that validates.golangci.yamlagainst the vendored copy with no remote fetch.Why
config verifyis worth keeping: it validates the whole config against the schema and reports precise diagnostics (unknown keys, wrong types, misplaced sections) before any lint run. The alternative — dropping the check altogether (verify: falsewith no replacement) — removes the flake with zero maintenance, but loses those schema diagnostics: a config typo would then surface only as whatever errorgolangci-lint runhappens to produce, or worse, as a silently ignored setting.The cost of the vendored approach is a schema file that must be refreshed whenever the pinned golangci-lint minor version moves. That cost is temporary: the hidden
--schemaflag is removed in golangci-lint v2.12+, which embeds the schema in the binary —config verifybecomes hermetic by default. On that version bump, the vendored file and the extra step get deleted and the action's built-in verify is re-enabled (the workflow comment records this).