Skip to content

Commit c3d0c79

Browse files
committed
1 parent cc5a629 commit c3d0c79

File tree

4 files changed

+136
-1
lines changed

4 files changed

+136
-1
lines changed

.github/workflows/tests.yaml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,69 @@ jobs:
5151
run: git config --global protocol.file.allow always
5252
- name: Run tests with tox
5353
run: uvx --with tox-uv tox -e ${{ matrix.python-config.tox-env }}
54+
55+
# Upload coverage data from this matrix job
56+
- name: Upload coverage data
57+
uses: actions/upload-artifact@v4
58+
with:
59+
name: coverage-data-${{ matrix.os }}-${{ matrix.python-config.tox-env }}
60+
path: .coverage.*
61+
include-hidden-files: true
62+
if-no-files-found: ignore
63+
64+
# Combine coverage from all matrix jobs and report
65+
coverage:
66+
name: Combine & check coverage
67+
needs: test
68+
runs-on: ubuntu-latest
69+
70+
steps:
71+
- uses: actions/checkout@v5
72+
73+
- name: Install uv
74+
uses: astral-sh/setup-uv@v7
75+
76+
- name: Set up Python
77+
run: uv python install 3.12
78+
79+
- name: Install coverage
80+
run: uv pip install --system coverage[toml]
81+
82+
# Download all coverage artifacts from matrix jobs
83+
- name: Download coverage data
84+
uses: actions/download-artifact@v4
85+
with:
86+
pattern: coverage-data-*
87+
merge-multiple: true
88+
89+
# Combine all .coverage.* files into one .coverage database
90+
- name: Combine coverage data
91+
run: |
92+
python -Im coverage combine
93+
python -Im coverage html
94+
python -Im coverage json
95+
96+
# Export total coverage percentage for badge
97+
export TOTAL=$(python -c "import json;print(json.load(open('coverage.json'))['totals']['percent_covered_display'])")
98+
echo "total=$TOTAL" >> $GITHUB_ENV
99+
echo "### Total coverage: ${TOTAL}%" >> $GITHUB_STEP_SUMMARY
100+
101+
# Generate markdown report and add to GitHub summary
102+
- name: Generate coverage report
103+
run: |
104+
echo "## Coverage Report" >> $GITHUB_STEP_SUMMARY
105+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
106+
python -Im coverage report --format=markdown >> $GITHUB_STEP_SUMMARY
107+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
108+
109+
# Upload HTML coverage report as artifact for debugging
110+
- name: Upload HTML coverage report
111+
uses: actions/upload-artifact@v4
112+
with:
113+
name: html-coverage-report
114+
path: htmlcov/
115+
116+
# Fail if coverage is below threshold
117+
- name: Fail if coverage is below threshold
118+
run: |
119+
python -Im coverage report --fail-under=75

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
*.egg-info
22
.*-cache
33
.coverage
4+
.coverage.*
5+
!.coveragerc
6+
coverage.json
7+
coverage.xml
8+
htmlcov/
49
.installed.txt
510
.mxmake/
611
.python-version
12+
.pytest_cache/
713
.tox
814
__pycache__
915
build/

include.mk

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
##############################################################################
2+
# Custom Makefile targets
3+
# This file is included by the mxmake-generated Makefile and will be preserved
4+
# during mxmake updates.
5+
##############################################################################
6+
7+
##############################################################################
8+
# Coverage targets
9+
##############################################################################
10+
11+
.PHONY: coverage
12+
coverage: $(PACKAGES_TARGET)
13+
@echo "Run tests with coverage"
14+
@coverage run -m pytest
15+
@coverage combine
16+
@coverage report --show-missing
17+
18+
.PHONY: coverage-html
19+
coverage-html: $(PACKAGES_TARGET)
20+
@echo "Run tests with coverage and generate HTML report"
21+
@coverage run -m pytest
22+
@coverage combine
23+
@coverage html
24+
@echo "Opening coverage report..."
25+
@which xdg-open > /dev/null && xdg-open htmlcov/index.html || \
26+
which open > /dev/null && open htmlcov/index.html || \
27+
echo "Open htmlcov/index.html in your browser"

pyproject.toml

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ test = [
3030
"pytest-cov",
3131
"pytest-mock",
3232
"httpretty",
33+
"coverage[toml]",
3334
]
3435

3536
[project.urls]
@@ -133,6 +134,41 @@ max-line-length = 120
133134
# max-line-length = 88
134135
ignore = "D001"
135136

137+
[tool.coverage.run]
138+
source = ["src"]
139+
branch = true
140+
parallel = true
141+
relative_files = true
142+
omit = [
143+
"*/tests/*",
144+
"*/_version.py",
145+
"*/vcs/__init__.py",
146+
]
147+
148+
[tool.coverage.paths]
149+
source = [
150+
"src",
151+
".tox/*/lib/python*/site-packages",
152+
".tox/*/Lib/site-packages",
153+
]
154+
155+
[tool.coverage.report]
156+
exclude_lines = [
157+
"pragma: no cover",
158+
"def __repr__",
159+
"if __name__ == .__main__.:",
160+
"raise AssertionError",
161+
"raise NotImplementedError",
162+
"if TYPE_CHECKING:",
163+
"@abstractmethod",
164+
]
165+
precision = 2
166+
show_missing = true
167+
skip_covered = false
168+
169+
[tool.coverage.html]
170+
directory = "htmlcov"
171+
136172
[tool.tox]
137173
requires = ["tox>=4", "tox-uv>=1"]
138174
env_list = ["lint", "py38", "py39", "py310", "py311", "py312", "py313", "py314"]
@@ -144,7 +180,7 @@ uv_resolution = "highest"
144180
pass_env = ["LC_ALL", "LANG", "HOME"]
145181
commands = [
146182
["uv", "pip", "install", "-e", ".[test]"],
147-
["pytest", "--cov", "--cov-report=term", "--cov-branch", "{posargs:tests}"]
183+
["coverage", "run", "-m", "pytest", "{posargs:tests}"]
148184
]
149185

150186
[tool.tox.env.lint]

0 commit comments

Comments
 (0)