Code Coverage with codecov #1363
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Code Coverage with codecov | |
on: | |
pull_request: | |
branches: | |
- main | |
paths: | |
- '.github/workflows/codecov.yml' | |
- 'include/**' | |
- 'lib/**' | |
- 'subsys/**' | |
- 'tests/**' | |
- '**/Kconfig*' | |
- 'west.yml' | |
schedule: | |
# Run at 14:37 UTC every day | |
- cron: '37 14 * * *' | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.head_ref || github.ref }} | |
cancel-in-progress: true | |
jobs: | |
twister: | |
runs-on: self-hosted | |
container: | |
image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.27.4.20241026 | |
options: '--entrypoint /bin/bash' | |
volumes: | |
- /repo-cache/embeint:/github/cache/embeint | |
- /repo-cache/ccache:/github/ccache | |
strategy: | |
fail-fast: false | |
matrix: | |
platform: ["mps2/an385", "native_sim", "unit_testing"] | |
include: | |
- platform: 'mps2/an385' | |
normalized: 'mps2_an385' | |
- platform: 'native_sim' | |
normalized: 'native_sim' | |
- platform: 'unit_testing' | |
normalized: 'unit_testing' | |
env: | |
CCACHE_DIR: /github/ccache | |
# `--specs` is ignored because ccache is unable to resolve the toolchain specs file path. | |
CCACHE_IGNOREOPTIONS: '-specs=* --specs=*' | |
BASE_REF: ${{ github.base_ref }} | |
ZEPHYR_TOOLCHAIN_VARIANT: zephyr | |
steps: | |
- name: Apply container owner mismatch workaround | |
run: | | |
# FIXME: The owner UID of the GITHUB_WORKSPACE directory may not | |
# match the container user UID because of the way GitHub | |
# Actions runner is implemented. Remove this workaround when | |
# GitHub comes up with a fundamental fix for this problem. | |
git config --global --add safe.directory ${GITHUB_WORKSPACE} | |
- name: Workspace cleanup | |
run: | | |
rm -rf ./{*,.*} | |
rm -rf infuse-sdk twister-out* | |
- name: Clone cached Embeint SDK repository | |
continue-on-error: true | |
run: | | |
git config --global --add safe.directory '*' | |
git clone --shared /github/cache/embeint/infuse-sdk infuse-sdk | |
cd infuse-sdk | |
git remote set-url origin ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{ github.event.pull_request.head.sha }} | |
path: infuse-sdk | |
fetch-depth: 0 | |
persist-credentials: false | |
- name: Environment Setup | |
working-directory: infuse-sdk | |
run: | | |
if [ "${{github.event_name}}" = "pull_request" ]; then | |
git config --global user.email "[email protected]" | |
git config --global user.name "Embeint CI" | |
rm -fr ".git/rebase-apply" | |
git rebase origin/${BASE_REF} | |
git log --pretty=oneline | head -n 10 | |
fi | |
west init -l . || true | |
west config --global update.narrow true | |
west update --path-cache /github/cache/embeint 2>&1 1> west.update.log || west update --path-cache /github/cache/embeint 2>&1 1> west.update.log || ( rm -rf ../modules ../bootloader ../tools && west update --path-cache /github/cache/embeint) | |
west forall -c 'git reset --hard HEAD' | |
echo "ZEPHYR_SDK_INSTALL_DIR=/opt/toolchains/zephyr-sdk-$( cat SDK_VERSION )" >> $GITHUB_ENV | |
- name: Check Environment | |
run: | | |
cmake --version | |
gcc --version | |
ls -la /opt/toolchains | |
ls -la | |
echo "github.ref: ${{ github.ref }}" | |
echo "github.base_ref: ${{ github.base_ref }}" | |
echo "github.ref_name: ${{ github.ref_name }}" | |
- name: Set up ccache | |
run: | | |
mkdir -p ${CCACHE_DIR} | |
ccache -M 10G | |
ccache -p | |
ccache -z -s -vv | |
- name: Run Tests with Coverage Information | |
continue-on-error: true | |
run: | | |
mkdir -p coverage/reports | |
pip install gcovr==6.0 | |
export ZEPHYR_BASE=${PWD}/zephyr | |
$ZEPHYR_BASE/scripts/twister -i --force-color -N -v --filter runnable -p ${{ matrix.platform }} --coverage -T infuse-sdk/tests --coverage-tool gcovr -xCONFIG_TEST_EXTRA_STACK_SIZE=4096 -e nano --coverage-basedir infuse-sdk | |
- name: Print ccache stats | |
if: always() | |
run: | | |
ccache -s -vv | |
- name: Rename coverage files | |
if: always() | |
run: | | |
mv twister-out/coverage.json coverage/reports/${{ matrix.normalized }}.json | |
- name: Upload Coverage Results | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: Coverage Data (Subset ${{ matrix.normalized }}) | |
path: coverage/reports/${{ matrix.normalized }}.json | |
retention-days: 1 | |
babblesim: | |
runs-on: self-hosted | |
container: | |
image: ghcr.io/zephyrproject-rtos/ci-repo-cache:v0.27.4.20241026 | |
options: '--entrypoint /bin/bash' | |
volumes: | |
- /repo-cache/embeint:/github/cache/embeint | |
- /repo-cache/ccache:/github/ccache | |
env: | |
CCACHE_DIR: /github/ccache | |
# `--specs` is ignored because ccache is unable to resolve the toolchain specs file path. | |
CCACHE_IGNOREOPTIONS: '-specs=* --specs=*' | |
BASE_REF: ${{ github.base_ref }} | |
ZEPHYR_TOOLCHAIN_VARIANT: zephyr | |
BSIM_OUT_PATH: /github/cache/embeint/tools/bsim | |
BSIM_COMPONENTS_PATH: /github/cache/embeint/tools/bsim/components/ | |
steps: | |
- name: Workspace cleanup | |
run: | | |
rm -rf ./{*,.*} | |
rm -rf infuse-sdk | |
- name: Clone cached Embeint SDK repository | |
continue-on-error: true | |
run: | | |
git config --global --add safe.directory '*' | |
git clone --shared /github/cache/embeint/infuse-sdk infuse-sdk | |
cd infuse-sdk | |
git remote set-url origin ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY} | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{ github.event.pull_request.head.sha }} | |
path: infuse-sdk | |
fetch-depth: 0 | |
persist-credentials: false | |
- name: Environment Setup | |
working-directory: infuse-sdk | |
run: | | |
if [ "${{github.event_name}}" = "pull_request" ]; then | |
git config --global user.email "[email protected]" | |
git config --global user.name "Embeint CI" | |
rm -fr ".git/rebase-apply" | |
git rebase origin/${BASE_REF} | |
git log --pretty=oneline | head -n 10 | |
fi | |
west init -l . || true | |
west config --global update.narrow true | |
west config manifest.group-filter -- +babblesim | |
west update --path-cache /github/cache/embeint 2>&1 1> west.update.log || west update --path-cache /github/cache/embeint 2>&1 1> west.update.log || ( rm -rf ../modules ../bootloader ../tools && west update --path-cache /github/cache/embeint) | |
west forall -c 'git reset --hard HEAD' | |
pip install gcovr==6.0 | |
echo "ZEPHYR_SDK_INSTALL_DIR=/opt/toolchains/zephyr-sdk-$( cat SDK_VERSION )" >> $GITHUB_ENV | |
- name: BabbleSim build | |
run: | | |
cd ${BSIM_OUT_PATH} | |
make everything -j 8 | |
- name: Check Environment | |
run: | | |
cmake --version | |
gcc --version | |
ls -la /opt/toolchains | |
ls -la | |
echo "github.ref: ${{ github.ref }}" | |
echo "github.base_ref: ${{ github.base_ref }}" | |
echo "github.ref_name: ${{ github.ref_name }}" | |
- name: Set up ccache | |
run: | | |
mkdir -p ${CCACHE_DIR} | |
ccache -M 10G | |
ccache -p | |
ccache -z -s -vv | |
- name: Run tests with BabbleSim | |
run: | | |
export ZEPHYR_BASE=${PWD}/zephyr | |
export INFUSE_BASE=${PWD}/infuse-sdk | |
export WORK_DIR=${PWD}/bsim_out | |
rm -rf $WORK_DIR | |
$INFUSE_BASE/tests/bsim/ci.bt.sh | |
$INFUSE_BASE/tests/bsim/ci.802154.sh | |
$INFUSE_BASE/tests/bsim/ci.serial.sh | |
- name: Print ccache stats | |
if: always() | |
run: | | |
ccache -s -vv | |
- name: Generate coverage report | |
run: | | |
export INFUSE_BASE=${PWD}/infuse-sdk | |
export WORK_DIR=${PWD}/bsim_out | |
mkdir -p coverage/reports | |
gcovr -r $INFUSE_BASE \ | |
--gcov-ignore-parse-errors=negative_hits.warn_once_per_file \ | |
--gcov-executable gcov -e tests/* -e .*generated.* -e .*/tests/.* -e .*/samples/.* \ | |
--exclude-branches-by-pattern "(^\s*LOG_(?:HEXDUMP_)?(?:DBG|INF|WRN|ERR)\(.*)|(^\s*__ASSERT(?:_EVAL|_NO_MSG|_POST_ACTION)?\(.*)" \ | |
--merge-mode-functions=separate --json \ | |
-o coverage/reports/nrf52_bsim.json \ | |
$WORK_DIR | |
- name: Upload Coverage Results | |
uses: actions/upload-artifact@v4 | |
with: | |
name: Coverage Data (BabbleSim) | |
path: coverage/reports/nrf52_bsim.json | |
if-no-files-found: ignore | |
retention-days: 1 | |
codecov-results: | |
name: "Publish Coverage Results" | |
needs: | |
- twister | |
- babblesim | |
runs-on: ubuntu-22.04 | |
# the codecov job might be skipped, we don't need to run this job then | |
if: success() || failure() | |
steps: | |
- name: checkout | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Download Artifacts | |
uses: actions/download-artifact@v4 | |
with: | |
path: coverage/reports | |
- name: Move coverage files | |
run: | | |
mv ./coverage/reports/*/*.json ./coverage/reports | |
ls -la ./coverage/reports | |
- name: Generate list of coverage files | |
id: get-coverage-files | |
shell: cmake -P {0} | |
run: | | |
file(GLOB INPUT_FILES_LIST "coverage/reports/*.json") | |
set(MERGELIST "") | |
set(FILELIST "") | |
foreach(ITEM ${INPUT_FILES_LIST}) | |
get_filename_component(f ${ITEM} NAME) | |
if(FILELIST STREQUAL "") | |
set(FILELIST "${f}") | |
else() | |
set(FILELIST "${FILELIST},${f}") | |
endif() | |
endforeach() | |
foreach(ITEM ${INPUT_FILES_LIST}) | |
get_filename_component(f ${ITEM} NAME) | |
if(MERGELIST STREQUAL "") | |
set(MERGELIST "--add-tracefile ${f}") | |
else() | |
set(MERGELIST "${MERGELIST} -a ${f}") | |
endif() | |
endforeach() | |
file(APPEND $ENV{GITHUB_OUTPUT} "mergefiles=${MERGELIST}\n") | |
file(APPEND $ENV{GITHUB_OUTPUT} "covfiles=${FILELIST}\n") | |
- name: Merge coverage files | |
run: | | |
cd ./coverage/reports | |
pip install gcovr==6.0 | |
gcovr ${{ steps.get-coverage-files.outputs.mergefiles }} --merge-mode-functions=separate --json merged.json | |
gcovr ${{ steps.get-coverage-files.outputs.mergefiles }} --merge-mode-functions=separate --cobertura merged.xml | |
ls -la . | |
- name: Upload Merged Coverage Results and Report | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: Coverage Data and report | |
path: | | |
coverage/reports/merged.json | |
coverage/reports/merged.xml | |
retention-days: 2 | |
- name: Upload coverage to Codecov | |
if: always() | |
uses: codecov/codecov-action@v5 | |
with: | |
token: ${{ secrets.CODECOV_TOKEN }} | |
files: ./coverage/reports/merged.xml | |
env_vars: OS,PYTHON | |
fail_ci_if_error: false | |
verbose: true |