Skip to content

Commit a5c1de1

Browse files
committed
ci, justfile: lint every sub-module, not just the root
The root lint job (vet + staticcheck + golangci-lint + modernize) skipped the sub-modules, so findings in their own module context — like the modernize one that slipped into vfs/compress — went uncaught. Now each discovered sub-module runs the same suite in its own context: the CI `submodules` matrix gains the four lint steps before its test, and a new `just lint-submodules` recipe (wired into `lint`) mirrors them. gofmt stays repo-wide in the root job, which already covers every file. golangci-lint runs in the sub-module dir and walks up to the repo-root .golangci.yml, so the exclusions apply uniformly across modules.
1 parent d95b2c8 commit a5c1de1

2 files changed

Lines changed: 61 additions & 7 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,9 @@ jobs:
200200
# Every sub-module has its OWN go.mod (joined to the root via `replace
201201
# gosqlite.org`), so its private deps never reach the root graph: blobstore's
202202
# codec, vfs/crypto's adiantum + x/crypto, xorm-compat's xorm.io/xorm, gorm's
203-
# dialector deps. Each is tested in its own module context. (xorm-compat is the
204-
# CI-enforced proof gosqlite.org is a drop-in xorm SQLite driver — see
205-
# dev/upstream/xorm.md.)
203+
# dialector deps. Each is linted (vet + staticcheck + golangci-lint + modernize)
204+
# and tested in its own module context. (xorm-compat is the CI-enforced proof
205+
# gosqlite.org is a drop-in xorm SQLite driver — see dev/upstream/xorm.md.)
206206
#
207207
# The matrix is DISCOVERED, not hand-listed: `discover` finds every joined
208208
# sub-module's go.mod and emits the dir list as JSON; `submodules` fans out
@@ -237,6 +237,34 @@ jobs:
237237
steps:
238238
- uses: actions/checkout@v5
239239
- uses: ./.github/actions/setup
240+
# Same lint gate as the root `lint` job, in the sub-module's own context.
241+
# gofmt is not repeated here — the root job's `gofmt -d` already covers
242+
# every .go file in the repo, sub-modules included.
243+
- name: go vet
244+
working-directory: ${{ matrix.dir }}
245+
run: go vet -unsafeptr=false ./...
246+
- name: staticcheck
247+
working-directory: ${{ matrix.dir }}
248+
run: |
249+
go install honnef.co/go/tools/cmd/staticcheck@latest
250+
staticcheck ./...
251+
- name: golangci-lint
252+
uses: golangci/golangci-lint-action@v9
253+
with:
254+
version: v2.4.0
255+
args: --timeout 5m
256+
# Runs in the sub-module dir; golangci-lint walks up to the repo-root
257+
# .golangci.yml, so its exclusions apply uniformly across modules.
258+
working-directory: ${{ matrix.dir }}
259+
- name: gopls modernize
260+
working-directory: ${{ matrix.dir }}
261+
# Forked upstream files (gorm's sqlite.go/migrator.go) are excluded by
262+
# path tail, since modernize runs with the sub-module as the working dir.
263+
run: |
264+
out=$(go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest ./... 2>&1 \
265+
| grep -v -E '(^|/)(sqlite|vtab|rows|migrator)\.go:' \
266+
| grep -v '^exit status' | grep -v '^go: ' || true)
267+
if [ -n "$out" ]; then echo "$out"; exit 1; fi
240268
- name: go test (${{ matrix.dir }} module)
241269
working-directory: ${{ matrix.dir }}
242270
run: go test -count=1 -timeout 5m -v ./...

‎justfile‎

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,11 @@ bench-vec:
6767
bench-fts:
6868
go test -run=^$ -bench='^Benchmark' -benchmem -count=5 ./fts/
6969

70-
# Lint with fmt-check + vet + staticcheck + golangci-lint + modernize
71-
# (matches CI). fmt-check runs first because it's the cheapest and the
72-
# most common cause of CI failures from local-only pushes.
73-
lint: fmt-check vet staticcheck golangci modernize
70+
# Lint the root module + every sub-module with fmt-check + vet + staticcheck +
71+
# golangci-lint + modernize (matches CI). fmt-check runs first because it's the
72+
# cheapest and the most common cause of CI failures from local-only pushes;
73+
# lint-submodules runs last because it lints N modules and is the slowest.
74+
lint: fmt-check vet staticcheck golangci modernize lint-submodules
7475

7576
# go vet across all packages. unsafeptr=false suppresses the false-positive
7677
# storm from modernc's uintptr↔unsafe.Pointer conversions inherited in our
@@ -196,6 +197,31 @@ submodule DIR:
196197
test-submodules:
197198
@set -e; for d in {{submods}}; do echo "=== test $d ==="; (cd "$d" && go test -count=1 -timeout 5m ./...); done
198199

200+
# Lint EVERY sub-module in its own module context: vet + staticcheck +
201+
# golangci-lint + modernize (gofmt is already repo-wide via fmt-check). Mirrors
202+
# the per-module lint the CI `submodules` matrix runs. Slow — lints N modules.
203+
# Assumes staticcheck + golangci-lint are installed (the root `staticcheck` /
204+
# `golangci` recipes that run before this in `lint` already check that).
205+
lint-submodules:
206+
#!/usr/bin/env bash
207+
set -euo pipefail
208+
for d in {{submods}}; do
209+
echo "=== lint $d ==="
210+
(
211+
cd "$d"
212+
go vet -unsafeptr=false ./...
213+
staticcheck ./...
214+
golangci-lint run --timeout 5m ./...
215+
# Modernize, minus the forked upstream files we keep verbatim (gorm's
216+
# sqlite.go/migrator.go; matched on the path tail since these run with
217+
# the sub-module as the working dir).
218+
out=$(go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest ./... 2>&1 \
219+
| grep -v -E '(^|/)(sqlite|vtab|rows|migrator)\.go:' \
220+
| grep -v '^exit status' | grep -v '^go: ' || true)
221+
[ -z "$out" ] || { echo "$out"; exit 1; }
222+
)
223+
done
224+
199225
# Full CI parity: everything CI runs, in order. Slower than `default`. Now mirrors
200226
# CI's submodule + pin coverage (the old `ci` skipped xorm-compat and the pins).
201227
ci: build test test-race lint cross-build test-submodules check-pins

0 commit comments

Comments
 (0)