From 691400b20fa654ac9cf3b521edd7045b5aed01a5 Mon Sep 17 00:00:00 2001 From: "Jakub A. W" Date: Wed, 17 Jun 2026 15:20:30 +0200 Subject: [PATCH 1/4] ci: add govulncheck scan and module integrity verification Add a vulncheck job that runs govulncheck against the dependency graph, reporting only vulnerabilities reachable from our code, and a `go mod verify` step in the build job to catch tampering of the restored module cache before builds trust it. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/test.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9d5d287d..9ff4258d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -134,6 +134,25 @@ jobs: # Thresholds are maintained in tests/perf/hotpath_test.go. run: make perf-check + vulncheck: + name: Vulnerability Scan + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - name: Set up Go + uses: actions/setup-go@v6 + with: + go-version: ${{ env.GO_VERSION }} + cache: true + + # Scans the dependency graph against the Go vulnerability database, + # reporting only vulnerabilities reachable from our code. + - name: Run govulncheck + run: | + go install golang.org/x/vuln/cmd/govulncheck@latest + govulncheck ./... + docs-validate: name: Docs Validation runs-on: ubuntu-latest @@ -166,5 +185,8 @@ jobs: go-version: ${{ env.GO_VERSION }} cache: true + - name: Verify module integrity + run: go mod verify + - name: Build run: go build -v ./cmd/gomodel From 7893eb424cbe07ee5cb86059811e40bb258f79d5 Mon Sep 17 00:00:00 2001 From: "Jakub A. W" Date: Wed, 17 Jun 2026 15:29:31 +0200 Subject: [PATCH 2/4] ci: collapse go test jobs into a matrix and un-gate build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The unit, e2e, integration, and contract jobs shared identical checkout/setup-go/cache boilerplate and differed only in the test command, so they now run as a single matrix job. Check names are preserved (Unit Tests, E2E Tests, Integration Tests, Contract Replay Tests) so required status checks keep matching. The build job no longer waits on the test jobs — compiling the binary doesn't depend on tests passing, so it now runs in parallel and shortens the critical path. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/test.yml | 72 ++++++++++++-------------------------- 1 file changed, 22 insertions(+), 50 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9ff4258d..8877d36f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -37,9 +37,24 @@ jobs: # the schema fetch is reliable again; track in this PR/branch discussion. verify: false - test-unit: - name: Unit Tests + # Unit, E2E, integration, and contract suites share identical setup and + # differ only in the test command, so they run as one matrix. + go-tests: + name: ${{ matrix.name }} runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - name: Unit Tests + cmd: make test-race + coverage: true + - name: E2E Tests + cmd: go test -v -tags=e2e -timeout=5m ./tests/e2e/... + - name: Integration Tests + cmd: go test -v -tags=integration -timeout=10m ./tests/integration/... + - name: Contract Replay Tests + cmd: go test -v -tags=contract -timeout=5m ./tests/contract/... steps: - uses: actions/checkout@v6 @@ -49,10 +64,11 @@ jobs: go-version: ${{ env.GO_VERSION }} cache: true - - name: Run unit tests - run: make test-race + - name: Run tests + run: ${{ matrix.cmd }} - name: Upload coverage + if: matrix.coverage uses: codecov/codecov-action@v7 with: files: ./coverage.out @@ -73,51 +89,6 @@ jobs: - name: Run dashboard JavaScript tests run: make test-dashboard - test-e2e: - name: E2E Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version: ${{ env.GO_VERSION }} - cache: true - - - name: Run E2E tests - run: go test -v -tags=e2e -timeout=5m ./tests/e2e/... - - integration: - name: Integration Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version: ${{ env.GO_VERSION }} - cache: true - - - name: Run integration tests - run: go test -v -tags=integration -timeout=10m ./tests/integration/... - - test-contract: - name: Contract Replay Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version: ${{ env.GO_VERSION }} - cache: true - - - name: Run contract replay tests - run: go test -v -tags=contract -timeout=5m ./tests/contract/... - performance: name: Performance Guard runs-on: ubuntu-latest @@ -172,10 +143,11 @@ jobs: run: npx mint validate working-directory: docs + # Compiling the binary doesn't depend on tests passing, so this runs in + # parallel with the test jobs rather than gating behind them. build: name: Build runs-on: ubuntu-latest - needs: [lint, test-unit, test-dashboard, test-e2e, integration, test-contract, performance] steps: - uses: actions/checkout@v6 From 60e26e23ca84ecc3faea2a209e085c78304ddb4b Mon Sep 17 00:00:00 2001 From: "Jakub A. W" Date: Wed, 17 Jun 2026 15:33:38 +0200 Subject: [PATCH 3/4] ci: harden vulncheck job (timeout + swagger-tag scan) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address review feedback on the vulncheck job: - Add timeout-minutes: 10 so a hung govulncheck can't run to the 360-minute default. - Add a second govulncheck run with -tags=swagger to cover the swagger-tagged production build (swagger_enabled.go), which the default tag set excludes. The tests/* suites behind e2e/integration/ contract tags are intentionally not scanned — they aren't shipped. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/test.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8877d36f..9454a94b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -108,6 +108,7 @@ jobs: vulncheck: name: Vulnerability Scan runs-on: ubuntu-latest + timeout-minutes: 10 steps: - uses: actions/checkout@v6 @@ -118,11 +119,15 @@ jobs: cache: true # Scans the dependency graph against the Go vulnerability database, - # reporting only vulnerabilities reachable from our code. + # reporting only vulnerabilities reachable from our code. The second run + # covers the swagger-tagged production build (swagger_enabled.go), which + # the default tag set excludes. The tests/* suites behind e2e/integration/ + # contract tags are deliberately skipped — they aren't in the shipped binary. - name: Run govulncheck run: | go install golang.org/x/vuln/cmd/govulncheck@latest govulncheck ./... + govulncheck -tags=swagger ./... docs-validate: name: Docs Validation From 85806ef6cc549a11318aabb295e83930e2a7387d Mon Sep 17 00:00:00 2001 From: "Jakub A. W" Date: Wed, 17 Jun 2026 15:44:27 +0200 Subject: [PATCH 4/4] ci: pin govulncheck to v1.3.0 Replace @latest with an explicit version so the vulnerability gate is reproducible and doesn't drift with upstream releases. v1.3.0 is the current latest; bump intentionally when updating. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9454a94b..26422d20 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -125,7 +125,7 @@ jobs: # contract tags are deliberately skipped — they aren't in the shipped binary. - name: Run govulncheck run: | - go install golang.org/x/vuln/cmd/govulncheck@latest + go install golang.org/x/vuln/cmd/govulncheck@v1.3.0 govulncheck ./... govulncheck -tags=swagger ./...