3232 - run : task vuln
3333 - run : task test:race
3434 - run : task coverage
35+ - name : Coverage summary
36+ if : always()
37+ run : bash scripts/coverage-report.sh coverage.out "unit (hermetic)" >> "$GITHUB_STEP_SUMMARY"
3538 - run : task test:integration
3639 - run : task build
3740 - run : ./devcontainer --version
@@ -49,11 +52,12 @@ jobs:
4952 language : Go
5053 label : code-coverage/go
5154
55+ # Binary covdata for the cross-lane merge (coverage-report job).
5256 - uses : actions/upload-artifact@v7
5357 if : always()
5458 with :
55- name : unit-coverage
56- path : coverage.out
59+ name : covdata-unit
60+ path : artifacts/ coverage/data/unit
5761 if-no-files-found : error
5862
5963 e2e :
@@ -70,11 +74,14 @@ jobs:
7074 repo-token : ${{ secrets.GITHUB_TOKEN }}
7175
7276 - run : task coverage:e2e
77+ - name : Coverage summary
78+ if : always()
79+ run : bash scripts/coverage-report.sh artifacts/coverage/data/e2e "e2e" >> "$GITHUB_STEP_SUMMARY"
7380 - uses : actions/upload-artifact@v7
7481 if : always()
7582 with :
76- name : e2e-coverage
77- path : artifacts/coverage/e2e.out
83+ name : covdata-e2e
84+ path : artifacts/coverage/data/ e2e
7885 if-no-files-found : error
7986 - if : always()
8087 run : task clean
@@ -106,6 +113,9 @@ jobs:
106113 # functional parity run above release-like, and avoid conflating subprocess
107114 # coverage with the hermetic unit profile.
108115 - run : task coverage:parity-contract
116+ - name : Coverage summary
117+ if : always()
118+ run : bash scripts/coverage-report.sh artifacts/coverage/data/contract "parity:contract" >> "$GITHUB_STEP_SUMMARY"
109119 - if : always()
110120 run : |
111121 mkdir -p artifacts
@@ -116,10 +126,16 @@ jobs:
116126 name : parity-contract-network-v0.88.0
117127 path : artifacts/
118128 if-no-files-found : error
129+ - uses : actions/upload-artifact@v7
130+ if : always()
131+ with :
132+ name : covdata-contract
133+ path : artifacts/coverage/data/contract
134+ if-no-files-found : error
119135
120136 # Runtime lane of the parity matrix (creates real containers via Docker) on
121137 # push/PR, SCOPED to the commands affected by the change: the full matrix takes
122- # ~45 min, so .github/ scripts/parity-affected.sh maps the diff to a
138+ # ~45 min, so scripts/parity-affected.sh maps the diff to a
123139 # PARITY_COMMAND allowlist (or "all"/"none"). The daily parity-runtime-full job
124140 # is the backstop that always runs the whole thing.
125141 parity-runtime :
@@ -141,46 +157,11 @@ jobs:
141157 id : affected
142158 run : |
143159 if [ "${{ github.event_name }}" = "pull_request" ]; then
144- base="${{ github.event.pull_request.base.sha }}"
145- head="${{ github.event.pull_request.head.sha }}"
146- else
147- base="${{ github.event.before }}"
148- head="${{ github.sha }}"
149- fi
150- # New branch / unknown base (e.g. all-zero before-SHA) → run everything.
151- if [ -z "$base" ] || ! git cat-file -e "${base}^{commit}" 2>/dev/null; then
152- echo "commands=all" >> "$GITHUB_OUTPUT"; echo "run=true" >> "$GITHUB_OUTPUT"
153- echo "unknown base → running the full matrix"; exit 0
154- fi
155- files=$(git diff --name-only "$base" "$head")
156- echo "changed files:"; echo "$files"
157- cmds=$(printf '%s\n' "$files" | .github/scripts/parity-affected.sh)
158- echo "affected parity commands: $cmds"
159- echo "commands=$cmds" >> "$GITHUB_OUTPUT"
160- if [ "$cmds" = "none" ]; then
161- echo "run=false" >> "$GITHUB_OUTPUT"
162- echo "no runtime-relevant changes → skipping the runtime matrix"
160+ base="${{ github.event.pull_request.base.sha }}"; head="${{ github.event.pull_request.head.sha }}"
163161 else
164- echo "run=true" >> "$GITHUB_OUTPUT "
162+ base="${{ github.event.before }}"; head="${{ github.sha }} "
165163 fi
166- # The runtime matrix builds real images serially; they accumulate and
167- # exhaust the runner's root disk ("No space left on device" — the runner then
168- # dies hard, losing logs). /mnt is the SAME filesystem as / on these runners,
169- # so it buys nothing; instead free the big preinstalled SDKs (Go/Node are
170- # reinstalled by the setup steps that follow) for ~25-30GB of headroom. Also
171- # enable the containerd image store (needed for cache export / --platform).
172- - name : Free disk space + configure Docker (containerd store)
173- if : steps.affected.outputs.run == 'true'
174- run : |
175- echo "before:"; df -h / | tail -1
176- sudo rm -rf /usr/share/dotnet /opt/ghc /usr/local/lib/android \
177- /opt/hostedtoolcache/CodeQL /usr/share/swift \
178- /usr/local/share/boost /usr/lib/jvm || true
179- sudo docker image prune -af >/dev/null 2>&1 || true
180- echo "after:"; df -h / | tail -1
181- echo '{"features":{"containerd-snapshotter":true}}' | sudo tee /etc/docker/daemon.json
182- sudo systemctl restart docker
183- docker info -f 'driver={{.DriverStatus}}'
164+ bash scripts/parity-affected-commands.sh "$base" "$head" >> "$GITHUB_OUTPUT"
184165 - uses : actions/setup-go@v6
185166 if : steps.affected.outputs.run == 'true'
186167 with :
@@ -194,6 +175,10 @@ jobs:
194175 with :
195176 version : 3.x
196177 repo-token : ${{ secrets.GITHUB_TOKEN }}
178+ # Free disk + enable the containerd image store (build-cache export). Reuses
179+ # the Taskfile so the runner prep is identical to release.yml.
180+ - if : steps.affected.outputs.run == 'true'
181+ run : task ci:prepare-runner
197182
198183 - if : steps.affected.outputs.run == 'true'
199184 run : task reference
@@ -227,17 +212,6 @@ jobs:
227212 - uses : actions/checkout@v7
228213 with :
229214 submodules : recursive
230- - name : Free disk space + configure Docker (containerd store)
231- run : |
232- echo "before:"; df -h / | tail -1
233- sudo rm -rf /usr/share/dotnet /opt/ghc /usr/local/lib/android \
234- /opt/hostedtoolcache/CodeQL /usr/share/swift \
235- /usr/local/share/boost /usr/lib/jvm || true
236- sudo docker image prune -af >/dev/null 2>&1 || true
237- echo "after:"; df -h / | tail -1
238- echo '{"features":{"containerd-snapshotter":true}}' | sudo tee /etc/docker/daemon.json
239- sudo systemctl restart docker
240- docker info -f 'driver={{.DriverStatus}}'
241215 - uses : actions/setup-go@v6
242216 with :
243217 go-version-file : go.mod
@@ -248,10 +222,16 @@ jobs:
248222 with :
249223 version : 3.x
250224 repo-token : ${{ secrets.GITHUB_TOKEN }}
225+ - run : task ci:prepare-runner
251226
252227 - run : task reference
228+ # The full lanes run the instrumented binary, so this measures coverage AND
229+ # gates parity; coverage:merge unions them into one cross-lane report.
253230 - run : task coverage:parity-runtime
254231 - run : task coverage:parity-publish
232+ - name : Merged coverage report
233+ if : always()
234+ run : task coverage:merge | tee -a "$GITHUB_STEP_SUMMARY"
255235 - if : always()
256236 run : |
257237 mkdir -p artifacts
@@ -260,7 +240,9 @@ jobs:
260240 if : always()
261241 with :
262242 name : parity-runtime-full-v0.88.0
263- path : artifacts/
243+ path : |
244+ artifacts/
245+ artifacts/coverage/
264246 if-no-files-found : error
265247 - if : always()
266248 run : task clean
@@ -285,13 +267,6 @@ jobs:
285267 uses : docker/setup-qemu-action@v3
286268 with :
287269 platforms : arm64
288- - name : Free disk space + configure Docker (containerd store)
289- run : |
290- sudo rm -rf /usr/share/dotnet /opt/ghc /usr/local/lib/android \
291- /opt/hostedtoolcache/CodeQL /usr/share/swift \
292- /usr/local/share/boost /usr/lib/jvm || true
293- echo '{"features":{"containerd-snapshotter":true}}' | sudo tee /etc/docker/daemon.json
294- sudo systemctl restart docker
295270 - uses : actions/setup-go@v6
296271 with :
297272 go-version-file : go.mod
@@ -302,12 +277,47 @@ jobs:
302277 with :
303278 version : 3.x
304279 repo-token : ${{ secrets.GITHUB_TOKEN }}
280+ - run : task ci:prepare-runner
305281 - run : task reference
306282 - run : task parity:runtime
307283 - if : always()
308284 run : task clean
309285
310286
287+ # Cross-lane coverage: merge the per-PR lanes' covdata (unit + e2e + contract)
288+ # into the one number no single lane shows, and post it to the run summary.
289+ coverage-report :
290+ if : always() && (github.event_name == 'push' || github.event_name == 'pull_request')
291+ runs-on : ubuntu-latest
292+ needs : [lint-and-test, e2e, parity]
293+ steps :
294+ - uses : actions/checkout@v7
295+ - uses : actions/setup-go@v6
296+ with :
297+ go-version-file : go.mod
298+ - uses : go-task/setup-task@v2
299+ with :
300+ version : 3.x
301+ repo-token : ${{ secrets.GITHUB_TOKEN }}
302+ - name : Download lane covdata
303+ uses : actions/download-artifact@v7
304+ with :
305+ pattern : covdata-*
306+ path : artifacts/coverage/data
307+ # download-artifact nests each artifact under covdata-<lane>/; flatten to <lane>/.
308+ - name : Normalize lane dirs
309+ run : |
310+ cd artifacts/coverage/data
311+ for d in covdata-*; do [ -d "$d" ] && mv "$d" "${d#covdata-}"; done
312+ ls -R . || true
313+ - name : Merged coverage report
314+ run : task coverage:merge | tee -a "$GITHUB_STEP_SUMMARY"
315+ - uses : actions/upload-artifact@v7
316+ with :
317+ name : covdata-merged
318+ path : artifacts/coverage/merged.out
319+ if-no-files-found : warn
320+
311321 cross-compile :
312322 runs-on : ubuntu-latest
313323 needs : lint-and-test
0 commit comments