Skip to content

ci: go vet/lint steps don't use the per-module loop convention [cli part] #1478

Description

@cristim

Summary

ci.yml's three core code-health checks silently skip every module except the root one, in a repo that has been multi-module (go.work: ., pkg, providers/aws, providers/azure, providers/gcp, tests/e2e) for some time:

  • "Run go vet" (.github/workflows/ci.yml around line 53-54): go vet ./...
  • "Run unit tests" (Unit Tests job, around line 97-99): go test -v -race -short -coverprofile=coverage.out -covermode=atomic ./...
  • "Run integration tests" (Integration Tests job, around line 180): go test -v -race -tags=integration -coverprofile=coverage-integration.out ./...
  • Lint Code job: golangci-lint run --timeout=10m (no path arg)

In a Go workspace, a bare ./... from the repo root only expands to packages in the current module (confirmed locally: go list ./... from repo root returns 38 packages, zero of which are under providers/). go.work only affects cross-module dependency resolution, not what ./... expands to.

The govulncheck and gosec steps already handle this correctly — both loop for mod in . pkg providers/aws providers/azure providers/gcp tests/e2e; do (cd "$mod" && <tool> ./...); done, with an inline comment explaining exactly why. The same fix was never applied to go vet, unit tests, integration tests, or golangci-lint.

Impact

  • providers/aws, providers/azure, providers/gcp, pkg, and tests/e2e get zero go vet/lint coverage and their Go tests never run in CI, even though these packages contain the actual cloud-provider purchase logic (the highest money-risk code in the repo).
  • Confirmed while verifying PR fixing the EC2 RI term silent-default bug (follow-up to fix(providers/aws): fail loud on unrecognized RI term strings #1207): the fix and its new regression tests live in providers/aws/services/ec2, so go build/vet/test and lint for that package are exercised only by whatever a contributor runs locally, not by CI.
  • Locally reproducing golangci-lint v2.10.1 (the exact CI-pinned version) scoped to providers/aws/services/ec2 alone (not ./... bare) surfaces ~27 pre-existing findings (misspellings, gocritic rangeValCopy, a gosec G117 field-name match, godot comment-period nits) that have presumably been accumulating silently since this gap opened.

Suggested fix

Mirror the govulncheck/gosec per-module loop for the go vet, unit-test, integration-test, and golangci-lint steps. Since this will likely surface the accumulated per-module lint/vet debt (~27+ in providers/aws alone, azure/gcp not yet surveyed), budget this as a two-part effort: (1) wire up the per-module loop, (2) batch-fix the debt it uncovers rather than suppressing it (per this repo's "no masking CI debt" convention) or gating it behind continue-on-error.

Follow-up

Filed while adversarially verifying a merged PR; not fixed here to keep that fix scoped. Assessing severity as high (money-risk provider code has zero CI vet/test/lint coverage) but not critical (no active incident; the gap is latent, not currently causing production harm), priority p1 (should be next up, not urgent-drop-everything), effort m (loop change is small; the debt cleanup it uncovers is the real size unknown until surveyed).

Scope after the split

The CUDly monorepo was split into four repos. The providers/aws, providers/azure, providers/gcp, and pkg modules named above now live in cloud-commitments-go; that repo has the genuine live version of this gap (go vet and lint still bare, still skipping five of its six go.work modules) — see LeanerCloud/cloud-commitments-go#118. cloud-commitments-platform inherited the tests/e2e module and has the same live gap for it — see LeanerCloud/cloud-commitments-platform#346.

cloud-commitments-cli itself is a single-module repo (go.work only declares use .): there is no second module for go vet/lint to silently skip here today, and the unit-test/integration-test steps already loop for mod in .. This issue is kept open, scoped down to a consistency/hardening item: go vet and the lint action are the only two CI checks in this repo not using that same loop convention, which would silently regress into this exact bug if a second module is ever added.

Sibling issues:

Acceptance criteria (this repo)

  • go vet and the golangci-lint invocation are rewritten to use the same for mod in . loop pattern as the unit-test/integration-test/govulncheck/gosec steps, for consistency and to guard against a silent regression if a second module is added later.
  • No behavioral change expected today (single module); confirm go vet/lint output is unchanged before and after.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions