Skip to content

Replace codecov for simpler GitHub Actions solution #1486

Replace codecov for simpler GitHub Actions solution

Replace codecov for simpler GitHub Actions solution #1486

Workflow file for this run

# Run tests and upload to Codecov with GitHub Actions
#
# NOTE: Pin actions to a specific commit to avoid having the authentication
# token stolen if the Action is compromised. See the comments and links here:
# https://github.com/pypa/gh-action-pypi-publish/issues/27
#
name: test
# Only build PRs, the main branch, and releases. Pushes to branches will only
# be built when a PR is opened. This avoids duplicated buids in PRs comming
# from branches in the origin repository (1 for PR and 1 for push).
on:
pull_request:
push:
branches:
- main
release:
types:
- published
permissions: {}
# Use bash by default in all jobs
defaults:
run:
shell: bash
jobs:
#############################################################################
# Run tests
tests:
name: ${{ matrix.os }} python=${{ matrix.python }} dependencies=${{ matrix.dependencies }}
runs-on: ${{ matrix.os }}
strategy:
# Otherwise, the workflow would stop if a single job fails. We want to
# run all of them to catch failures in different combinations.
fail-fast: false
matrix:
os:
- ubuntu-latest
- macos-latest
- windows-latest
dependencies:
- oldest
- latest
- optional
include:
- dependencies: oldest
python: "3.9"
- dependencies: latest
python: "3.12"
- dependencies: optional
python: "3.12"
# test on macos-13 (x86) using oldest dependencies and python 3.8
- os: macos-13
dependencies: oldest
python: "3.9"
exclude:
# don't test on macos-latest (arm64) with oldest dependencies
- os: macos-latest
dependencies: oldest
env:
REQUIREMENTS: env/requirements-build.txt env/requirements-tests.txt
steps:
# Checks-out your repository under $GITHUB_WORKSPACE
- name: Checkout
uses: actions/checkout@v4
with:
# Need to fetch more than the last commit so that setuptools-scm can
# create the correct version string. If the number of commits since
# the last release is greater than this, the version still be wrong.
# Increase if necessary.
fetch-depth: 100
# The GitHub token is preserved by default but this job doesn't need
# to be able to push to GitHub.
persist-credentials: false
# Need the tags so that setuptools-scm can form a valid version number
- name: Fetch git tags
run: git fetch origin 'refs/tags/*:refs/tags/*'
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
- name: Collect requirements
run: |
echo "Install Dependente to capture dependencies:"
python -m pip install dependente==0.3.0
echo ""
echo "Capturing run-time dependencies:"
if [[ "${{ matrix.dependencies }}" == "oldest" ]]; then
dependente --source install --oldest > requirements-full.txt
elif [[ "${{ matrix.dependencies }}" == "optional" ]]; then
dependente --source install,extras > requirements-full.txt
else
dependente --source install > requirements-full.txt
fi
echo "Capturing dependencies from:"
for requirement in $REQUIREMENTS
do
echo " $requirement"
cat $requirement >> requirements-full.txt
done
echo ""
echo "Collected dependencies:"
cat requirements-full.txt
- name: Get the pip cache folder
id: pip-cache
run: |
echo "dir="$(pip cache dir) >> $GITHUB_OUTPUT
- name: Setup caching for pip packages
uses: actions/cache@v4
with:
path: ${{ steps.pip-cache.outputs.dir }}
key: ${{ runner.os }}-pip-${{ hashFiles('requirements-full.txt') }}
- name: Install requirements
run: |
python -m pip install --requirement requirements-full.txt
- name: Build source and wheel distributions
run: |
make build
echo ""
echo "Generated files:"
ls -lh dist/
- name: Install the package
run: python -m pip install --no-deps dist/*.whl
- name: List installed packages
run: python -m pip freeze
- name: Run the tests
run: |
if [ $RUNNER_OS == "Linux" ]; then
# Set NUMBA_THREADING_LAYER to workqueue on Ubuntu to prevent
# endless loop on some test functions that make use of Numba
echo "Running 'NUMBA_THREADING_LAYER=workqueue make test'"
NUMBA_THREADING_LAYER=workqueue make test
else
echo "Running 'make test'"
make test
fi
- name: Rename the coverage artifact
run: |
mv .coverage .coverage.${{ matrix.os }}_${{ matrix.python }}_${{ matrix.dependencies }}
- name: Upload coverage data
uses: actions/upload-artifact@v4
with:
name: coverage_${{ matrix.os }}_${{ matrix.python }}_${{ matrix.dependencies }}
path: .coverage.*
include-hidden-files: true
if-no-files-found: ignore
#############################################################################
# Check coverage and upload a report
#
# Inspired by: https://hynek.me/articles/ditch-codecov-python/
coverage:
name: Combine & check coverage
if: always()
needs: tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# The GitHub token is preserved by default but this job doesn't need
# to be able to push to GitHub.
persist-credentials: false
- uses: actions/setup-python@v5
with:
# Use latest Python, so it understands all syntax.
python-version: "3.13"
- name: Get the pip cache folder
id: pip-cache
run: echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT
- name: Setup caching for pip packages
uses: actions/cache@v4
with:
path: ${{ steps.pip-cache.outputs.dir }}
key: ${{ runner.os }}-pip-coverage
- uses: actions/download-artifact@v4
with:
pattern: coverage_*
# If true, the downloaded artifacts will be in the same directory
# specified by path.
merge-multiple: true
- name: Install coverage.py
run: python -m pip install --upgrade coverage[toml]
- name: Combine coverage
run: python -m coverage combine
- name: Make an HTML report
run: python -m coverage html --skip-empty
- name: Report coverage on the job summary
run: python -m coverage report --format=markdown >> $GITHUB_STEP_SUMMARY
- name: Fail if coverage is not 100%
run: python -m coverage report --fail-under=100
- name: Upload HTML report if check failed
uses: actions/upload-artifact@v4
with:
name: html-report
path: htmlcov
if: ${{ failure() }}