Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# For more configuration details:
# https://docs.codecov.io/docs/codecov-yaml

# After making edits, check if this file is valid by running:
# curl -X POST --data-binary @.codecov.yml https://codecov.io/validate

#
# Coverage configuration
# ----------------------
#
github_checks:
#
# On adding coverage annotations to the code in the GitHub
# Code Review for now:
#
# - The annotations consume a lot of space in the PR code review,
# and can make it hard to review files that are not covered yet.
#
# - The coverage can be visited using the Codecov link at all times.
# https://app.codecov.io/gh/xapi-project/xen-api/pulls
#
# - The annotations can be hidden in GitHub PR code review by
# pressing the "a" key or by deselecting the "Show comments"
# checkbox but they are shown by default.
#
# - The Codecov Chrome and Firefox extension is a much nicer
# way to indicate coverage:
#
# Link: https://github.com/codecov/codecov-browser-extension
#
# - How to enable: You need to log in to Codecov using Github.
# For Firefox, enable the needed permissions:
# https://github.com/codecov/codecov-browser-extension/issues/50
#
# Reference:
# http://docs.codecov.com/docs/common-recipe-list#disable-github-check-run-annotations
#
annotations: true

#
# Pull request comments:
# ----------------------
# This feature adds the code coverage summary as a comment on each PR.
# See https://docs.codecov.io/docs/pull-request-comments
# This same information is available from the Codecov checks in the PR's
# "Checks" tab in GitHub even when this feature is disabled.
#
comment:
#
# Legend:
# "diff" is the Coverage Diff of the pull request.
# "files" are the files impacted by the pull request
# "flags" are the coverage status of the pull request
#
# For an even shorter layout, this may be used:
# layout: "condensed_header, diff, files, flags"
#
layout: "header, diff, files, flags"

#
# Only add the Codecov comment to the PR when coverage changes
#
require_changes: true

#
# The overall project coverage is secondary to the individual coverage
# and it is always shown in the repository at:
# - https://app.codecov.io/gh/xenserver/python-libs
#
hide_project_coverage: true

coverage:
#
# Number of precision digits when showing coverage percentage e.g. 88.8%.
# One precision digit is also used by coverage.py when reporting coverage:
#
precision: 1

status:

#
# Patch coverage is the incremental change in coverage in a PR
#
patch:
default: false # disable the default status that measures entire project

tests:
paths: ["tests/"] # only include coverage in "tests/" folder
target: auto # don't reduce coverage on test code lines

python-libs: # declare a new status context "python-libs"
paths: ["xcp/"] # library code
target: 0 # Temporarily allow 0% coverage to allow to merge dmv.py,
# Project threshold sets a lower bound to not go further.

#
# Project coverage is the absolute coverage of the entire project
#
project:
default: false # disable the default status that measures entire project

tests: # declare a new status context "tests"
paths: ["tests/"] # only include coverage in "tests/" folder
target: 99% # we always want 99% coverage here

python-libs: # declare a new status context "python-libs"
paths: ["xcp/"] # library code
target: 78% # Coverage should not be reduced compared to its base
105 changes: 31 additions & 74 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ jobs:
- python-version: '3.13'
os: ubuntu-22.04
runs-on: ${{ matrix.os }}
env:
COV_UPLOAD: ${{ '3.11' }}
steps:
- uses: actions/checkout@v4
with:
Expand All @@ -52,93 +54,48 @@ jobs:
if: ${{ github.actor == 'nektos/act'}}
run: apt-get update && apt-get install -y cpio

- name: Run of tox on ubuntu-latest
if: ${{ startsWith(matrix.python-version, '3.') && matrix.python-version != 3.6 }}
- name: Run tox to run pytest in the defined tox environments
run: |
pip install 'virtualenv<20.22' 'tox==4.5.1' tox-gh-actions
pip install tox-gh-actions
tox --workdir .github/workflows/.tox --recreate
env:
DIFF_COVERAGE_MIN: 0 # Let the reviewdog and codecov show uncovered lines

- name: Select the coverage file for upload
if: |
( matrix.python-version == '3.6' || matrix.python-version == '3.11' ) &&
( !cancelled() && github.actor != 'nektos/act' )
id: coverage
run: mv $( ls -t .github/workflows/.tox/*/log/.coverage | head -1 ) .coverage

# The new reliable Codecov upload requires Codecov to query the GitHub API to check
# the repo and the commit. The repo (or organisation) owner needs to login to
# codecov, generated the CODECOV_TOKEN and save it as a secret in the ORG or the repo:
# https://docs.codecov.com/docs/adding-the-codecov-token

# Links to get and set the token:
# Get the CODECOV_TOKEN: https://app.codecov.io/gh/xenserver/python-libs/settings
# Set the CODE_COV_TOKEN: https://github.com/xenserver/python-libs/settings/secrets/actions

# Without it, the API calls are rate-limited by GitHub, and the upload may fail:
# https://github.com/codecov/feedback/issues/126#issuecomment-1932658904
#
- name: Upload coverage reports to Codecov (fallback, legacy Node.js 16 action)
# If CODECOV_TOKEN is not set, use the legacy tokenless Codecov action:
- uses: aki77/reviewdog-action-code-coverage@v2
continue-on-error: true
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
# To reduce chances of GitHub's API throttling to hit this upload, only run the
# upload for the py38-covcombine-check job running on Ubuntu-20.04, which is the
# one we need. And only run it for PRs and the master branch, not for pushes.
# This reduces the number of uploads and the chance of hitting the rate limit
# by a factor of 6.
if: |
steps.coverage.outcome == 'success' &&
!env.CODECOV_TOKEN && !cancelled() &&
matrix.os == 'ubuntu-20.04' && github.actor != 'nektos/act' &&
( github.event.pull_request.number || github.ref == 'refs/heads/master' )
uses: codecov/codecov-action@v3
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.REVIEWDOG_GITHUB_API_TOKEN }}
if:
env.REVIEWDOG_GITHUB_API_TOKEN &&
matrix.python-version == env.COV_UPLOAD &&
github.actor != 'nektos/act'
with:
directory: .github/workflows/.tox/py38-covcombine-check/log
env_vars: OS,PYTHON
# Use fail_ci_if_error: false as explained the big comment above:
# Not failing this job in this case is ok because the tox CI checks also contain
# a diff-cover check which would fail on changed lines missing coverage.
# The Codecov CLI is more reliable and should be used if the CODECOV_TOKEN is set.
# The Codecov CLI is used in the next step when CODECOV_TOKEN is set.
fail_ci_if_error: false
flags: unittest
name: py27-py38-combined
verbose: true
lcov_path: coverage.lcov
github_token: ${{ secrets.REVIEWDOG_GITHUB_API_TOKEN }}

- name: Upload coverage reports to Codecov (used when secrets.CODECOV_TOKEN is set)
# If CODECOV_TOKEN is set, use the new Codecov CLI to upload the coverage reports
- name: Upload coverage reports to Codecov
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
id: codecov
if: |
env.CODECOV_TOKEN && !cancelled() && github.actor != 'nektos/act' &&
steps.coverage.outcome == 'success' && matrix.os == 'ubuntu-20.04'
run: >
set -euxv;
mv .github/workflows/.tox/py38-covcombine-check/log/coverage.xml cov.xml;
curl -O https://cli.codecov.io/latest/linux/codecov; sudo chmod +x codecov;
./codecov upload-process --report-type coverage
--name "CLI Upload for ${{ env.PYTHON_VERSION }}"
--git-service github --fail-on-error --file cov.xml --disable-search
--flag python${{ env.PYTHON_VERSION }}
continue-on-error: false # Fail the job if the upload with CODECOV_TOKEN fails
matrix.python-version == env.COV_UPLOAD
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}

- uses: codecov/test-results-action@v1
if: ${{ !cancelled() && steps.codecov.outcome == 'success' }}
with:
token: ${{ secrets.CODECOV_TOKEN }}

- if: steps.coverage.outcome == 'success'
- if: |
matrix.python-version == env.COV_UPLOAD &&
github.actor != 'nektos/act' &&
!cancelled()
name: Upload coverage reports to Coveralls
env:
COVERALLS_PARALLEL: true
COVERALLS_FLAG_NAME: ${{ format('python{0}', steps.python.outputs.python-version ) }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: pip install coveralls && coveralls --service=github

# For combined coverage of 2.7, 3.8 and 3.11 we upload to Coveralls in parallel mode.
# To view the Coveralls results from the PR, click on the "Details" link to the right
# of the Coveralls Logo in the Checks section of the PR.
finish-coverage-upload:
if: github.actor != 'nektos/act'
needs: test
runs-on: ubuntu-latest
steps:
- name: Finish the coverage upload to Coveralls
uses: coverallsapp/github-action@v1
with:
parallel-finished: true
continue-on-error: true # Coveralls.io is currently overloaded
62 changes: 62 additions & 0 deletions .github/workflows/reviewdog-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Reviewdog PR Review comments

#
# The reviewdog steps use reporter: github-pr-review, which submits the results
# as a review comment on the pull request. It needs a GitHub token with
# public_repo scope to post the comments and can only be used in the context
# of a pull request.
#
on: pull_request

#
# Checks can be skipped by adding "skip-checks: true" to a commit message,
# or requested by adding "request-checks: true" if disabled by default for pushes:
# https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/about-status-checks#skipping-and-requesting-checks-for-individual-commits
#

concurrency: # On new workflow, cancel old workflows from the same PR, branch or tag:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
reviewdog:
runs-on: ubuntu-24.04
env:
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.REVIEWDOG_GITHUB_API_TOKEN }}
GITHUB_ACTOR: ${{ github.actor }}
steps:
- uses: actions/checkout@v4
id: checkout
if: env.REVIEWDOG_GITHUB_API_TOKEN && env.GITHUB_ACTOR != 'nektos/act'

- uses: actions/setup-python@v5
if: env.REVIEWDOG_GITHUB_API_TOKEN && env.GITHUB_ACTOR != 'nektos/act'
with:
python-version: 3.13

- name: Install uv and activate the environment
if: env.REVIEWDOG_GITHUB_API_TOKEN && env.GITHUB_ACTOR != 'nektos/act'
uses: astral-sh/setup-uv@v6
with:
activate-environment: true

- run: uv pip install pylint types-setuptools -r pyproject.toml --extra mypy
if: env.REVIEWDOG_GITHUB_API_TOKEN && env.GITHUB_ACTOR != 'nektos/act'

- uses: tsuyoshicho/action-mypy@v4
name: Run mypy with reviewdog to submit GitHub checks for warnings
if: env.REVIEWDOG_GITHUB_API_TOKEN && env.GITHUB_ACTOR != 'nektos/act'
with:
install_types: false
mypy_flags: --exclude python-libs-*/stubs/
reporter: github-pr-review
level: warning
github_token: ${{ secrets.REVIEWDOG_GITHUB_API_TOKEN }}

- uses: dciborow/[email protected]
name: Run pylint with reviewdog to submit GitHub checks for warnings
if: env.REVIEWDOG_GITHUB_API_TOKEN && env.GITHUB_ACTOR != 'nektos/act'
with:
reporter: github-pr-review
glob_pattern: "xcp tests"
github_token: ${{ secrets.REVIEWDOG_GITHUB_API_TOKEN }}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Common XenServer/XCP-ng Python classes

[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit)
[![](https://img.shields.io/badge/python-2.7_%7C_3.6_%7C_3.7_%7C_3.8_%7C_3.9_%7C_3.10_%7C_3.11+-blue.svg)](https://www.python.org/downloads/)
[![](https://img.shields.io/badge/python-3.6_%7C_3.10_%7C_3.11_%7C_3.12_%7C_3.13-blue.svg)](https://www.python.org/downloads/)
[![codecov](https://codecov.io/gh/xenserver/python-libs/branch/master/graph/badge.svg?token=6WKVLDXJFN)](https://codecov.io/gh/xenserver/python-libs)
[![](https://img.shields.io/badge/License-BSD--2--Cause%20%26%20MIT-brightgreen)](https://github.com/xenserver/python-libs/blob/master/LICENSE)

Expand Down
4 changes: 4 additions & 0 deletions pytype_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ def skip_uninteresting_lines(line: str) -> bool:


def run_pytype(command: List[str], branch_url: str, errorlog: TextIO, results):
if os.environ.get("GITHUB_STEP_SUMMARY", None):
print("::group::pytype-output")
info(" ".join(shlex.quote(arg) for arg in command))
# When run in tox, pytype dumps debug messages to stderr. Point stderr to /dev/null:
popen = Popen(command, stdout=PIPE, stderr=PIPE, universal_newlines=True)
Expand Down Expand Up @@ -108,6 +110,8 @@ def run_pytype(command: List[str], branch_url: str, errorlog: TextIO, results):
if popen.stdout:
popen.stdout.close()
popen.wait()
if os.environ.get("GITHUB_STEP_SUMMARY", None):
print("::endgroup::")
return popen.returncode, results


Expand Down
18 changes: 12 additions & 6 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ commands =
# https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md
# https://github.com/actions/toolkit/blob/main/docs/commands.md#problem-matchers
echo "::add-matcher::.github/workflows/PYTHONWARNINGS-problemMatcher.json"
pytest --cov -v --new-first -x --show-capture=all -rA
sh -c 'if [ -n "{env:GITHUB_STEP_SUMMARY:-}" ];then echo "::group::pytest";fi'
pytest --cov -v --new-first -x --show-capture=all -rA --junitxml={envlogdir}/junit.xml -o junit_family=legacy
sh -c 'if [ -n "{env:GITHUB_STEP_SUMMARY:-}" ];then echo "::endgroup::";fi'
sh -c 'if [ -n "{env:PYTEST_MD_REPORT_OUTPUT}" -a -n "{env:GITHUB_STEP_SUMMARY}" ];then \
mkdir -p $(dirname "{env:GITHUB_STEP_SUMMARY:.git/sum.md}"); \
sed "s/tests\(.*py\)/[&](&)/" \
Expand Down Expand Up @@ -81,6 +83,9 @@ passenv =
pytype: GITHUB_REF_NAME
test: PYTEST_ADDOPTS
test: PYTEST_XDIST_WORKER_COUNT
cov: TESTS_COVERAGE_MIN
cov: XCP_COVERAGE_MIN
cov: DIFF_COVERAGE_MIN
covcp: UPLOAD_DIR
covcp: HOME
check: MYPY_FORCE_COLOR
Expand Down Expand Up @@ -114,7 +119,7 @@ commands =
# covcombine shall not call [cov]commands: diff-cover shall check the combined cov:
{cov,covcp}: {[cov]commands}
{py27-test}: pylint --py3k --disable=no-absolute-import xcp/
covcp: cp -av {envlogdir}/coverage.xml {env:UPLOAD_DIR:.}
covcp: cp -av {envlogdir}/coverage.xml {envlogdir}/coverage.lcov {envlogdir}/junit.xml {env:UPLOAD_DIR:.}
covcombine: {[covcombine]commands}
fox: {[covcombine]commands}
fox: {[lint]commands}
Expand All @@ -127,12 +132,13 @@ setenv = PY3_DIFFCOVER_OPTIONS=--ignore-whitespace --show-uncovered
extras = coverage
test
commands =
coverage xml -o {envlogdir}/coverage.xml --fail-under {env:XCP_COV_MIN:68}
coverage xml -o {envlogdir}/coverage.xml --fail-under {env:XCP_COVERAGE_MIN:78}
coverage lcov -o {envlogdir}/coverage.lcov
coverage html -d {envlogdir}/htmlcov
coverage html -d {envlogdir}/htmlcov-tests --fail-under {env:TESTS_COV_MIN:96} \
coverage html -d {envlogdir}/htmlcov-tests --fail-under {env:TESTS_COVERAGE_MIN:96} \
--include="tests/*"
diff-cover --compare-branch=origin/master \
{env:PY3_DIFFCOVER_OPTIONS} --fail-under {env:DIFF_COV_MIN:92} \
diff-cover --compare-branch=origin/master --exclude xcp/dmv.py \
{env:PY3_DIFFCOVER_OPTIONS} --fail-under {env:DIFF_COVERAGE_MIN:92} \
--html-report {envlogdir}/coverage-diff.html \
{envlogdir}/coverage.xml

Expand Down
Loading
Loading