Repository navigation
ci: verify golangci-lint config against a vendored schema - #1016
Conversation
`golangci-lint config verify` fetched its JSON schema from golangci-lint.run on every Lint Code run, with a hard-coded 2s HTTP timeout, so the job failed at random before linting anything. Vendor the v2.10 schema (sha256 692e8da7..., byte-identical to the published https://golangci-lint.run/jsonschema/golangci.v2.10.jsonschema.json and to jsonschema/golangci.next.jsonschema.json at tag v2.10.1) and pass it to `config verify --schema file://...` in a dedicated step. The step checks the file's sha256 and fails if the installed golangci-lint minor has no vendored schema, so a version bump cannot silently validate against a stale schema. The config is still validated on every run; it just no longer needs the network. Closes LeanerCloud#977 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reached
This review includes 2 billable files and costs up to $0.50. Or wait 57 minutes for your next included review. View limit details
Comment |
Independent review verdict: CLEAN at 7ec5f56Reviewer: fresh Claude agent (Sonnet, high effort), not the author, cold brief. The PR body was treated as a claim. Coordinator: claude-cc-reviewer. Blocking findings: none. Provenance: the vendored schema has sha256
The step still fails on bad config: CI runs
Maintenance: the schema filename is derived from pre-commit: all hooks pass or are skipped on the JSON file and Gate:
|
|
Gate record for 7ec5f56 (origin/main CLAUDE.md "Review gate"):
Merging at 7ec5f56 with --match-head-commit. |
Root cause
The
Run golangci-lintstep in theLint Codejob rangolangci-lint config verifybefore each lint run. With no--schema, golangci-lint v2.10.1 builds the URLhttps://golangci-lint.run/jsonschema/golangci.v2.10.jsonschema.jsonand fetches it with an HTTP client that has a hard-coded 2s timeout (newJSONSchemaHTTPLoaderinpkg/commands/config_verify.go). When golangci-lint.run is slow to send headers, verify exits 3 and the job goes red even though the lint reports 0 issues. The first attempt of run 38894294427 (job 116950948944) shows this inRun golangci-lint:The
golangci-lint-actionstep isn't involved: withinstall-only: trueit returns before its ownrunVerify.golangci-lint rundoesn't fetch the schema either.Fix
The config is still checked against the schema on every run. The check just no longer needs the network.
.github/golangci-lint/golangci.v2.10.jsonschema.json. It was copied fromjsonschema/golangci.next.jsonschema.jsonat tag v2.10.1, read from the Go module cache. That file is byte-identical to the publishedhttps://golangci-lint.run/jsonschema/golangci.v2.10.jsonschema.jsonand tojsonschema/golangci.v2.10.jsonschema.jsonon golangci-lintmain. All three have sha256692e8da79dc1f110a4a4f3bb841b26ed44e461d3503678eaaae90ae8876e3403. The schema's only refs are internal (#/...), and the draft-07 metaschema is built into the validator, so nothing is fetched.Verify golangci-lint config against vendored schema, runs beforeRun golangci-lint. It:golangci-lint version --short, and fails if there's no matchinggolangci.v<major.minor>.jsonschema.json;GOLANGCI_LINT_SCHEMA_SHA256withsha256sum -c, so an accidental edit (formatter, hand edit) fails loudly;golangci-lint config verify --schema file://$PWD/<schema>.config verifyis removed from the lint loop.tests/e2ehas no config of its own (golangci-lint config paththere gives../../.golangci.yml), so one check covers both modules.Why this option and not the others in the issue:
verify: falseon the action wouldn't help, because the action doesn't verify in install-only mode, and dropping the check entirely would lose validation. A non-blocking retry would still depend on the network and would no longer block a bad config. Vendoring is deterministic and keeps the check blocking. No new actions, and the existing action SHAs are unchanged.Caveat:
--schemais a hidden flag. Upstream says it's "for debugging purpose only", but it has been there sinceconfig verifywas added. If a future version drops it, this step fails loudly on the bump PR; it won't silently skip the check.Keeping the schema current
When
version:on the golangci-lint-action step moves to a new minor, the new step fails withno vendored schema for golangci-lint X.Y.Zuntil the schema is updated. The steps are also in the step's comment inci.yml:curl -fsSLo .github/golangci-lint/golangci.vX.Y.jsonschema.json https://golangci-lint.run/jsonschema/golangci.vX.Y.jsonschema.jsongolangci.v2.10.jsonschema.json.GOLANGCI_LINT_SCHEMA_SHA256to the new file'ssha256sum.A patch bump (for example 2.10.2) keeps the same schema file.
Closes #977
Verification
All local, macOS, golangci-lint v2.10.1 (go1.26.9). The new step's
run:block was pulled out ofci.ymland run as-is. Network was blocked withHTTPS_PROXY=HTTP_PROXY=http://127.0.0.1:9, which Go's HTTP client honors.golangci-lint config verify, network blockedfailing loading "https://golangci-lint.run/jsonschema/golangci.v2.10.jsonschema.json" ... connection refused. Reproduces the CI failure..golangci.yml...: OKfrom the sha256 check, then verify exit 0.-vshowswith the JSON Schema from file:///.../.github/golangci-lint/golangci.v2.10.jsonschema.json.not-a-real-key: trueaddedadditional properties 'not-a-real-key' not allowedlinters.default: bogus-defaultvalue must be one of 'standard', 'all', 'none', 'fast'sha256sum: ... FAILED::error::no vendored schema for golangci-lint 2.10.1 ...Run golangci-lintblock, network blocked,GOPROXY=off0 issues.for.and fortests/e2e, exit 0.runmakes no schema fetch.actionlint1.7.12 (shellcheck enabled)zizmor==1.29.0 --offline --persona=pedantic --min-severity=medium .github/workflows/(as Lint Workflows runs it)shellcheck -s bashon the extracted new and changedrun:blocks--register-awson a temp copy (isolated HOME), scanning both changed filesbash scripts/test-git-secrets-allowlist.shscripts/test-actionlint-hook.shwasn't run because it needspre-commit, which isn't installed here. This PR doesn't touch that hook.The changed workflow only runs on GitHub once a maintainer approves the workflow run for this fork PR. Until then, the evidence above is the only check of the new step on this PR.
Out of scope
config verifytomake lintor pre-commit. CI still blocks on it; this can follow up if wanted.version: v2.10.1inci.ymlmatchesGOLANGCI_LINT_VERSIONin theMakefile. They agree today.Run golangci-lint. Previously the loop went on to lint both modules and reported the failure at the end. The job is red either way.🤖 Generated with Claude Code