Skip to content

Commit 45ef85a

Browse files
committed
Updated the workflowfor coverage check to use pytst -xdist to run the tests parallely
1 parent b5b6cfb commit 45ef85a

File tree

3 files changed

+137
-417
lines changed

3 files changed

+137
-417
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
name: Code Coverage
2+
3+
permissions:
4+
contents: read
5+
6+
on: [pull_request, workflow_dispatch]
7+
8+
jobs:
9+
test-with-coverage:
10+
runs-on: ubuntu-latest
11+
environment: azure-prod
12+
env:
13+
DATABRICKS_SERVER_HOSTNAME: ${{ secrets.DATABRICKS_HOST }}
14+
DATABRICKS_HTTP_PATH: ${{ secrets.TEST_PECO_WAREHOUSE_HTTP_PATH }}
15+
DATABRICKS_TOKEN: ${{ secrets.DATABRICKS_TOKEN }}
16+
DATABRICKS_CATALOG: peco
17+
DATABRICKS_USER: ${{ secrets.TEST_PECO_SP_ID }}
18+
steps:
19+
#----------------------------------------------
20+
# check-out repo and set-up python
21+
#----------------------------------------------
22+
- name: Check out repository
23+
uses: actions/checkout@v4
24+
with:
25+
fetch-depth: 0
26+
ref: ${{ github.event.pull_request.head.ref || github.ref_name }}
27+
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
28+
- name: Set up python
29+
id: setup-python
30+
uses: actions/setup-python@v5
31+
with:
32+
python-version: "3.10"
33+
#----------------------------------------------
34+
# ----- install & configure poetry -----
35+
#----------------------------------------------
36+
- name: Install Poetry
37+
uses: snok/install-poetry@v1
38+
with:
39+
virtualenvs-create: true
40+
virtualenvs-in-project: true
41+
installer-parallel: true
42+
43+
#----------------------------------------------
44+
# load cached venv if cache exists
45+
#----------------------------------------------
46+
- name: Load cached venv
47+
id: cached-poetry-dependencies
48+
uses: actions/cache@v4
49+
with:
50+
path: .venv
51+
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ github.event.repository.name }}-${{ hashFiles('**/poetry.lock') }}
52+
#----------------------------------------------
53+
# install dependencies if cache does not exist
54+
#----------------------------------------------
55+
- name: Install dependencies
56+
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
57+
run: poetry install --no-interaction --no-root
58+
#----------------------------------------------
59+
# install your root project, if required
60+
#----------------------------------------------
61+
- name: Install library
62+
run: poetry install --no-interaction --all-extras
63+
#----------------------------------------------
64+
# run all tests in parallel with xdist
65+
#----------------------------------------------
66+
- name: Run all tests with coverage using pytest-xdist
67+
continue-on-error: true
68+
run: |
69+
poetry run pytest tests/unit tests/e2e \
70+
-n auto \
71+
--cov=src \
72+
--cov-report=xml \
73+
--cov-report=term \
74+
-v
75+
76+
#----------------------------------------------
77+
# check for coverage override
78+
#----------------------------------------------
79+
- name: Check for coverage override
80+
id: override
81+
run: |
82+
OVERRIDE_COMMENT=$(echo "${{ github.event.pull_request.body }}" | grep -E "SKIP_COVERAGE_CHECK\s*=" || echo "")
83+
if [ -n "$OVERRIDE_COMMENT" ]; then
84+
echo "override=true" >> $GITHUB_OUTPUT
85+
REASON=$(echo "$OVERRIDE_COMMENT" | sed -E 's/.*SKIP_COVERAGE_CHECK\s*=\s*(.+)/\1/')
86+
echo "reason=$REASON" >> $GITHUB_OUTPUT
87+
echo "Coverage override found in PR description: $REASON"
88+
else
89+
echo "override=false" >> $GITHUB_OUTPUT
90+
echo "No coverage override found"
91+
fi
92+
#----------------------------------------------
93+
# check coverage percentage
94+
#----------------------------------------------
95+
- name: Check coverage percentage
96+
if: steps.override.outputs.override == 'false'
97+
run: |
98+
COVERAGE_FILE="coverage.xml"
99+
if [ ! -f "$COVERAGE_FILE" ]; then
100+
echo "ERROR: Coverage file not found at $COVERAGE_FILE"
101+
exit 1
102+
fi
103+
104+
# Install xmllint if not available
105+
if ! command -v xmllint &> /dev/null; then
106+
sudo apt-get update && sudo apt-get install -y libxml2-utils
107+
fi
108+
109+
COVERED=$(xmllint --xpath "string(//coverage/@lines-covered)" "$COVERAGE_FILE")
110+
TOTAL=$(xmllint --xpath "string(//coverage/@lines-valid)" "$COVERAGE_FILE")
111+
PERCENTAGE=$(python3 -c "covered=${COVERED}; total=${TOTAL}; print(round((covered/total)*100, 2))")
112+
113+
echo "Branch Coverage: $PERCENTAGE%"
114+
echo "Required Coverage: 85%"
115+
116+
# Use Python to compare the coverage with 85
117+
python3 -c "import sys; sys.exit(0 if float('$PERCENTAGE') >= 85 else 1)"
118+
if [ $? -eq 1 ]; then
119+
echo "ERROR: Coverage is $PERCENTAGE%, which is less than the required 85%"
120+
exit 1
121+
else
122+
echo "SUCCESS: Coverage is $PERCENTAGE%, which meets the required 85%"
123+
fi
124+
125+
#----------------------------------------------
126+
# coverage enforcement summary
127+
#----------------------------------------------
128+
- name: Coverage enforcement summary
129+
run: |
130+
if [ "${{ steps.override.outputs.override }}" == "true" ]; then
131+
echo "⚠️ Coverage checks bypassed: ${{ steps.override.outputs.reason }}"
132+
echo "Please ensure this override is justified and temporary"
133+
else
134+
echo "✅ Coverage checks enforced - minimum 85% required"
135+
fi
136+

0 commit comments

Comments
 (0)