Skip to content
Open
194 changes: 121 additions & 73 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,76 +6,133 @@ on:
branches:
- main

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

permissions:
contents: read

jobs:
smoke:
name: Smoke (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
quality:
name: Code Quality & Lint
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read

steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.2.2
with:
persist-credentials: false

- name: Setup Go
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.3.0
with:
go-version-file: go.mod
cache: true

- name: Install Make on Windows
if: matrix.os == 'windows-latest'
shell: pwsh
run: choco install make --no-progress -y

- name: Validate quality targets with stock macOS Make
if: matrix.os == 'macos-latest'
env:
GIT_CONFIG_COUNT: 1
GIT_CONFIG_KEY_0: grep.patternType
GIT_CONFIG_VALUE_0: fixed
run: make -n vulncheck

- name: Check vulnerabilities through native Windows Make
if: matrix.os == 'windows-latest'
shell: cmd
run: make vulncheck
- name: Check formatting
run: make fmt-check

- name: Vet
run: go vet ./...

- name: Check dead code through native Windows Make
if: matrix.os == 'windows-latest'
- name: deadcode (advisory)
continue-on-error: true
shell: cmd
run: make deadcode

- name: Run static lint through native Windows Make
if: matrix.os == 'windows-latest'
- name: golangci-lint (advisory)
continue-on-error: true
shell: cmd
run: make lint-static

- name: Check formatting
if: matrix.os == 'ubuntu-latest'
test:
name: Unit Tests & Race Detector
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read

steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.2.2
with:
persist-credentials: false

- name: Setup Go
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.3.0
with:
go-version-file: go.mod
cache: true

- name: Test with coverage
run: |
go test -count=1 -coverprofile=coverage.out -covermode=atomic ./...

- name: Publish coverage summary
if: always()
shell: bash
run: |
unformatted="$(gofmt -l .)"
if [ -n "$unformatted" ]; then
echo "gofmt needed on:" >&2
echo "$unformatted" >&2
exit 1
if [ -f coverage.out ]; then
go tool cover -func=coverage.out | awk '
BEGIN {
total = "unknown"
rows = ""
}
$1 == "total:" {
total = $3
next
}
{
rows = rows sprintf("| `%s` | `%s` | **%s** |\n", $1, $2, $3)
}
END {
print "### 📊 Test Coverage Summary: **" total "**"
print "<details><summary>Coverage per function</summary>\n"
print "| File | Function | Coverage |"
print "| :--- | :--- | :--- |"
printf "%s", rows
print "</details>"
}' >> "$GITHUB_STEP_SUMMARY"
fi
Comment thread
coderabbitai[bot] marked this conversation as resolved.

- name: Vet
if: matrix.os == 'ubuntu-latest'
run: go vet ./...
- name: Upload coverage artifact
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: zero-coverage-report
path: coverage.out
if-no-files-found: warn

smoke:
name: Smoke (${{ matrix.os }})
runs-on: ${{ matrix.os }}
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest

- name: Test
permissions:
contents: read

steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.2.2
with:
persist-credentials: false

- name: Setup Go
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.3.0
with:
go-version-file: go.mod
cache: true

- name: Test (Fast Non-Race)
run: go test ./...

- name: Build binary
Expand All @@ -87,15 +144,18 @@ jobs:
performance:
name: Performance Smoke
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read

steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.2.2
with:
persist-credentials: false

- name: Setup Go
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.3.0
with:
go-version-file: go.mod
cache: true
Expand All @@ -104,51 +164,39 @@ jobs:
run: go run ./cmd/zero-release build

- name: Performance smoke
run: go run ./cmd/zero-perf-bench --output dist/perf/perf-bench.json --ci
run: |
mkdir -p dist/perf
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
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: zero-performance-smoke
path: dist/perf/perf-bench.json
if-no-files-found: warn

security:
name: Security & code health
name: Security & Code Health
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read

steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.2.2
with:
persist-credentials: false

- name: Setup Go
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.3.0
with:
go-version-file: go.mod
cache: true

# 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
- name: govulncheck (linux)
run: make vulncheck

# 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: make deadcode

# 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: make lint-static
- name: govulncheck (windows)
run: make vulncheck-windows
3 changes: 3 additions & 0 deletions .github/workflows/zero-action-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ on:
- docs/GITHUB_ACTION.md
- .github/workflows/zero-action-smoke.yml

permissions:
contents: read

jobs:
validate:
name: Validate action.yml
Expand Down
14 changes: 11 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ DEADCODE_VERSION := v0.46.0
GOLANGCI_LINT_VERSION := v2.12.2
GOVULNCHECK_VERSION := v1.3.0

.PHONY: build build-all test test-race vet fmt fmt-check lint lint-static deadcode vulncheck tidy clean baseline help
export GOWORK ?= off

.PHONY: build build-all test test-race vet fmt fmt-check lint lint-static deadcode vulncheck vulncheck-windows tidy clean baseline help

# Build the main CLI binary into ./zero.
build:
Expand Down Expand Up @@ -44,7 +46,8 @@ lint: fmt-check vet
# the possibly stale Go toolchain or consulting a multi-module GOWORK. git grep
# works with both POSIX shells and cmd.exe, including GNU Make 3.81 on macOS.
# The target-specific export is shell-independent.
lint-static deadcode vulncheck: export GOTOOLCHAIN = $(GO_TOOLCHAIN)
lint-static deadcode vulncheck vulncheck-windows: export GOTOOLCHAIN = $(GO_TOOLCHAIN)
lint-static deadcode vulncheck vulncheck-windows: export GOWORK = off

lint-static:
go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION) run --enable-only unused,ineffassign,staticcheck ./...
Expand All @@ -55,6 +58,11 @@ deadcode:
vulncheck:
go run golang.org/x/vuln/cmd/govulncheck@$(GOVULNCHECK_VERSION) ./...

vulncheck-windows:
mkdir -p "$(CURDIR)/.cache/gobin"
GOBIN="$(CURDIR)/.cache/gobin" go install golang.org/x/vuln/cmd/govulncheck@$(GOVULNCHECK_VERSION)
GOOS=windows "$(CURDIR)/.cache/gobin/govulncheck" ./...

tidy:
go mod tidy

Expand All @@ -77,4 +85,4 @@ baseline: build
--output internal/perfbench/reports/baseline.json

help:
@echo "Targets: build (default), build-all, test, test-quick, vet, fmt, fmt-check, lint, lint-static, deadcode, vulncheck, tidy, clean, baseline"
@echo "Targets: build (default), build-all, test, test-quick, vet, fmt, fmt-check, lint, lint-static, deadcode, vulncheck, vulncheck-windows, tidy, clean, baseline"
Loading