Skip to content
Merged
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
99 changes: 89 additions & 10 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,99 @@ on:
# run daily, this refreshes the cache
- cron: '13 2 * * *'

concurrency: # On new push, 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:
python-test:
name: Python tests
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
docker-image: # See https://hub.docker.com/_/python/tags for images
- python:2.7.18-alpine3.11
- python:3.11.4-alpine3.18
container: ${{ matrix.docker-image }}
python-version: ['2.7', '3.11']
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0 # To check which files changed: origin/master..HEAD
- uses: LizardByte/setup-python-action@master
with:
python-version: ${{matrix.python-version}}

- uses: actions/cache@v3
name: Setup cache for running pre-commit fast
with:
path: ~/.cache/pre-commit
key: pre-commit|${{ env.pythonLocation }}|${{ hashFiles('.pre-commit-config.yaml') }}

- name: Install python 2 dependencies
if: ${{ startsWith(matrix.docker-image, 'python:2.7.18') }}
- run: echo "::add-matcher::.github/workflows/python-warning-matcher.json"
name: "Setup GitHub for reporting Python warnings as annotations in pull request code review"

- uses: pre-commit/action@v3.0.0
name: Run pre-commit checks (no spaces at end of lines, etc)
if: ${{ matrix.python-version != '2.7' }}
with:
extra_args: --all-files --verbose --hook-stage commit
env:
SKIP: no-commit-to-branch

- name: Install dependencies only needed for python 2
if: ${{ matrix.python-version == '2.7' }}
run: pip install enum

- name: Install dependencies
run: pip install mock pytest
- name: Install dependencies only needed for python 3
if: ${{ matrix.python-version != '2.7' }}
run: pip install pandas pytype toml

- name: Run python tests
run: pytest scripts
- name: Install common dependencies for Python ${{matrix.python-version}}
run: pip install mock pytest-coverage pytest-mock

- name: Run Pytest tests for Python ${{matrix.python-version}}
run: >
pytest --cov scripts scripts/ -vv -rA
--junitxml=.git/pytest${{matrix.python-version}}.xml
--cov-report term-missing
--cov-report xml:.git/coverage${{matrix.python-version}}.xml
env:
PYTHONDEVMODE: yes

- name: Upload Python ${{matrix.python-version}} coverage report to Codecov
uses: codecov/codecov-action@v3
with:
directory: .git
files: coverage${{matrix.python-version}}.xml
env_vars: OS,PYTHON
fail_ci_if_error: false
flags: python${{matrix.python-version}}
name: coverage${{matrix.python-version}}
verbose: true

- uses: dciborow/action-pylint@0.1.0
if: ${{ matrix.python-version != '2.7' }}
with:
reporter: github-pr-review
level: warning
# To be customized to cover remaining Python scripts:
glob_pattern: "**/*.py"

- name: Run pytype checks
if: ${{ matrix.python-version != '2.7' }}
run: ./pytype_reporter.py
env:
PR_NUMBER: ${{ github.event.number }}

# Try to add pytype_report.py's summary file as a comment to the PR:
# Documentation: https://github.com/marketplace/actions/add-pr-comment
- name: Add the pytype summary as a comment to the PR (if permitted)
uses: mshick/add-pr-comment@v2
# Depends on pytype checks, which are not run for python 2.7:
if: ${{ matrix.python-version != '2.7' }}
# Fails for user workflows without permissions(fork-based pull requests):
continue-on-error: true
with:
message-path: .git/pytype-summary.md # Add the content of it as comment

ocaml-test:
name: Ocaml tests
Expand Down Expand Up @@ -115,3 +184,13 @@ jobs:

- name: quality-gate
run: make quality-gate

- uses: reviewdog/action-actionlint@v1
name: GitHub Action linter from https://github.com/reviewdog/action-actionlint

- name: pyflakes
uses: reviewdog/action-pyflakes@master
with:
github_token: ${{ secrets.github_token }}
reporter: github-pr-review
level: error
17 changes: 17 additions & 0 deletions .github/workflows/python-warning-matcher.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"problemMatcher": [
{
"owner": "python-warnings",
"severity": "warning",
"pattern": [
{
"regexp": "^.*/xen-api/(.+):([0-9]*):(.*):(.*)$",
"file": 1,
"line": 2,
"code": 3,
"message": 4
}
]
}
]
}
55 changes: 55 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#
# Configuration of pre-commit, a Python framework for git hooks.
# pre-commit is run for each git push by GitHub CI. It can run
# locally as well for early feedback and automatic formatting
# like trailing whitespace removal (to be configured later):
#
## For only installing the package itself, run:
# pip3 install pre-commit
#
## For activating it as a pre-commit and pre-push hook (recommended):
# pre-commit install --hook-type pre-push --hook-type pre-commit
#
## For manually executing the pre-push hook:
# pre-commit run -av --hook-stage pre-push
#
default_stages: [commit, push]
repos:
# Recommendation for a minimal git pre-commit hook:
# https://github.com/pre-commit/pre-commit-hooks/blob/main/README.md:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: no-commit-to-branch
name: "The master branch should be pulled only, don't commit to it"
args: [--branch, master]
always_run: true
- id: check-merge-conflict
- id: check-yaml
- id: check-executables-have-shebangs
exclude: ocaml

# Recommendation for a minimal git pre-push hook:
# While using pre-commit yields great results, it
# is "not fast". Therefore only run it pre-push,
# (but always in GitHub CI of course):
#
# Calls ./pytype_reporter.py in a dedicated venv:
# pre-commit run -av --hook-stage push
- repo: local
hooks:
- id: pytype
name: pytype
entry: python3 pytype_reporter.py
types: [python]
stages: [push]
verbose: true
# This hook runs locally only when Python files change:
language: python
# Pytype supports running on Python 3.8 to Python3.11 currently:
# https://google.github.io/pytype/support.html
# If a dev's default python3 interpreter is outside that range, but
# developers have such version installed, it can be configured here:
# language_version: python3.11
require_serial: true
additional_dependencies: [pandas, pytype]
129 changes: 129 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# https://packaging.python.org/en/latest/specifications/pyproject-toml/
[project]
name = "xen-api"
requires-python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
license = {file = "LICENSE"}
keywords = ["xen-project", "Xen", "hypervisor", "libraries"]
maintainers = [
{name = "Christian Lindig"},
{name = "Edwin Török"},
{name = "Rob Hoes"},
{name = "Pau Ruiz Safont"},
]
readme = "README.markdown"
# https://pypi.org/classifiers/
classifiers = [
"Development Status :: 5 - Production/Stable",
"Operating System :: POSIX :: Linux :: XenServer Dom0",
"Operating System :: POSIX :: Linux :: XCP-ng Dom0",
"Programming Language :: ML",
"Programming Language :: Python :: Implementation :: CPython",
]

[project.urls]
homepage = "https://github.com/xapi-project/xen-api"
repository = "https://github.com/xapi-project/xen-api"

[tool.black]
line-length = 88

[tool.isort]
line_length = 88
py_version = 27
profile = "black"
combine_as_imports = true
ensure_newline_before_comments = false


[tool.mypy]
# Note mypy has no config setting for PYTHONPATH, so you need to call it with:
# PYTHONPATH="scripts/examples/python:.:scripts:scripts/plugins:scripts/examples"
files = [
"scripts/usb_reset.py",
"scripts/unit_tests",
]
pretty = true
error_summary = true
strict_equality = true
show_error_codes = true
show_error_context = true
# Check the contents of untyped functions in all modules by default:
check_untyped_defs = true
scripts_are_modules = true
python_version = "3.11"
warn_return_any = true
warn_unreachable = true
warn_unused_configs = true
warn_redundant_casts = true
disallow_any_explicit = false
disallow_any_generics = true
disallow_any_unimported = true
disallow_subclassing_any = true


[tool.pytype_reporter]
default_branch = "master"
discard_messages_matching = [
"Couldn't import pyi for 'xml.dom.minidom'",
"No attribute '.*' on RRDContentHandler",
"No attribute 'group' on None",
"No Node.TEXT_NODE in module xml.dom.minidom, referenced from 'xml.dom.expatbuilder'"
]
expected_to_fail = [
"scripts/hfx_filename",
"scripts/perfmon",
# Need 2to3 -w <file> and maybe a few other minor updates:
"scripts/hatests",
"scripts/backup-sr-metadata.py",
"scripts/restore-sr-metadata.py",
"scripts/nbd_client_manager.py",
# No attribute 'popen2' on module 'os' [module-attr] and a couple more:
"scripts/mail-alarm",
# SSLSocket.send() only accepts bytes, not unicode string as argument:
"scripts/examples/python/exportimport.py",
# Other fixes needed:
"scripts/examples/python/mini-xenrt.py",
"scripts/examples/python/XenAPI/XenAPI.py",
"scripts/examples/python/monitor-unwanted-domains.py",
"scripts/examples/python/shell.py",
"scripts/examples/smapiv2.py",
"scripts/static-vdis",
# add_interface: unsupported operand type(s) for +: str and UsbInterface
"scripts/usb_scan.py",
# TestUsbScan.assertIn() is called with wrong arguments(code not iterable)
"scripts/test_usb_scan.py",
"scripts/plugins/extauth-hook-AD.py",
]


[tool.pytype]
inputs = [
"scripts/hfx_filename",
"scripts/perfmon",
"scripts/static-vdis",
"scripts/Makefile",
"scripts/generate-iscsi-iqn",
"scripts/hatests",
"scripts/host-display",
"scripts/mail-alarm",
"scripts/print-custom-templates",
"scripts/probe-device-for-file",
"scripts/xe-reset-networking",
"scripts/xe-scsi-dev-map",
"scripts/examples/python",
"scripts/yum-plugins",
"scripts/*.py",

# To be added later,
# when converted to Python3-compatible syntax:
# "ocaml/message-switch/python",
# "ocaml/idl/ocaml_backend/python",
# "ocaml/xapi-storage/python",
]
disable = [
"import-error", # xenfsimage, xcp.bootloader. xcp.cmd
"ignored-abstractmethod",
"ignored-metaclass",
]
platform = "linux"
pythonpath = "scripts/examples/python:.:scripts:scripts/plugins:scripts/examples"
Loading