1+ name : Code Coverage
2+
3+ permissions :
4+ contents : read
5+
6+ on :
7+ pull_request :
8+
9+ jobs :
10+ coverage :
11+ runs-on : ubuntu-latest
12+ steps :
13+ # ----------------------------------------------
14+ # check-out repo and set-up python
15+ # ----------------------------------------------
16+ - name : Check out repository
17+ uses : actions/checkout@v4
18+ with :
19+ fetch-depth : 0 # Needed for coverage comparison
20+ ref : ${{ github.event.pull_request.head.ref || github.ref_name }}
21+ repository : ${{ github.event.pull_request.head.repo.full_name || github.repository }}
22+ - name : Set up python
23+ id : setup-python
24+ uses : actions/setup-python@v5
25+ with :
26+ python-version : " 3.10"
27+ # ----------------------------------------------
28+ # ----- install & configure poetry -----
29+ # ----------------------------------------------
30+ - name : Install Poetry
31+ uses : snok/install-poetry@v1
32+ with :
33+ virtualenvs-create : true
34+ virtualenvs-in-project : true
35+ installer-parallel : true
36+
37+ # ----------------------------------------------
38+ # load cached venv if cache exists
39+ # ----------------------------------------------
40+ - name : Load cached venv
41+ id : cached-poetry-dependencies
42+ uses : actions/cache@v4
43+ with :
44+ path : .venv
45+ key : venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ github.event.repository.name }}-${{ hashFiles('**/poetry.lock') }}
46+ # ----------------------------------------------
47+ # install dependencies if cache does not exist
48+ # ----------------------------------------------
49+ - name : Install dependencies
50+ if : steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
51+ run : poetry install --no-interaction --no-root
52+ # ----------------------------------------------
53+ # install your root project, if required
54+ # ----------------------------------------------
55+ - name : Install library
56+ run : poetry install --no-interaction
57+ # ----------------------------------------------
58+ # install additional dependencies for e2e tests
59+ # ----------------------------------------------
60+ - name : Install e2e test dependencies
61+ run : poetry run pip install pyarrow
62+ # ----------------------------------------------
63+ # run test suite
64+ # ----------------------------------------------
65+ - name : Run tests with coverage
66+ continue-on-error : true
67+ run : poetry run python -m pytest tests/unit tests/e2e --cov=src --cov-report=xml --cov-report=term
68+ # ----------------------------------------------
69+ # check for coverage override
70+ # ----------------------------------------------
71+ - name : Check for coverage override
72+ id : override
73+ run : |
74+ OVERRIDE_COMMENT=$(echo "${{ github.event.pull_request.body }}" | grep -E "SKIP_COVERAGE_CHECK\s*=" || echo "")
75+ if [ -n "$OVERRIDE_COMMENT" ]; then
76+ echo "override=true" >> $GITHUB_OUTPUT
77+ REASON=$(echo "$OVERRIDE_COMMENT" | sed -E 's/.*SKIP_COVERAGE_CHECK\s*=\s*(.+)/\1/')
78+ echo "reason=$REASON" >> $GITHUB_OUTPUT
79+ echo "Coverage override found in PR description: $REASON"
80+ else
81+ echo "override=false" >> $GITHUB_OUTPUT
82+ echo "No coverage override found"
83+ fi
84+ # ----------------------------------------------
85+ # check coverage percentage
86+ # ----------------------------------------------
87+ - name : Report coverage percentage
88+ run : |
89+ COVERAGE_FILE="coverage.xml"
90+ if [ ! -f "$COVERAGE_FILE" ]; then
91+ echo "ERROR: Coverage file not found at $COVERAGE_FILE"
92+ exit 1
93+ fi
94+
95+ # Install xmllint if not available
96+ if ! command -v xmllint &> /dev/null; then
97+ sudo apt-get update && sudo apt-get install -y libxml2-utils
98+ fi
99+
100+ COVERED=$(xmllint --xpath "string(//coverage/@lines-covered)" "$COVERAGE_FILE")
101+ TOTAL=$(xmllint --xpath "string(//coverage/@lines-valid)" "$COVERAGE_FILE")
102+
103+ # Calculate percentage using Python for precision
104+ PERCENTAGE=$(python3 -c "covered=${COVERED}; total=${TOTAL}; print(round((covered/total)*100, 2))")
105+
106+ echo "📊 Branch Coverage: ${PERCENTAGE}%"
107+ # ----------------------------------------------
108+ # coverage enforcement summary
109+ # ----------------------------------------------
110+ - name : Coverage summary
111+ run : |
112+ echo "Coverage calculation complete. No minimum enforced."
0 commit comments