name: CI on: pull_request: push: branches: - main jobs: smoke: name: Smoke (${{ matrix.os }}) runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: - ubuntu-latest - macos-latest - windows-latest steps: - name: Checkout uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: persist-credentials: false - name: Setup Go uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff with: go-version-file: go.mod cache: true - name: Check formatting if: matrix.os == 'ubuntu-latest' shell: bash run: | unformatted="$(gofmt -l .)" if [ -n "$unformatted" ]; then echo "gofmt needed on:" >&2 echo "$unformatted" >&2 exit 1 fi - name: Vet if: matrix.os == 'ubuntu-latest' run: go vet ./... - name: Test run: go test ./... - name: Build binary run: go run ./cmd/zero-release build - name: Smoke binary run: go run ./cmd/zero-release smoke performance: name: Performance Smoke runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: persist-credentials: false - name: Setup Go uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff with: go-version-file: go.mod cache: true - name: Build binary run: go run ./cmd/zero-release build - name: Performance smoke run: go run ./cmd/zero-perf-bench --output dist/perf/perf-bench.json --ci - name: Upload performance report if: always() uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: zero-performance-smoke path: dist/perf/perf-bench.json if-no-files-found: warn security: name: Security & code health runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: persist-credentials: false - name: Setup Go uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff with: go-version-file: go.mod cache: true # govulncheck, deadcode, and golangci-lint each resolve a toolchain from # their own modules, which can drop below the version go.mod requires and # then fail to load our packages. Pin GOTOOLCHAIN to the go.mod toolchain # so all three run under it. - name: Pin toolchain from go.mod run: | toolchain="$(awk '/^toolchain /{print $2}' go.mod)" echo "GOTOOLCHAIN=${toolchain:-auto}" >> "$GITHUB_ENV" # Hard gate: fails the build when code reaches a known vulnerability. A stdlib # CVE is cleared by a toolchain bump (see go.mod). May also flag a newly # published advisory on an unrelated PR — intentional: do not ship known vulns. - name: govulncheck run: go run golang.org/x/vuln/cmd/govulncheck@v1.3.0 ./... # Advisory: reports functions unreachable from any cmd/* main so dormant # code is visible in CI. Non-blocking while the dormant subsystems are # still being wired or removed. - name: deadcode (advisory) continue-on-error: true run: go run golang.org/x/tools/cmd/deadcode@v0.46.0 -test=false ./... # Advisory: catches what deadcode's whole-program reachability analysis # doesn't, unused private functions/assignments reachable within a # package but never actually called, plus staticcheck-style correctness # and readability issues. Scoped to a few linters rather than the full # default battery, and non-blocking, while the existing findings across # the repo are cleaned up incrementally (see #527). - name: golangci-lint (advisory) continue-on-error: true run: go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.2 run --enable-only unused,ineffassign,staticcheck ./...