Skip to content

Commit 13daf58

Browse files
committed
add coverage workflow
1 parent 8793eb7 commit 13daf58

2 files changed

Lines changed: 350 additions & 0 deletions

File tree

.codecov.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Copyright 2019 - 2021 Alexander Grund
2+
# Distributed under the Boost Software License, Version 1.0.
3+
# (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt)
4+
5+
codecov:
6+
max_report_age: off
7+
require_ci_to_pass: yes
8+
notify:
9+
# Increase this if you have multiple coverage collection jobs
10+
after_n_builds: 1
11+
wait_for_ci: yes
12+
13+
# Fix paths from CI build to match repository structure.
14+
# The lcov report records absolute paths such as
15+
# /home/runner/.../boost-root/libs/burl/include/...
16+
fixes:
17+
- "boost-root/libs/burl/::"
18+
19+
# Make coverage checks informational (report but never fail CI)
20+
coverage:
21+
status:
22+
project:
23+
default:
24+
informational: true
25+
patch:
26+
default:
27+
informational: true
28+
29+
# Change how pull request comments look
30+
comment:
31+
layout: "reach,diff,flags,files,footer"
32+
33+
# Ignore specific files or folders. Glob patterns are supported.
34+
# See https://docs.codecov.com/docs/ignoring-paths
35+
ignore:
36+
- example/*
37+
- example/**/*
38+
- test/*
39+
- test/**/*
Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
#
2+
# Copyright (c) 2026 Sam Darwin
3+
# Copyright (c) 2026 Alexander Grund
4+
#
5+
# Distributed under the Boost Software License, Version 1.0. (See accompanying
6+
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7+
#
8+
# Official repository: https://github.com/cppalliance/burl/
9+
#
10+
11+
# Instructions
12+
#
13+
# After running this workflow successfully, go to https://github.com/cppalliance/burl/settings/pages
14+
# and enable github pages on the code-coverage branch.
15+
# The coverage will be hosted at https://cppalliance.github.io/burl
16+
#
17+
18+
name: Code Coverage
19+
20+
on:
21+
push:
22+
branches:
23+
- master
24+
- develop
25+
paths:
26+
- 'src/**'
27+
- 'include/**'
28+
- 'test/**'
29+
- '.github/workflows/code-coverage.yml'
30+
workflow_dispatch:
31+
32+
concurrency:
33+
group: code-coverage-pages
34+
cancel-in-progress: false
35+
36+
env:
37+
GIT_FETCH_JOBS: 8
38+
NET_RETRY_COUNT: 5
39+
GCOVR_COMMIT_MSG: "Update coverage data"
40+
41+
jobs:
42+
build-linux:
43+
defaults:
44+
run:
45+
shell: bash
46+
name: Coverage (Linux)
47+
runs-on: ubuntu-24.04
48+
timeout-minutes: 120
49+
50+
steps:
51+
- name: Clone Boost.Burl
52+
uses: actions/checkout@v6
53+
with:
54+
path: burl-root
55+
56+
- name: Setup C++
57+
uses: alandefreitas/cpp-actions/setup-cpp@v1.9.4
58+
id: setup-cpp
59+
with:
60+
compiler: gcc
61+
version: 13
62+
check-latest: true
63+
64+
- name: Install packages
65+
uses: alandefreitas/cpp-actions/package-install@v1.9.4
66+
with:
67+
apt-get: >-
68+
build-essential libssl-dev zlib1g-dev libbrotli-dev
69+
lcov
70+
71+
- name: Clone Boost
72+
uses: alandefreitas/cpp-actions/boost-clone@v1.9.4
73+
id: boost-clone
74+
with:
75+
branch: ${{ (github.ref_name == 'master' && github.ref_name) || 'develop' }}
76+
boost-dir: boost-source
77+
scan-modules-dir: burl-root
78+
patches: >
79+
https://github.com/cppalliance/capy
80+
https://github.com/cppalliance/corosio
81+
https://github.com/cppalliance/http
82+
83+
- name: ASLR Fix
84+
run: sysctl vm.mmap_rnd_bits=28
85+
86+
- name: Patch Boost
87+
id: patch
88+
run: |
89+
set -xe
90+
91+
# Identify boost module being tested
92+
module=${GITHUB_REPOSITORY#*/}
93+
echo "module=$module" >> $GITHUB_OUTPUT
94+
95+
# Identify GitHub workspace root
96+
workspace_root=$(echo "$GITHUB_WORKSPACE" | sed 's/\\/\//g')
97+
echo -E "workspace_root=$workspace_root" >> $GITHUB_OUTPUT
98+
99+
# Remove module from boost-source
100+
rm -r "boost-source/libs/$module" || true
101+
102+
# Copy cached boost-source to an isolated boost-root
103+
cp -r boost-source boost-root
104+
105+
# Set boost-root output
106+
cd boost-root
107+
boost_root="$(pwd)"
108+
boost_root=$(echo "$boost_root" | sed 's/\\/\//g')
109+
echo -E "boost_root=$boost_root" >> $GITHUB_OUTPUT
110+
cd ..
111+
112+
# Patch boost-root with workspace module
113+
cp -r "$workspace_root"/burl-root "boost-root/libs/$module"
114+
115+
- name: Build with coverage
116+
uses: alandefreitas/cpp-actions/cmake-workflow@v1.9.4
117+
with:
118+
source-dir: boost-root
119+
build-dir: __build_cmake_test__
120+
build-type: Debug
121+
build-target: tests
122+
run-tests: true
123+
install-prefix: .local
124+
cxxstd: '20'
125+
cc: ${{ steps.setup-cpp.outputs.cc || 'gcc-13' }}
126+
cxx: ${{ steps.setup-cpp.outputs.cxx || 'g++-13' }}
127+
cxxflags: '--coverage -fprofile-arcs -ftest-coverage'
128+
ccflags: '--coverage -fprofile-arcs -ftest-coverage'
129+
shared: false
130+
cmake-version: '>=3.20'
131+
extra-args: |
132+
-D Boost_VERBOSE=ON
133+
-D BOOST_INCLUDE_LIBRARIES="${{ steps.patch.outputs.module }}"
134+
-D CMAKE_EXPORT_COMPILE_COMMANDS=ON
135+
package: false
136+
package-artifact: false
137+
ref-source-dir: boost-root/libs/burl
138+
139+
- name: Install Python
140+
uses: actions/setup-python@v6
141+
with:
142+
python-version: '3.13'
143+
144+
- name: Install Python packages
145+
run: pip install gcovr
146+
147+
- name: Checkout ci-automation
148+
uses: actions/checkout@v6
149+
with:
150+
repository: cppalliance/ci-automation
151+
path: ci-automation
152+
153+
- name: Generate gcovr report
154+
run: |
155+
set -xe
156+
module=$(basename ${GITHUB_REPOSITORY})
157+
gcov_tool="gcov-${{ steps.setup-cpp.outputs.version-major }}"
158+
command -v "$gcov_tool" >/dev/null 2>&1 || gcov_tool="gcov"
159+
mkdir -p gcovr
160+
161+
# First pass: collect raw coverage data into JSON
162+
gcovr \
163+
--root boost-root \
164+
--gcov-executable "$gcov_tool" \
165+
--merge-mode-functions separate \
166+
--sort uncovered-percent \
167+
--html-title "${module}" \
168+
--merge-lines \
169+
--exclude-unreachable-branches \
170+
--exclude-throw-branches \
171+
--exclude '.*/example/.*' \
172+
--exclude '.*/examples/.*' \
173+
--filter ".*/${module}/.*" \
174+
--html --output gcovr/index.html \
175+
--json-summary-pretty --json-summary gcovr/summary.json \
176+
--json gcovr/coverage-raw.json \
177+
boost-root/__build_cmake_test__
178+
179+
# Fix paths for repo-relative display
180+
python3 ci-automation/scripts/fix_paths.py \
181+
gcovr/coverage-raw.json \
182+
gcovr/coverage-fixed.json \
183+
--repo "${module}"
184+
185+
# Create symlinks so gcovr can find source files at repo-relative paths
186+
ln -sfn "boost-root/libs/${module}/include" include 2>/dev/null || true
187+
ln -sfn "boost-root/libs/${module}/src" src 2>/dev/null || true
188+
189+
# Second pass: generate nested HTML from fixed JSON with custom templates
190+
gcovr \
191+
-a gcovr/coverage-fixed.json \
192+
--merge-mode-functions separate \
193+
--sort uncovered-percent \
194+
--html-nested \
195+
--html-template-dir=ci-automation/gcovr-templates/html \
196+
--html-title "${module}" \
197+
--merge-lines \
198+
--exclude-unreachable-branches \
199+
--exclude-throw-branches \
200+
--exclude '(^|.*/)test/.*' \
201+
--exclude '.*/example/.*' \
202+
--exclude '.*/examples/.*' \
203+
--html --output gcovr/index.html \
204+
--json-summary-pretty --json-summary gcovr/summary.json
205+
206+
- name: Generate sidebar navigation
207+
run: python3 ci-automation/scripts/gcovr_build_tree.py gcovr
208+
209+
- name: Generate badges
210+
run: python3 ci-automation/scripts/generate_badges.py gcovr --json gcovr/summary.json
211+
212+
- name: Upload coverage artifact
213+
uses: actions/upload-artifact@v4
214+
with:
215+
name: coverage-linux
216+
path: gcovr/
217+
218+
deploy:
219+
needs: [build-linux]
220+
if: ${{ !cancelled() }}
221+
defaults:
222+
run:
223+
shell: bash
224+
name: Deploy Coverage
225+
runs-on: ubuntu-24.04
226+
timeout-minutes: 30
227+
228+
steps:
229+
- name: Checkout code
230+
uses: actions/checkout@v6
231+
232+
- name: Check for code-coverage Branch
233+
run: |
234+
set -xe
235+
git config --global user.name cppalliance-bot
236+
git config --global user.email cppalliance-bot@example.com
237+
git fetch origin
238+
if git branch -r | grep origin/code-coverage; then
239+
echo "The code-coverage branch exists. Continuing."
240+
else
241+
echo "The code-coverage branch does not exist. Creating it."
242+
git switch --orphan code-coverage
243+
git commit --allow-empty -m "$GCOVR_COMMIT_MSG"
244+
git push origin code-coverage
245+
git checkout $GITHUB_REF_NAME
246+
fi
247+
248+
- name: Checkout GitHub pages branch
249+
uses: actions/checkout@v6
250+
with:
251+
ref: code-coverage
252+
path: gh_pages_dir
253+
254+
- name: Download coverage artifacts
255+
uses: actions/download-artifact@v4
256+
with:
257+
pattern: coverage-*
258+
path: coverage-artifacts/
259+
260+
- name: Copy coverage results
261+
run: |
262+
set -xe
263+
touch gh_pages_dir/.nojekyll
264+
265+
mkdir -p "gh_pages_dir/develop"
266+
mkdir -p "gh_pages_dir/master"
267+
268+
# Remove old single-directory layout (migration from gcovr/ to gcovr-linux/)
269+
rm -rf "gh_pages_dir/${GITHUB_REF_NAME}/gcovr"
270+
271+
# Copy each platform's results (only if artifact exists)
272+
for platform in linux; do
273+
if [ -d "coverage-artifacts/coverage-${platform}" ]; then
274+
rm -rf "gh_pages_dir/${GITHUB_REF_NAME}/gcovr-${platform}"
275+
cp -rp "coverage-artifacts/coverage-${platform}" \
276+
"gh_pages_dir/${GITHUB_REF_NAME}/gcovr-${platform}"
277+
fi
278+
done
279+
280+
# Generate branch index pages
281+
for branch in develop master; do
282+
cat > "gh_pages_dir/${branch}/index.html" << 'HTMLEOF'
283+
<html>
284+
<head><title>Code Coverage</title></head>
285+
<body>
286+
<h2>Code Coverage Reports</h2>
287+
<ul>
288+
<li><a href="gcovr-linux/index.html">Linux (GCC)</a></li>
289+
</ul>
290+
</body>
291+
</html>
292+
HTMLEOF
293+
done
294+
295+
# Root index
296+
cat > gh_pages_dir/index.html << 'HTMLEOF'
297+
<html>
298+
<head></head>
299+
<body>
300+
<a href="develop/index.html">develop</a><br>
301+
<a href="master/index.html">master</a><br>
302+
</body>
303+
</html>
304+
HTMLEOF
305+
306+
cd gh_pages_dir
307+
git config --global user.name cppalliance-bot
308+
git config --global user.email cppalliance-bot@example.com
309+
git add .
310+
git commit --amend -m "$GCOVR_COMMIT_MSG"
311+
git push -f origin code-coverage

0 commit comments

Comments
 (0)