-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* chore: replace coverage job * feat: check coverage is above threshold
- Loading branch information
1 parent
d7d82e1
commit 4a6315f
Showing
4 changed files
with
128 additions
and
6 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
[run] | ||
omit = | ||
tests/* | ||
|
||
[report] | ||
exclude_lines = | ||
# Ignore pragma: no cover comments | ||
pragma: no cover |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,9 +20,12 @@ jobs: | |
coverage: | ||
timeout-minutes: 50 | ||
runs-on: ubuntu-latest | ||
|
||
if: github.event_name == 'pull_request' && github.event.pull_request.base.repo.full_name == github.event.pull_request.head.repo.full_name | ||
steps: | ||
- uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 0 # Fetch full history to enable proper diff | ||
|
||
- uses: actions/setup-python@v5 | ||
with: | ||
|
@@ -38,13 +41,22 @@ jobs: | |
|
||
- name: Pytest | ||
run: | | ||
pipenv run pytest --cov=taipy --cov-report="xml:overall-coverage.xml" tests | ||
python -m pip install xmltodict | ||
pipenv run pytest --cov=taipy --cov-report=xml:${{ github.workspace }}/coverage.xml --cov-config=.coveragerc | ||
- name: Coverage | ||
uses: orgoro/[email protected] | ||
with: | ||
coverageFile: overall-coverage.xml | ||
token: ${{ secrets.GITHUB_TOKEN }} | ||
- name: Fetch base branch | ||
run: | | ||
git fetch origin ${{ github.event.pull_request.base.ref }}:refs/remotes/origin/${{ github.event.pull_request.base.ref }} | ||
- name: Check total project coverage | ||
run: | | ||
python tools/coverage_check.py check-total --coverage-file ${{ github.workspace }}/coverage.xml --threshold 80 | ||
- name: Check pull request coverage | ||
run: | | ||
python tools/coverage_check.py check-changed --coverage-file ${{ github.workspace }}/coverage.xml --threshold 80 --base-branch ${{ github.event.pull_request.base.ref }} | ||
overall-tests: | ||
needs: [partial-tests] | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,6 +51,7 @@ exclude = [ | |
"build", | ||
"dist", | ||
"releases", | ||
"tools", | ||
".venv", | ||
".mypy_cache", | ||
".pytest_cache", | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
# Copyright 2021-2025 Avaiga Private Limited | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with | ||
# the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on | ||
# an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the | ||
# specific language governing permissions and limitations under the License. | ||
|
||
import argparse | ||
import xmltodict | ||
import sys | ||
import subprocess | ||
|
||
|
||
def check_total_coverage(coverage_file, threshold=80): | ||
"""Check the total project coverage.""" | ||
with open(coverage_file) as f: | ||
data = xmltodict.parse(f.read()) | ||
total_coverage = float(data['coverage']['@line-rate']) * 100 | ||
print(f"Total Coverage: {total_coverage:.2f}%") | ||
if total_coverage < threshold: | ||
print(f"Total project coverage is below {threshold}%: {total_coverage:.2f}%") | ||
sys.exit(1) | ||
|
||
|
||
def check_changed_files_coverage(coverage_file, changed_files, threshold=80): | ||
"""Check the coverage of changed files.""" | ||
with open(coverage_file) as f: | ||
data = xmltodict.parse(f.read()) | ||
|
||
# Handle multiple packages in the coverage report | ||
packages = data["coverage"]["packages"]["package"] | ||
if not isinstance(packages, list): | ||
packages = [packages] | ||
|
||
# Extract coverage data for all files | ||
files = {} | ||
for package in packages: | ||
classes = package["classes"]["class"] | ||
if not isinstance(classes, list): | ||
classes = [classes] | ||
for cls in classes: | ||
files[cls["@filename"]] = float(cls["@line-rate"]) * 100 | ||
qty = 0 | ||
sum_coverage = 0 | ||
for file in changed_files: | ||
if file in files: | ||
coverage = files[file] | ||
print(f"Coverage for {file}: {coverage:.2f}%") | ||
sum_coverage += coverage | ||
qty += 1 | ||
else: | ||
print(f"No coverage data found for {file}") | ||
|
||
if sum_coverage/qty < threshold: | ||
print(f"Coverage for changed files is below {threshold}%: {sum_coverage/qty:.2f}%") | ||
sys.exit(1) | ||
print(f"Coverage for changed files: {sum_coverage/qty:.2f}%") | ||
|
||
|
||
def get_changed_files(base_branch): | ||
"""Get the list of changed Python files in the pull request.""" | ||
try: | ||
result = subprocess.run( | ||
['git', 'diff', '--name-only', f"origin/{base_branch}", '--', '*.py'], | ||
capture_output=True, | ||
text=True, | ||
check=True, | ||
) | ||
changed_files = [ | ||
file.replace("taipy/", "") for file in result.stdout.strip().splitlines() if not file.startswith(('tests/', 'tools/')) | ||
] | ||
return changed_files | ||
except subprocess.CalledProcessError as e: | ||
print(f"Error fetching changed files: {e}") | ||
sys.exit(1) | ||
|
||
|
||
if __name__ == '__main__': | ||
parser = argparse.ArgumentParser(description="Coverage check script.") | ||
parser.add_argument('command', choices=['check-total', 'check-changed'], help="Command to execute") | ||
parser.add_argument('--coverage-file', default='coverage.xml', help="Path to the coverage XML file") | ||
parser.add_argument('--threshold', type=float, default=80, help="Coverage threshold percentage") | ||
parser.add_argument('--base-branch', help="Base branch for comparing changed files") | ||
|
||
args = parser.parse_args() | ||
|
||
if args.command == 'check-total': | ||
check_total_coverage(args.coverage_file, args.threshold) | ||
elif args.command == 'check-changed': | ||
if not args.base_branch: | ||
print("Error: --base-branch is required for check-changed") | ||
sys.exit(1) | ||
changed_files = get_changed_files(args.base_branch) | ||
if not changed_files: | ||
print("No relevant Python files changed.") | ||
sys.exit(0) | ||
check_changed_files_coverage(args.coverage_file, changed_files, args.threshold) |