diff --git a/.github/workflows/all-lints.yml b/.github/workflows/all-lints.yml index d812331..de59ecf 100644 --- a/.github/workflows/all-lints.yml +++ b/.github/workflows/all-lints.yml @@ -5,10 +5,26 @@ name: Lint Python jobs: lintpython: name: Lint Python - runs-on: ubuntu-20.04 + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-13, macos-latest, windows-latest] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] + exclude: + - os: macos-latest + python-version: 3.8 + - os: macos-latest + python-version: 3.9 + - os: macos-latest + python-version: 3.10 + - os: macos-13 + python-version: 3.11 + - os: macos-13 + python-version: 3.12 + steps: - - uses: actions/checkout@v1 - - uses: marian-code/pyaction@master + - uses: actions/checkout@v4 + - uses: ./ with: python-root-list: "./tests/*.py ./tests/subtest/*.py" use-black: true @@ -20,5 +36,6 @@ jobs: use-pylint: false use-flake8: false use-vulture: true - conda-python-version: "3.6" + python-version: ${{ matrix.python-version }} + diff --git a/.github/workflows/test-python-install.yml b/.github/workflows/test-python-install.yml new file mode 100644 index 0000000..038dcd5 --- /dev/null +++ b/.github/workflows/test-python-install.yml @@ -0,0 +1,55 @@ +on: + push: + pull_request: +name: Check python installation +jobs: + pythoninstall: + name: Test Python install + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + python-version: ['3.11'] + use-external-python: [true, false] + env: + python-test-package: python-dummy + steps: + - uses: actions/checkout@v4 + + - name: Install Python if required + if: ${{ matrix.use-external-python }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install a test dependency if external Python is used + if: ${{ matrix.use-external-python }} + run: + pip install ${{ env.python-test-package }} + + - name: Test Action usage + uses: ./ + with: + python-root-list: "./tests/*.py ./tests/subtest/*.py" + use-black: true + use-isort: true + use-mypy: true + use-pycodestyle: true + use-pydocstyle: true + extra-pycodestyle-options: "--max-line-length=88" + use-pylint: false + use-flake8: false + use-vulture: true + python-version: ${{ matrix.python-version }} + use-external-python: ${{ matrix.use-external-python }} + + - name: Check if test dependency exists after execution + run: | + pip freeze > all-deps.txt + should_appear=$( if [[ "${{ matrix.use-external-python }}" == "true" ]]; then echo 0; else echo 1; fi ) + line_exists=$( grep -qF "${{ env.python-test-package }}" "all-deps.txt"; echo $? ) + echo "test package should be installed: ${{ matrix.use-external-python }}" + echo "test package is present (0 = present): ${line_exists}" + cat all-deps.txt + test "${should_appear}" == "${line_exists}" + diff --git a/README.md b/README.md index ac79752..34e8534 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ selected linters. - Zero configuration based: Add a single line in your CI and done! - GitHub Annotations on PR: Highlights issues inline on the PR diff. - Most of the popular community trusted linters in one place. +- Allows to use either a new or existing Python version using `use-external-python`. +See [this example](examples/actions-use_external_python.yml). ## Linters supported @@ -30,52 +32,47 @@ Basic: ```yml steps: - - uses: actions/checkout@v1 - - uses: marian-code/python-lint-annotate@v2 + - uses: actions/checkout@v4 + - uses: marian-code/python-lint-annotate@v4 ``` Options: ```yml steps: - - uses: actions/checkout@v1 - - uses: marian-code/python-lint-annotate@v2 + - uses: actions/checkout@v4 + - uses: marian-code/python-lint-annotate@v4 with: python-root-list: "src/ tests/*" # accepts wildcards use-pycodestyle: false use-mypy: false use-vulture: true extra-pylint-options: "--output-format="colorized" - conda-python-version: "3.7" + python-version: "3.8" ``` +### Examples +* [Only lint changed files, and ignore missing docstrings](examples/actions-only_changed_files.yml) + ## Details -Uses conda environment with user selected python version. Only python `3.6` - `3.9` -version are tested since they are by far most common now. Other python `3.x` versions -should also work. Any python `2.x` versions are unsupported! - -The lintner versions are: - -```bash -pycodestyle==2.6.0 -pydocstyle==5.1.1 -pylint==2.6.0 -mypy==0.800 -black==20.8b1 -flake8==3.8.4 -vulture==2.3 -isort==isort-5.7.0 -``` +Uses `actions/setup-python@v5`. Only python `3.8` - `3.12` versions are tested. +Python `3.x` versions prior to `3.8` are not tested since they are EOL now. +Any python `2.x` versions are unsupported! You can lint on Linux, Windows and MacOS. + +The linter versions are defined in [requirements.txt](requirements.txt). ## IMPORTANT - test environment -The python version you set up in your action script with `actions/setup-python@v2` -or by other means will not affect the linting process. The python version used by -the linters can be set up only by `conda-python-version` argument! This also means -that if you modify the system conda environment it might affect the lintnig process. -So it is best to keep the lintnig action separated from others. It is also recomended -to run this on `ubuntu-latest`. Example: +The python version is set by `actions/setup-python@v5` using composite actions. This +means that the the action will change python you might have previously set with +`actions/setup-python@v5`. There are two ways to circumvent this. + +- Keep the lintnig action separated from others +- Use it at the and of your workflow when the change in python version will not + affect anything else + +Example: ```yml on: @@ -85,10 +82,16 @@ name: Lint Python jobs: lintpython: name: Lint Python - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: marian-code/pyaction@v2 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: 3.9 + - run: | + python --version # this will output 3.9 now + run tests or other things using python ... + - uses: marian-code/python-lint-annotate@v4 with: python-root-list: "./tests/*.py" use-black: true @@ -100,7 +103,9 @@ jobs: use-pylint: false use-flake8: false use-vulture: true - conda-python-version: "3.8" + python-version: "3.8" + - run: | + python --version # this will output 3.8 now !!! ``` ## License diff --git a/action.yml b/action.yml index 0771b3f..746853d 100644 --- a/action.yml +++ b/action.yml @@ -7,7 +7,7 @@ inputs: python-root-list: description: "A list of all paths to test" required: false - default: "'./**/*.py'" + default: "." use-pylint: description: "Use Pylint" required: false @@ -72,25 +72,68 @@ inputs: description: "Extra options: pydocstyle $(extra-pydocstyle-options) $(python-root-list)" required: false default: "" - conda-python-version: - description: "Tests are run in Conda environment, set desired python version with this keyword" + python-version: + description: "Set desired python version with this keyword" required: false default: "3.8" + use-external-python: + description: "false (default): Install a new Python for this action; true: use the python installation in the previous steps" + type: boolean + required: false + default: false runs: using: "composite" steps: - - run: | - $CONDA/bin/conda --version - $CONDA/bin/conda install python=${{ inputs.conda-python-version }} + - name: Setup python + if: ${{ ! inputs.use-external-python }} + uses: actions/setup-python@v5 + with: + python-version: ${{ inputs.python-version }} + architecture: x64 + cache: pip + + - run: python --version shell: bash - name: Install lintners - - run: | - $CONDA/bin/python --version - $CONDA/bin/pip install -r ${{ github.action_path }}/requirements.txt + + - name: Windows install dependencies + if: ${{ runner.os == 'Windows' }} + run: | + pip install -r ${{ github.action_path }}\requirements.txt --ignore-installed + echo "path_sep=" >> $GITHUB_ENV + shell: pwsh + + - name: Posix install dependencies + if: ${{ runner.os != 'Windows' }} + run: pip install -r ${{ github.action_path }}/requirements.txt --ignore-installed shell: bash - name: Install lintners - - run: > + + - name: Lint on Windows + if: ${{ runner.os == 'Windows' }} + run: > + ${{ github.action_path }}\entrypoint.sh + '${{ inputs.python-root-list }}' + ${{ inputs.use-pylint }} + ${{ inputs.use-pycodestyle }} + ${{ inputs.use-flake8 }} + ${{ inputs.use-black }} + ${{ inputs.use-mypy }} + ${{ inputs.use-isort }} + ${{ inputs.use-vulture }} + ${{ inputs.use-pydocstyle }} + '${{ inputs.extra-pylint-options }}' + '${{ inputs.extra-pycodestyle-options }}' + '${{ inputs.extra-flake8-options }}' + '${{ inputs.extra-black-options }}' + '${{ inputs.extra-mypy-options }}' + '${{ inputs.extra-isort-options }}' + '${{ inputs.extra-vulture-options }}' + '${{ inputs.extra-pydocstyle-options }}' + shell: pwsh + + - name: Lint on Linux + if: ${{ runner.os == 'Linux' }} + run: > ${{ github.action_path }}/entrypoint.sh '${{ inputs.python-root-list }}' ${{ inputs.use-pylint }} @@ -110,4 +153,3 @@ runs: '${{ inputs.extra-vulture-options }}' '${{ inputs.extra-pydocstyle-options }}' shell: bash - name: Lint diff --git a/entrypoint.sh b/entrypoint.sh index ef1596a..0e84798 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,5 +1,3 @@ -#!/bin/sh -l - # Parameters # # $1 - python-root-list @@ -39,7 +37,16 @@ echo extra-vulture-options: ${16} echo extra-pydocstyle-options: ${17} # actions path has the copy of this actions repo -for matcher in $GITHUB_ACTION_PATH/matchers/*.json +echo $RUNNER_OS +if [ $RUNNER_OS = 'Windows' ] +then + MATCHERS=$GITHUB_ACTION_PATH\matchers\*.json +else + MATCHERS=$GITHUB_ACTION_PATH/matchers/*.json +fi +echo $MATCHERS + +for matcher in $MATCHERS do echo adding matcher $matcher echo "::add-matcher::${matcher}" @@ -51,7 +58,7 @@ if [ "$2" = true ] ; then echo Running: pylint ${10} $1 - $CONDA/bin/pylint --output-format="colorized" ${10} $1 + pylint --output-format="colorized" ${10} $1 exit_code=$? if [ "$exit_code" = "0" ]; then @@ -66,7 +73,7 @@ if [ "$3" = true ] ; then echo Running: pycodestyle ${11} $1 - $CONDA/bin/pycodestyle ${11} $1 + pycodestyle ${11} $1 exit_code=$? if [ "$exit_code" = "0" ]; then @@ -81,7 +88,7 @@ if [ "$4" = true ] ; then echo Running: flake8 ${12} $1 - $CONDA/bin/flake8 ${12} $1 + flake8 ${12} $1 exit_code=$? if [ "$exit_code" = "0" ]; then @@ -96,7 +103,7 @@ if [ "$5" = true ] ; then echo Running: black --check ${13} $1 - $CONDA/bin/black --check ${13} $1 + black --check ${13} $1 exit_code=$? if [ "$exit_code" = "0" ]; then @@ -109,9 +116,13 @@ fi if [ "$6" = true ] ; then - echo Running: mypy --ignore-missing-imports --follow-imports=silent --show-column-numbers ${14} $1 + echo Running: mypy --install-types --non-interactive --ignore-missing-imports --follow-imports=silent --show-column-numbers ${14} $1 - $CONDA/bin/mypy --ignore-missing-imports --follow-imports=silent --show-column-numbers ${14} $1 + mypy \ + --install-types --non-interactive \ + --ignore-missing-imports \ + --follow-imports=silent \ + --show-column-numbers ${14} $1 exit_code=$? if [ "$exit_code" = "0" ]; then @@ -126,7 +137,7 @@ if [ "$7" = true ] ; then echo Running: isort ${15} $1 -c --diff - $CONDA/bin/isort ${15} $1 -c --diff + isort ${15} $1 -c --diff exit_code=$? if [ "$exit_code" = "0" ]; then @@ -141,7 +152,7 @@ if [ "$8" = true ] ; then echo Running: vulture ${16} $1 - $CONDA/bin/vulture ${16} $1 + vulture ${16} $1 exit_code=$? if [ "$exit_code" = "0" ]; then @@ -156,7 +167,7 @@ if [ "$9" = true ] ; then echo Running: pydocstyle ${17} $1 - $CONDA/bin/pydocstyle ${17} $1 + pydocstyle ${17} $1 exit_code=$? if [ "$exit_code" = "0" ]; then diff --git a/examples/actions-only_changed_files.yml b/examples/actions-only_changed_files.yml new file mode 100644 index 0000000..3bb23bd --- /dev/null +++ b/examples/actions-only_changed_files.yml @@ -0,0 +1,26 @@ +name: Lint only files changed in Pull Request, and ignore Missing docstrings +on: + pull_request: + types: [ opened, reopened, synchronize, edited ] +jobs: + lint: + runs-on: ubuntu-latest + name: Lint + steps: + - name: Check out source repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # This is necessary to get the commits + - name: Set up Python environment + uses: actions/setup-python@v5 + with: + python-version: "3.8" + - name: Get changed python files between base and head + run: > + echo "CHANGED_FILES=$(echo $(git diff --name-only ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} -- | grep \.py))" >> $GITHUB_ENV + - if: ${{ env.CHANGED_FILES }} + uses: marian-code/python-lint-annotate@v3 + with: + python-root-list: ${{ env.CHANGED_FILES }} + extra-pylint-options: "--disable=C0114,C0116" # Missing doctrings + extra-pydocstyle-options: "--ignore=D1" # Missing doctrings http://www.pydocstyle.org/en/stable/error_codes.html#grouping diff --git a/requirements.txt b/requirements.txt index e5fd10b..95890b8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ -black==20.8b1 -flake8==3.8.4 -isort==5.7.0 -mypy==0.800 -pycodestyle==2.6.0 -pydocstyle==5.1.1 -pylint==2.6.0 -vulture==2.3 \ No newline at end of file +black==24.3.0 +flake8==7.0.0 +isort==5.13.2 +mypy~=1.9.0 +pycodestyle==2.11.1 +pydocstyle==6.3.0 +pylint==3.1.0 +vulture==2.11