diff --git a/.github/workflows/format.yml b/.github/format.yml similarity index 100% rename from .github/workflows/format.yml rename to .github/format.yml diff --git a/.github/workflows/main.yml b/.github/main.yml similarity index 62% rename from .github/workflows/main.yml rename to .github/main.yml index 0c163aa7e32..18896d8b673 100644 --- a/.github/workflows/main.yml +++ b/.github/main.yml @@ -14,16 +14,18 @@ jobs: 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 + - name: Setup Python ${{matrix.python-version}} (without a container) + uses: LizardByte/setup-python-action@master + with: + python-version: ${{matrix.python-version}} + - name: Install python 2 dependencies - if: ${{ startsWith(matrix.docker-image, 'python:2.7.18') }} + if: ${{ matrix.python-version == '2.7' }} run: pip install enum - name: Install dependencies @@ -115,3 +117,45 @@ jobs: - name: quality-gate run: make quality-gate + + # uses: tsuyoshicho/action-mypy@v3.13.0 + - uses: bernhardkaindl/action-mypy@36cb3a857d01c1bdaa2811893106c71580132d71 + with: + filter_mode: no_filter + setup_method: install + setup_command: pip install mypy mock + mypy_flags: | + --scripts-are-modules + --check-untyped-defs + --allow-redefinition + --hide-error-context + --ignore-missing-imports + --no-pretty + --warn-unreachable + --exclude ocaml/ + --exclude scripts/examples + --exclude scripts/examples/python/monitor-unwanted-domains.py + --exclude scripts/scalability-tests/ping-master.py + --exclude scripts/backup-sr-metadata.py + --exclude scripts/restore-sr-metadata.py + --exclude scripts/nbd_client_manager.py + --config-file mypy.ini + target: | + scripts/perfmon + scripts/hfx_filename + scripts/mail-alarm + scripts/host-display + github_token: ${{ secrets.github_token }} + reporter: github-pr-review + + - uses: dciborow/action-pylint@0.1.1 + with: + filter_mode: no_filter + glob_pattern: "scripts/*" + pylint_args: | + --verbose + --disable=trailing-whitespace + --disable=bad-indentation + --rc .pylintrc + github_token: ${{ secrets.github_token }} + reporter: github-pr-review diff --git a/.github/mypy.ini b/.github/mypy.ini new file mode 100644 index 00000000000..aee7c50c3d4 --- /dev/null +++ b/.github/mypy.ini @@ -0,0 +1,46 @@ +[mypy-XenAPI.*] +# TODO/FIXME: +disable_error_code = union-attr +[mypy] +# TODO/FIXME: +exclude = (?x)( + ^ocaml/ + | scripts/.*usb_scan.py + | scripts/examples + | scripts/examples/python/monitor-unwanted-domains.py + | scripts/scalability-tests/ping-master.py + | scripts/backup-sr-metadata.py + | scripts/restore-sr-metadata.py + | scripts/nbd_client_manager.py + ) +# Python scripts that don't end in .py must be given here: +files = +# TODO/FIXME: Test more scripts by default after those are fixed: + scripts/hfx_filename, + scripts/perfmon, + scripts/mail-alarm, + scripts/host-display, +# TODO/FIXME: +disable_error_code = + attr-defined, + import-not-found, + import-untyped, + type-arg, + var-annotated, +mypy_path = scripts/examples/python:.:scripts:scripts/plugins:scripts/examples +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 +# TODO/FIXME: mypy does not support targetting 3.6 anymore: +python_version = 3.8 +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 diff --git a/.github/workflows/python-code-review.yml b/.github/workflows/python-code-review.yml new file mode 100644 index 00000000000..712ecad8cd7 --- /dev/null +++ b/.github/workflows/python-code-review.yml @@ -0,0 +1,59 @@ +name: Python Code Review +on: [pull_request] + +# Cancel a currently running workflow from the same PR, branch or tag when +# a new workflow is triggered: +# https://stackoverflow.com/questions/66335225/how-to-cancel-previous-runs-in-the-pr-when-you-push-new-commitsupdate-the-curre +concurrency: + cancel-in-progress: true + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + +jobs: + python-code-review: + name: Python Code Review + runs-on: ubuntu-20.04 + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Needed to get the changed lines: origin/master..HEAD + + - name: Setup Python 3.11 + uses: LizardByte/setup-python-action@master + with: + python-version: 3.11 + + # uses: tsuyoshicho/action-mypy@v3.13.0 + - uses: bernhardkaindl/action-mypy@36cb3a857d01c1bdaa2811893106c71580132d71 + with: + filter_mode: nofilter + setup_method: install + setup_command: pip install mypy mock + mypy_flags: | + --scripts-are-modules + --check-untyped-defs + --allow-redefinition + --ignore-missing-imports + --no-pretty + --warn-unreachable + --exclude ocaml/ + --exclude scripts/examples + --exclude scripts/examples/python/monitor-unwanted-domains.py + --exclude scripts/scalability-tests/ping-master.py + --exclude scripts/backup-sr-metadata.py + --exclude scripts/restore-sr-metadata.py + --exclude scripts/nbd_client_manager.py + target: | + scripts/perfmon + scripts/hfx_filename + scripts/mail-alarm + scripts/host-display + github_token: ${{ secrets.github_token }} + reporter: github-pr-review + + - uses: dciborow/action-pylint@0.1.1 + with: + filter_mode: nofilter + glob_pattern: "scripts/*" + github_token: ${{ secrets.github_token }} + reporter: github-pr-review diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 00000000000..d2709fd065f --- /dev/null +++ b/.pylintrc @@ -0,0 +1,75 @@ +[MAIN] + +# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the +# number of processors available to use, and will cap the count on Windows to +# avoid hangs. +jobs=2 + +# Pickle collected data for later comparisons. +persistent=yes + +# Discover python modules and packages in the file system subtree. +recursive=yes + +# Add paths to the list of the source roots. Supports globbing patterns. The +# source root is an absolute path or a path relative to the current working +# directory used to determine a package namespace for modules located under the +# source root. +source-roots= + ocaml/xapi-storage/python, + scripts, + scripts/examples/python, + +# When enabled, pylint would attempt to guess common misconfiguration and emit +# user-friendly hints instead of false-positive error messages. +suggestion-mode=yes + +# In verbose mode, extra non-checker-related info will be displayed. +verbose=yes + +[MESSAGES CONTROL] + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once). You can also use "--disable=all" to +# disable everything first and then re-enable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use "--disable=all --enable=classes +# --disable=W". +disable= + bad-option-value, # old pylint for py2: ignore newer (unknown) pylint options + bad-continuation, # old pylint warns about some modern black formatting + bad-indentation, + consider-using-dict-comprehension, + consider-using-f-string, + consider-using-with, + import-error, + import-outside-toplevel, + invalid-name, + missing-final-newline, + missing-function-docstring, + multiple-imports, + redefined-outer-name, + trailing-whitespace, # enable this soon, after citical PRs are merged + useless-option-value, # new pylint has abaondoned these old options + +[FORMAT] + +# Maximum number of characters on a single line. +max-line-length=98 + +[BASIC] + +# Good variable names which should always be accepted, separated by a comma. +good-names=a, + b, + c, + f, + i, + j, + k, + ex, + Run, + _