@@ -23,41 +23,36 @@ jobs:
2323 include :
2424 - os : ubuntu-latest
2525 target : x86_64-unknown-linux-musl
26+ platform : Linux
27+ comment_header : coverage-linux
2628 - os : windows-latest
2729 target : x86_64-pc-windows-msvc
30+ platform : Windows
31+ comment_header : coverage-windows
2832 steps :
2933 - name : Checkout
3034 uses : actions/checkout@v4
3135
32- - name : Post Coverage Started Comment (Linux)
33- if : startsWith(matrix.os, 'ubuntu')
36+ - name : Post Coverage Started Comment
3437 uses : marocchino/sticky-pull-request-comment@v2
3538 with :
36- header : coverage-linux
39+ header : ${{ matrix.comment_header }}
3740 message : |
38- ## Test Coverage Report (Linux )
41+ ## Test Coverage Report (${{ matrix.platform }} )
3942
4043 :hourglass_flowing_sand: **Coverage analysis in progress...**
4144
42- This comment will be updated with results when the analysis completes.
43-
44- - name : Post Coverage Started Comment (Windows)
45- if : startsWith(matrix.os, 'windows')
46- uses : marocchino/sticky-pull-request-comment@v2
47- with :
48- header : coverage-windows
49- message : |
50- ## Test Coverage Report (Windows)
51-
52- :hourglass_flowing_sand: **Coverage analysis in progress...**
53-
54- This comment will be updated with results when the analysis completes.
45+ Comparing against exact base `${{ github.event.pull_request.base.sha }}`.
5546
5647 - name : Set Python to PATH
5748 uses : actions/setup-python@v5
5849 with :
5950 python-version : " 3.12"
6051
52+ - name : Validate Snapshot Comparator
53+ run : python -m unittest discover -s scripts/tests -p 'test_*.py' -v
54+ shell : bash
55+
6156 - name : Add Conda to PATH (Windows)
6257 if : startsWith(matrix.os, 'windows')
6358 run : |
@@ -198,167 +193,47 @@ jobs:
198193 shell : bash
199194
200195 - name : Run Tests with Coverage
196+ id : coverage
201197 run : cargo llvm-cov --features ci --lcov --output-path lcov.info -- --nocapture --test-threads=1
202198 env :
203199 RUST_BACKTRACE : 1
204200 RUST_LOG : trace
205201 shell : bash
206202
207203 - name : Upload PR Coverage Artifact
204+ if : always()
208205 uses : actions/upload-artifact@v4
209206 with :
210207 name : coverage-pr-${{ matrix.os }}
211208 path : lcov.info
209+ if-no-files-found : ignore
212210
213- - name : Download Baseline Coverage
211+ - name : Download Exact PR Base Coverage
212+ if : always()
214213 uses : dawidd6/action-download-artifact@v6
215- id : download-baseline
216- continue-on-error : true
217214 with :
218215 workflow : coverage-baseline.yml
219- branch : main
216+ commit : ${{ github.event.pull_request.base.sha }}
217+ workflow_conclusion : success
220218 name : coverage-baseline-${{ matrix.os }}
221219 path : baseline-coverage
222-
223- - name : Install lcov (Linux)
224- if : startsWith(matrix.os, 'ubuntu')
225- run : sudo apt-get update && sudo apt-get install -y lcov
226-
227- - name : Install lcov (Windows)
228- if : startsWith(matrix.os, 'windows')
229- run : choco install lcov -y
220+ check_artifacts : true
221+ search_artifacts : true
222+
223+ - name : Compare Coverage Snapshot
224+ if : always()
225+ run : >-
226+ python scripts/quality_snapshot.py coverage
227+ --current lcov.info
228+ --baseline baseline-coverage/lcov.info
229+ --platform "${{ matrix.platform }}"
230+ --report coverage-report.md
231+ --summary "$GITHUB_STEP_SUMMARY"
230232 shell : bash
231233
232- - name : Generate Coverage Report (Linux)
233- if : startsWith(matrix.os, 'ubuntu')
234- id : coverage-linux
235- run : |
236- # Extract PR coverage
237- PR_LINES=$(lcov --summary lcov.info 2>&1 | grep "lines" | sed 's/.*: //' | sed 's/%.*//' | tr -d ' ')
238- PR_FUNCTIONS=$(lcov --summary lcov.info 2>&1 | grep "functions" | sed 's/.*: //' | sed 's/%.*//' | tr -d ' ')
239-
240- # Extract baseline coverage (default to 0 if not available)
241- if [ -f baseline-coverage/lcov.info ]; then
242- BASELINE_LINES=$(lcov --summary baseline-coverage/lcov.info 2>&1 | grep "lines" | sed 's/.*: //' | sed 's/%.*//' | tr -d ' ')
243- BASELINE_FUNCTIONS=$(lcov --summary baseline-coverage/lcov.info 2>&1 | grep "functions" | sed 's/.*: //' | sed 's/%.*//' | tr -d ' ')
244- else
245- BASELINE_LINES="0"
246- BASELINE_FUNCTIONS="0"
247- fi
248-
249- # Calculate diff
250- LINE_DIFF=$(echo "$PR_LINES - $BASELINE_LINES" | bc)
251- FUNC_DIFF=$(echo "$PR_FUNCTIONS - $BASELINE_FUNCTIONS" | bc)
252-
253- # Determine delta indicator
254- if (( $(echo "$LINE_DIFF > 0" | bc -l) )); then
255- DELTA_INDICATOR=":white_check_mark:"
256- elif (( $(echo "$LINE_DIFF < 0" | bc -l) )); then
257- DELTA_INDICATOR=":x:"
258- else
259- DELTA_INDICATOR=":heavy_minus_sign:"
260- fi
261-
262- # Set outputs
263- echo "pr_lines=$PR_LINES" >> $GITHUB_OUTPUT
264- echo "baseline_lines=$BASELINE_LINES" >> $GITHUB_OUTPUT
265- echo "line_diff=$LINE_DIFF" >> $GITHUB_OUTPUT
266- echo "delta_indicator=$DELTA_INDICATOR" >> $GITHUB_OUTPUT
267-
268- # Write step summary
269- echo "## Test Coverage Report (${{ matrix.os }})" >> $GITHUB_STEP_SUMMARY
270- echo "" >> $GITHUB_STEP_SUMMARY
271- echo "| Metric | Value |" >> $GITHUB_STEP_SUMMARY
272- echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY
273- echo "| Current Coverage | ${PR_LINES}% |" >> $GITHUB_STEP_SUMMARY
274- echo "| Base Branch Coverage | ${BASELINE_LINES}% |" >> $GITHUB_STEP_SUMMARY
275- echo "| Delta | ${LINE_DIFF}% ${DELTA_INDICATOR} |" >> $GITHUB_STEP_SUMMARY
276- shell : bash
277-
278- - name : Generate Coverage Report (Windows)
279- if : startsWith(matrix.os, 'windows')
280- id : coverage-windows
281- run : |
282- # Extract PR coverage
283- $prContent = Get-Content -Path "lcov.info" -Raw
284- $prLinesFound = ($prContent | Select-String -Pattern "LF:(\d+)" -AllMatches).Matches | ForEach-Object { [int]$_.Groups[1].Value } | Measure-Object -Sum | Select-Object -ExpandProperty Sum
285- $prLinesHit = ($prContent | Select-String -Pattern "LH:(\d+)" -AllMatches).Matches | ForEach-Object { [int]$_.Groups[1].Value } | Measure-Object -Sum | Select-Object -ExpandProperty Sum
286- if ($prLinesFound -gt 0) {
287- $prPct = [math]::Round(($prLinesHit / $prLinesFound) * 100, 2)
288- } else {
289- $prPct = 0
290- }
291-
292- # Extract baseline coverage (default to 0 if not available)
293- if (Test-Path "baseline-coverage/lcov.info") {
294- $baselineContent = Get-Content -Path "baseline-coverage/lcov.info" -Raw
295- $baselineLinesFound = ($baselineContent | Select-String -Pattern "LF:(\d+)" -AllMatches).Matches | ForEach-Object { [int]$_.Groups[1].Value } | Measure-Object -Sum | Select-Object -ExpandProperty Sum
296- $baselineLinesHit = ($baselineContent | Select-String -Pattern "LH:(\d+)" -AllMatches).Matches | ForEach-Object { [int]$_.Groups[1].Value } | Measure-Object -Sum | Select-Object -ExpandProperty Sum
297- if ($baselineLinesFound -gt 0) {
298- $baselinePct = [math]::Round(($baselineLinesHit / $baselineLinesFound) * 100, 2)
299- } else {
300- $baselinePct = 0
301- }
302- } else {
303- $baselinePct = 0
304- }
305-
306- $diff = [math]::Round($prPct - $baselinePct, 2)
307-
308- if ($diff -gt 0) {
309- $deltaIndicator = ":white_check_mark:"
310- } elseif ($diff -lt 0) {
311- $deltaIndicator = ":x:"
312- } else {
313- $deltaIndicator = ":heavy_minus_sign:"
314- }
315-
316- # Set outputs
317- echo "pr_lines=$prPct" >> $env:GITHUB_OUTPUT
318- echo "baseline_lines=$baselinePct" >> $env:GITHUB_OUTPUT
319- echo "line_diff=$diff" >> $env:GITHUB_OUTPUT
320- echo "delta_indicator=$deltaIndicator" >> $env:GITHUB_OUTPUT
321-
322- # Write step summary
323- echo "## Test Coverage Report (${{ matrix.os }})" >> $env:GITHUB_STEP_SUMMARY
324- echo "" >> $env:GITHUB_STEP_SUMMARY
325- echo "| Metric | Value |" >> $env:GITHUB_STEP_SUMMARY
326- echo "|--------|-------|" >> $env:GITHUB_STEP_SUMMARY
327- echo "| Current Coverage | ${prPct}% |" >> $env:GITHUB_STEP_SUMMARY
328- echo "| Base Branch Coverage | ${baselinePct}% |" >> $env:GITHUB_STEP_SUMMARY
329- echo "| Delta | ${diff}% ${deltaIndicator} |" >> $env:GITHUB_STEP_SUMMARY
330- shell : pwsh
331-
332- - name : Post Coverage Comment (Linux)
333- if : startsWith(matrix.os, 'ubuntu')
234+ - name : Post Coverage Comment
235+ if : always()
334236 uses : marocchino/sticky-pull-request-comment@v2
335237 with :
336- header : coverage-linux
337- message : |
338- ## Test Coverage Report (Linux)
339-
340- | Metric | Value |
341- |--------|-------|
342- | Current Coverage | ${{ steps.coverage-linux.outputs.pr_lines }}% |
343- | Base Branch Coverage | ${{ steps.coverage-linux.outputs.baseline_lines }}% |
344- | Delta | ${{ steps.coverage-linux.outputs.line_diff }}% ${{ steps.coverage-linux.outputs.delta_indicator }} |
345-
346- ---
347- ${{ steps.coverage-linux.outputs.line_diff > 0 && 'Coverage increased! Great work!' || (steps.coverage-linux.outputs.line_diff < 0 && 'Coverage decreased. Please add tests for new code.' || 'Coverage unchanged.') }}
348-
349- - name : Post Coverage Comment (Windows)
350- if : startsWith(matrix.os, 'windows')
351- uses : marocchino/sticky-pull-request-comment@v2
352- with :
353- header : coverage-windows
354- message : |
355- ## Test Coverage Report (Windows)
356-
357- | Metric | Value |
358- |--------|-------|
359- | Current Coverage | ${{ steps.coverage-windows.outputs.pr_lines }}% |
360- | Base Branch Coverage | ${{ steps.coverage-windows.outputs.baseline_lines }}% |
361- | Delta | ${{ steps.coverage-windows.outputs.line_diff }}% ${{ steps.coverage-windows.outputs.delta_indicator }} |
362-
363- ---
364- ${{ steps.coverage-windows.outputs.line_diff > 0 && 'Coverage increased! Great work!' || (steps.coverage-windows.outputs.line_diff < 0 && 'Coverage decreased. Please add tests for new code.' || 'Coverage unchanged.') }}
238+ header : ${{ matrix.comment_header }}
239+ path : coverage-report.md
0 commit comments