66 branches :
77 - main
88
9+ concurrency :
10+ group : ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
11+ cancel-in-progress : ${{ github.event_name == 'pull_request' }}
12+
13+ permissions :
14+ contents : read
15+
916jobs :
10- smoke :
11- name : Smoke (${{ matrix.os }})
12- runs-on : ${{ matrix.os }}
13- strategy :
14- fail-fast : false
15- matrix :
16- os :
17- - ubuntu-latest
18- - macos-latest
19- - windows-latest
17+ quality :
18+ name : Code Quality & Lint
19+ runs-on : ubuntu-latest
20+ timeout-minutes : 10
21+ permissions :
22+ contents : read
2023
2124 steps :
2225 - name : Checkout
23- uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
26+ uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.2.2
2427 with :
2528 persist-credentials : false
2629
2730 - name : Setup Go
28- uses : actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff
31+ uses : actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.3.0
2932 with :
3033 go-version-file : go.mod
3134 cache : true
3235
33- - name : Install Make on Windows
34- if : matrix.os == 'windows-latest'
35- shell : pwsh
36- run : choco install make --no-progress -y
37-
38- - name : Validate quality targets with stock macOS Make
39- if : matrix.os == 'macos-latest'
40- env :
41- GIT_CONFIG_COUNT : 1
42- GIT_CONFIG_KEY_0 : grep.patternType
43- GIT_CONFIG_VALUE_0 : fixed
44- run : make -n vulncheck
45-
46- - name : Check vulnerabilities through native Windows Make
47- if : matrix.os == 'windows-latest'
48- shell : cmd
49- run : make vulncheck
36+ - name : Check formatting
37+ run : make fmt-check
5038
51- - name : Check dead code through native Windows Make
52- if : matrix.os == 'windows-latest'
39+ - name : Vet
40+ run : go vet ./...
41+
42+ - name : deadcode (advisory)
5343 continue-on-error : true
54- shell : cmd
5544 run : make deadcode
5645
57- - name : Run static lint through native Windows Make
58- if : matrix.os == 'windows-latest'
46+ - name : golangci-lint (advisory)
5947 continue-on-error : true
60- shell : cmd
6148 run : make lint-static
6249
63- - name : Check formatting
64- if : matrix.os == 'ubuntu-latest'
50+ test :
51+ name : Unit Tests & Coverage
52+ runs-on : ubuntu-latest
53+ timeout-minutes : 15
54+ permissions :
55+ contents : read
56+
57+ steps :
58+ - name : Checkout
59+ uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.2.2
60+ with :
61+ persist-credentials : false
62+
63+ - name : Setup Go
64+ uses : actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.3.0
65+ with :
66+ go-version-file : go.mod
67+ cache : true
68+
69+ - name : Test with coverage
70+ run : |
71+ go test -count=1 -coverprofile=coverage.out -covermode=atomic ./...
72+
73+ - name : Publish coverage summary
74+ if : always()
6575 shell : bash
6676 run : |
67- unformatted="$(gofmt -l .)"
68- if [ -n "$unformatted" ]; then
69- echo "gofmt needed on:" >&2
70- echo "$unformatted" >&2
71- exit 1
77+ if [ -f coverage.out ]; then
78+ go tool cover -func=coverage.out | awk '
79+ BEGIN {
80+ total = "unknown"
81+ rows = ""
82+ }
83+ $1 == "total:" {
84+ total = $3
85+ next
86+ }
87+ {
88+ rows = rows sprintf("| `%s` | `%s` | **%s** |\n", $1, $2, $3)
89+ }
90+ END {
91+ print "### 📊 Test Coverage Summary: **" total "**"
92+ print "<details><summary>Coverage per function</summary>\n"
93+ print "| File | Function | Coverage |"
94+ print "| :--- | :--- | :--- |"
95+ printf "%s", rows
96+ print "</details>"
97+ }' >> "$GITHUB_STEP_SUMMARY"
7298 fi
7399
74- - name : Vet
75- if : matrix.os == 'ubuntu-latest'
76- run : go vet ./...
100+ - name : Upload coverage artifact
101+ if : always()
102+ uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
103+ with :
104+ name : zero-coverage-report
105+ path : coverage.out
106+ if-no-files-found : warn
107+
108+ smoke :
109+ name : Smoke (${{ matrix.os }})
110+ runs-on : ${{ matrix.os }}
111+ timeout-minutes : 15
112+ strategy :
113+ fail-fast : false
114+ matrix :
115+ os :
116+ - ubuntu-latest
117+ - macos-latest
118+ - windows-latest
119+
120+ permissions :
121+ contents : read
77122
78- - name : Test
123+ steps :
124+ - name : Checkout
125+ uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.2.2
126+ with :
127+ persist-credentials : false
128+
129+ - name : Setup Go
130+ uses : actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.3.0
131+ with :
132+ go-version-file : go.mod
133+ cache : true
134+
135+ - name : Test (Fast Non-Race)
79136 run : go test ./...
80137
81138 - name : Build binary
@@ -84,9 +141,15 @@ jobs:
84141 - name : Smoke binary
85142 run : go run ./cmd/zero-release smoke
86143
87- performance :
88- name : Performance Smoke
144+ race :
145+ name : Race Detector
89146 runs-on : ubuntu-latest
147+ permissions :
148+ contents : read
149+ # A race the detector newly reports can present as a deadlock rather than a
150+ # failure, and the default job timeout is six hours. This job is expected to
151+ # be the longest in the workflow, so the ceiling is generous but finite.
152+ timeout-minutes : 30
90153
91154 steps :
92155 - name : Checkout
@@ -100,55 +163,70 @@ jobs:
100163 go-version-file : go.mod
101164 cache : true
102165
166+ # Invoke the Makefile target rather than repeating its flags. `make test`
167+ # is already `go test ./... -race -count=1`, so running it here is what
168+ # stops the project's declared test command and what CI actually runs
169+ # from drifting apart again. The race detector needs cgo, which the
170+ # hosted ubuntu runner supplies without an extra setup step.
171+ - name : Test with the race detector
172+ run : make test
173+
174+ performance :
175+ name : Performance Smoke
176+ runs-on : ubuntu-latest
177+ timeout-minutes : 10
178+ permissions :
179+ contents : read
180+
181+ steps :
182+ - name : Checkout
183+ uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.2.2
184+ with :
185+ persist-credentials : false
186+
187+ - name : Setup Go
188+ uses : actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.3.0
189+ with :
190+ go-version-file : go.mod
191+ cache : true
192+
103193 - name : Build binary
104194 run : go run ./cmd/zero-release build
105195
106196 - name : Performance smoke
107- run : go run ./cmd/zero-perf-bench --output dist/perf/perf-bench.json --ci
197+ run : |
198+ mkdir -p dist/perf
199+ go run ./cmd/zero-perf-bench --output dist/perf/perf-bench.json --ci
108200
109201 - name : Upload performance report
110202 if : always()
111- uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
203+ uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
112204 with :
113205 name : zero-performance-smoke
114206 path : dist/perf/perf-bench.json
115207 if-no-files-found : warn
116208
117209 security :
118- name : Security & code health
210+ name : Security & Code Health
119211 runs-on : ubuntu-latest
212+ timeout-minutes : 10
213+ permissions :
214+ contents : read
120215
121216 steps :
122217 - name : Checkout
123- uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
218+ uses : actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.2.2
124219 with :
125220 persist-credentials : false
126221
127222 - name : Setup Go
128- uses : actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff
223+ uses : actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.3.0
129224 with :
130225 go-version-file : go.mod
131226 cache : true
132227
133- # Hard gate: fails the build when code reaches a known vulnerability. A stdlib
134- # CVE is cleared by a toolchain bump (see go.mod). May also flag a newly
135- # published advisory on an unrelated PR — intentional: do not ship known vulns.
136- - name : govulncheck
228+ - name : govulncheck (linux)
137229 run : make vulncheck
138230
139- # Advisory: reports functions unreachable from any cmd/* main so dormant
140- # code is visible in CI. Non-blocking while the dormant subsystems are
141- # still being wired or removed.
142- - name : deadcode (advisory)
143- continue-on-error : true
144- run : make deadcode
145-
146- # Advisory: catches what deadcode's whole-program reachability analysis
147- # doesn't, unused private functions/assignments reachable within a
148- # package but never actually called, plus staticcheck-style correctness
149- # and readability issues. Scoped to a few linters rather than the full
150- # default battery, and non-blocking, while the existing findings across
151- # the repo are cleaned up incrementally (see #527).
152- - name : golangci-lint (advisory)
153- continue-on-error : true
154- run : make lint-static
231+ - name : govulncheck (windows)
232+ run : make vulncheck-windows
0 commit comments