Repository navigation
140 lines (128 loc) · 6.79 KB
/
Copy pathcode-coverage.yml
File metadata and controls
140 lines (128 loc) · 6.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# Measure the code coverage of QLever's unit tests using LLVMs source
# instrumentation. When this workflow runs for the master branch, the
# coverage report is directly uploaded to Codecov.io. When this workflow
# runs for a pull request, the coverage report is stored as a GitHub artifact
# and a separate workflow from `upload-coverage.yml` is triggered that uploads
# the coverage report. That way the uploader has access to the Codecov token
# in all cases and the upload should never fail.
# The following name has to be the same as in the `workflows:` key in
# `upload-coverage.yml`, otherwise the uploader won't pick up the result
# of this workflow.
name: measure-code-coverage
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
# Also run when a label is applied, so that applying the `run-ci` or
# `run-full-ci` label triggers the checks. There is no need for `opened`,
# see `README.md`.
types: [ synchronize, reopened, labeled ]
merge_group:
concurrency:
group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}'
cancel-in-progress: true
# The default GITHUB_TOKEN only needs to read the repository here.
permissions:
contents: read
jobs:
build:
# Only run for PRs with the `run-ci` or `run-full-ci` label, see `README.md`.
if: >-
github.event_name != 'pull_request' ||
contains(github.event.pull_request.labels.*.name, 'run-ci') ||
contains(github.event.pull_request.labels.*.name, 'run-full-ci')
env:
compiler: clang
# The compiler and the LLVM coverage tools have to use the same major
# version, so this is the single place where it is specified.
compiler-version: 21
build-type: Debug
warnings: "-Wall -Wextra "
# we disable the `assert()` macro as it messes with the coverage reports
asan-flags: "-DNDEBUG"
ubsan-flags: ""
coverage-flags: "-fprofile-instr-generate -fcoverage-mapping"
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v7
with:
submodules: "recursive"
- name: Install dependencies
uses: ./.github/workflows/install-dependencies-ubuntu
- name: Install compiler
uses: ./.github/workflows/install-compiler-ubuntu
with:
compiler: ${{env.compiler}}
compiler-version: ${{env.compiler-version}}
- name: Install coverage tools
run: |
sudo apt install -y llvm-${{env.compiler-version}}
sudo apt install mold
- name: Show path
run: |
which llvm-profdata-${{env.compiler-version}}
which llvm-cov-${{env.compiler-version}}
- name: Create build directory
run: mkdir ${{github.workspace}}/build
- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
# Precompiled headers have to be disabled to make coverage deterministic.
run: cmake -B ${{github.workspace}}/build -DCMAKE_TOOLCHAIN_FILE="$(pwd)/toolchains/${{env.compiler}}${{env.compiler-version}}.cmake" -DUSE_PRECOMPILED_HEADERS=OFF -DCMAKE_BUILD_TYPE=${{env.build-type}} -DLOGLEVEL=TIMING -DBRANCHLESS_LOGGING=ON -DCOVERAGE_FRIENDLY_CHECKS=ON -DADDITIONAL_COMPILER_FLAGS="${{env.warnings}} ${{env.asan-flags}} ${{env.ubsan-flags}} ${{env.coverage-flags}}" -DADDITIONAL_LINKER_FLAGS="${{env.coverage-flags}}" -DRUN_EXPENSIVE_TESTS=false -DSINGLE_TEST_BINARY=ON -DENABLE_EXPENSIVE_CHECKS=true -DADDITIONAL_LINKER_FLAGS="-fuse-ld=mold"
- name: Build
# Build your program with the given configuration
run: cmake --build ${{github.workspace}}/build --config ${{env.build-type}} -- -j $(nproc)
- name: Run unit tests
working-directory: ${{github.workspace}}/build/test
env:
LLVM_PROFILE_FILE: "default%p.profraw"
# We have to manually run the test executable to only get a single `.profraw` file.
# Otherwise, the GitHub runner goes out of memory.
run: env ASAN_OPTIONS="alloc_dealloc_mismatch=0" ./QLeverAllUnitTestsMain
- name: Process coverage info
working-directory: ${{github.workspace}}/build/test
# Only measure QLever's own sources. Everything else (the dependencies
# below `_deps`, the tests, the benchmarks) already lies outside of `src`;
# the generated parsers don't, hence the explicit exclusion.
run: |
# `llvm-cov` only warns about a nonexistent source filter, and then reports everything.
test -d "${{github.workspace}}/src"
llvm-profdata-${{env.compiler-version}} merge -sparse *.profraw -o default.profdata
llvm-cov-${{env.compiler-version}} export ./QLeverAllUnitTestsMain --format=lcov --instr-profile ./default.profdata --ignore-filename-regex="/generated/" "${{github.workspace}}/src" > ./coverage.lcov
# Only upload the coverage directly if this is not a pull request. In this
# case we are on the master branch and have access to the Codecov token.
- name: "Submit coverage data to codecov.io"
if: github.event_name != 'pull_request'
uses: codecov/codecov-action@v7
with:
files: ${{github.workspace}}/build/test/coverage.lcov
# Fail if the file above is missing, instead of silently searching for
# other coverage reports.
disable_search: true
# Note: technically, a `token` is not required for codecov.io when
# uploading from a public repository, but specifying it avoids the
# nasty spurious failures due to GitHub's rate limit for codecov's
# public default token.
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
# For a pull request we store the coverage file as well as some information
# about this PR (number, how to check it out, etc.) and upload it as an artifact.
# This is all the data that is required for running the Codecov uploader manually
# from `upload-coverage.yml`.
- name: Save PR number and coverage file in same directory
if: github.event_name == 'pull_request'
# Note: If you change any of the filenames here, you also have to change them in `upload-coverage.yml`
run : |
mkdir -p coverage-report
echo ${{ github.event.number }} > ./coverage-report/pr
echo ${{ github.repository }} > ./coverage-report/github_repository
echo ${GITHUB_REF} > ./coverage-report/github_ref
mv ${{ github.workspace}}/build/test/coverage.lcov coverage-report
- name: Upload coverage artifact
if: github.event_name == 'pull_request'
uses: actions/upload-artifact@v7
with:
name: coverage-report
path: coverage-report/
# Note: for now we do not run the e2e tests for the coverage check