Skip to content

Commit ec2f12c

Browse files
sdarwinwchilders-nvidia
authored andcommitted
Add codecov reporting []
1 parent d1838fb commit ec2f12c

2 files changed

Lines changed: 214 additions & 5 deletions

File tree

‎.github/codecov.yml‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Part of the EDG Compiler Project, under the Apache License v2.0 with LLVM
2+
# Exceptions.
3+
# See https://edgcpp.org/LICENSE.txt for license information.
4+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
#
6+
# Codecov configuration (https://docs.codecov.com/docs/codecov-yaml).
7+
# The coverage job of .github/workflows/build-and-test-ci.yml merges the
8+
# reports of all test legs and uploads them as a single report, so no
9+
# upload count needs to be configured here.
10+
11+
codecov:
12+
# Wait for CI to pass before posting coverage results: a failed test leg
13+
# can leave the report incomplete, which would look like a regression.
14+
require_ci_to_pass: true
15+
16+
coverage:
17+
precision: 2
18+
round: down
19+
range: "20...80"
20+
status:
21+
# Report, but never fail, the project and patch checks.
22+
project:
23+
default:
24+
informational: true
25+
patch:
26+
default:
27+
informational: true
28+
29+
comment:
30+
layout: "header, diff, files, footer"
31+
behavior: default
32+
require_changes: false
33+
34+
# Only src/ is reported (see the gcovr --filter in build-and-test-ci.yml);
35+
# keep the rest of the tree out of Codecov's view even if a report includes
36+
# it.
37+
ignore:
38+
- "benchmarks/**"
39+
- "dev_tools/**"
40+
- "tests/**"
41+
- "util/**"

‎.github/workflows/build-and-test-ci.yml‎

Lines changed: 173 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
#
1414
# prepare ───────────────┬──► test-gcc ──┐
1515
# build-gcc ─────────────┘ ├──► publish (on failure)
16-
# prepare ───────────────┬──► test-i686 ──┘
17-
# build-i686 ────────────┘
16+
# prepare ───────────────┬──► test-i686 ──┤
17+
# build-i686 ────────────┘ └──► coverage
1818
# bench (pull requests only; independent)
1919
#
2020
# A shared run timestamp keeps results under the same tests/runs/<timestamp>/
@@ -23,6 +23,13 @@
2323
# `edg-docker-bench --posture=release` does and uploads them as bench-results
2424
# (c/ and cpp/ runs, for comparison against the checked-in
2525
# benchmarks/baselines/project/release-{c,cpp}).
26+
#
27+
# The debug builds are instrumented for gcov (EDG_CPFE_USE_GCOV) and ship
28+
# their .gcno files with the build products. Each test leg turns the .gcda
29+
# files its run produces into a gcovr JSON report for src/; the coverage job
30+
# merges the reports of all test legs and uploads one report to Codecov
31+
# (see .github/codecov.yml). The coverage steps never fail the run; only
32+
# edgy's results do.
2633

2734
name: Build & Test CI
2835

@@ -40,6 +47,9 @@ concurrency:
4047
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
4148
cancel-in-progress: true
4249

50+
env:
51+
GCOVR_VERSION: '8.7'
52+
4353
jobs:
4454
prepare:
4555
name: Prepare run timestamp
@@ -71,7 +81,7 @@ jobs:
7181
- name: Configure linux-gcc-debug
7282
env:
7383
EDG_BASE: ${{ github.workspace }}/bases/docker/dev-env/gcc
74-
run: cmake --preset linux-gcc-debug
84+
run: cmake --preset linux-gcc-debug -DEDG_CPFE_USE_GCOV=ON
7585

7686
- name: Build linux-gcc-debug
7787
env:
@@ -80,7 +90,8 @@ jobs:
8090

8191
# Runtime layout only: environment.sh / eccp need bin/, lib/, and the
8292
# per-target lib_linux_* / lib_win* dirs (eccp rewrites ECCP_LIBDIR to
83-
# lib_<target>). lib_src is build-only and omitted.
93+
# lib_<target>). lib_src is build-only and omitted. The .gcno files
94+
# let the test legs produce coverage reports.
8495
- name: Upload build products
8596
uses: actions/upload-artifact@v7
8697
with:
@@ -91,6 +102,7 @@ jobs:
91102
build/gcc/lib_linux_*
92103
build/gcc/lib_win*
93104
build/gcc/environment.sh
105+
build/gcc/src/**/*.gcno
94106
if-no-files-found: error
95107
retention-days: 1
96108
compression-level: 6
@@ -112,7 +124,7 @@ jobs:
112124
- name: Configure linux-i686-gcc-debug
113125
env:
114126
EDG_BASE: ${{ github.workspace }}/bases/docker/dev-env/gcc-i686
115-
run: cmake --preset linux-i686-gcc-debug
127+
run: cmake --preset linux-i686-gcc-debug -DEDG_CPFE_USE_GCOV=ON
116128

117129
- name: Build linux-i686-gcc-debug
118130
env:
@@ -129,6 +141,7 @@ jobs:
129141
build/gcc-i686/lib_linux_*
130142
build/gcc-i686/lib_win*
131143
build/gcc-i686/environment.sh
144+
build/gcc-i686/src/**/*.gcno
132145
if-no-files-found: error
133146
retention-days: 1
134147
compression-level: 6
@@ -201,6 +214,51 @@ jobs:
201214
if-no-files-found: warn
202215
retention-days: 1
203216

217+
# Coverage: the instrumented cpfe / cpfe-cp wrote .gcda files next to
218+
# the downloaded .gcno files under build/gcc/src. Each leg saves a gcovr
219+
# JSON report; the coverage job merges them and uploads to Codecov.
220+
# Coverage problems must never fail the test leg, hence
221+
# continue-on-error.
222+
- name: Install gcovr
223+
if: ${{ !cancelled() }}
224+
continue-on-error: true
225+
run: |
226+
python3 -m venv "${RUNNER_TEMP}/gcovr"
227+
"${RUNNER_TEMP}/gcovr/bin/pip" install --quiet \
228+
"gcovr==${GCOVR_VERSION}"
229+
230+
# cpfe and cpfe-cp compile the same sources; separate function merging
231+
# keeps gcovr from rejecting functions seen at different lines. A few
232+
# hot loops exceed gcovr's "suspicious hits" threshold; warn about them
233+
# instead of failing.
234+
- name: Generate coverage report
235+
if: ${{ !cancelled() }}
236+
continue-on-error: true
237+
env:
238+
CONFIG: ${{ matrix.config }}
239+
run: |
240+
mkdir -p coverage
241+
"${RUNNER_TEMP}/gcovr/bin/gcovr" \
242+
--root . \
243+
--filter 'src/' \
244+
--merge-mode-functions=separate \
245+
--gcov-ignore-parse-errors=negative_hits.warn_once_per_file \
246+
--gcov-ignore-parse-errors=suspicious_hits.warn_once_per_file \
247+
-j "$(nproc)" \
248+
--json "coverage/${CONFIG}.json" \
249+
--print-summary \
250+
build/gcc
251+
252+
- name: Upload coverage report
253+
if: ${{ !cancelled() && hashFiles('coverage/*.json') != '' }}
254+
continue-on-error: true
255+
uses: actions/upload-artifact@v7
256+
with:
257+
name: coverage-${{ matrix.config }}
258+
path: coverage/${{ matrix.config }}.json
259+
if-no-files-found: warn
260+
retention-days: 1
261+
204262
test-i686:
205263
name: Test ${{ matrix.config }}
206264
needs:
@@ -269,6 +327,51 @@ jobs:
269327
if-no-files-found: warn
270328
retention-days: 1
271329

330+
# Coverage: the instrumented cpfe / cpfe-cp wrote .gcda files next to
331+
# the downloaded .gcno files under build/gcc-i686/src. Each leg saves a gcovr
332+
# JSON report; the coverage job merges them and uploads to Codecov.
333+
# Coverage problems must never fail the test leg, hence
334+
# continue-on-error.
335+
- name: Install gcovr
336+
if: ${{ !cancelled() }}
337+
continue-on-error: true
338+
run: |
339+
python3 -m venv "${RUNNER_TEMP}/gcovr"
340+
"${RUNNER_TEMP}/gcovr/bin/pip" install --quiet \
341+
"gcovr==${GCOVR_VERSION}"
342+
343+
# cpfe and cpfe-cp compile the same sources; separate function merging
344+
# keeps gcovr from rejecting functions seen at different lines. A few
345+
# hot loops exceed gcovr's "suspicious hits" threshold; warn about them
346+
# instead of failing.
347+
- name: Generate coverage report
348+
if: ${{ !cancelled() }}
349+
continue-on-error: true
350+
env:
351+
CONFIG: ${{ matrix.config }}
352+
run: |
353+
mkdir -p coverage
354+
"${RUNNER_TEMP}/gcovr/bin/gcovr" \
355+
--root . \
356+
--filter 'src/' \
357+
--merge-mode-functions=separate \
358+
--gcov-ignore-parse-errors=negative_hits.warn_once_per_file \
359+
--gcov-ignore-parse-errors=suspicious_hits.warn_once_per_file \
360+
-j "$(nproc)" \
361+
--json "coverage/${CONFIG}.json" \
362+
--print-summary \
363+
build/gcc-i686
364+
365+
- name: Upload coverage report
366+
if: ${{ !cancelled() && hashFiles('coverage/*.json') != '' }}
367+
continue-on-error: true
368+
uses: actions/upload-artifact@v7
369+
with:
370+
name: coverage-${{ matrix.config }}
371+
path: coverage/${{ matrix.config }}.json
372+
if-no-files-found: warn
373+
retention-days: 1
374+
272375
publish-test-results:
273376
name: Publish aggregated test results
274377
needs:
@@ -318,6 +421,71 @@ jobs:
318421
if-no-files-found: warn
319422
retention-days: 14
320423

424+
coverage:
425+
name: Publish coverage to Codecov
426+
needs:
427+
- test-gcc
428+
- test-i686
429+
# Like publish-test-results, merge whatever the test legs produced,
430+
# whether or not their tests passed. The number of configs is not
431+
# fixed: every coverage-* artifact is merged into one report and
432+
# uploaded once.
433+
if: ${{ !cancelled() }}
434+
runs-on: ubuntu-latest
435+
timeout-minutes: 30
436+
steps:
437+
- name: Check out repository
438+
uses: actions/checkout@v7
439+
440+
- name: Download per-config coverage reports
441+
continue-on-error: true
442+
uses: actions/download-artifact@v7
443+
with:
444+
pattern: coverage-*
445+
path: coverage
446+
merge-multiple: true
447+
448+
- name: Install gcovr
449+
continue-on-error: true
450+
run: |
451+
python3 -m venv "${RUNNER_TEMP}/gcovr"
452+
"${RUNNER_TEMP}/gcovr/bin/pip" install --quiet \
453+
"gcovr==${GCOVR_VERSION}"
454+
455+
- name: Merge coverage reports
456+
if: ${{ hashFiles('coverage/*.json') != '' }}
457+
continue-on-error: true
458+
run: |
459+
ls -l coverage
460+
"${RUNNER_TEMP}/gcovr/bin/gcovr" \
461+
--root . \
462+
--merge-mode-functions=separate \
463+
--json-add-tracefile 'coverage/*.json' \
464+
--cobertura coverage.xml \
465+
--print-summary
466+
467+
# Pull requests from forks have no access to secrets; the Codecov
468+
# action then falls back to a tokenless upload, which Codecov accepts
469+
# for public repositories.
470+
#
471+
# The report is complete as generated by gcovr, so skip the CLI's own
472+
# gcov run (plugins: noop) and its "file fixes" pass, which opens every
473+
# file git tracks and crashes on the dangling symlinks used as test
474+
# inputs (e.g. tests/.../embed___has_embed/embed___has_embed.c).
475+
- name: Upload coverage to Codecov
476+
if: ${{ hashFiles('coverage.xml') != '' }}
477+
continue-on-error: true
478+
uses: codecov/codecov-action@v7
479+
with:
480+
token: ${{ secrets.CODECOV_TOKEN }}
481+
files: coverage.xml
482+
disable_search: true
483+
disable_file_fixes: true
484+
network_filter: src/
485+
plugins: noop
486+
fail_ci_if_error: true
487+
verbose: true
488+
321489
bench:
322490
name: Benchmark linux-gcc-release
323491
if: ${{ github.event_name == 'pull_request' }}

0 commit comments

Comments
 (0)