Skip to content

Lint and type check Python with your choice of popular linters, and upload results to GitHub Code Scanning

License

Notifications You must be signed in to change notification settings

advanced-security/python-lint-code-scanning-action

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Repository files navigation

Python Linting Action

Note

This is an unofficial tool created by Field Security Services, and is not officially supported by GitHub.

This Action and Python script lets you run one of several Python linters and type checkers, and upload the results to GitHub's Code Scanning, which is part of Advanced Security (free for open source projects hosted on GitHub).

Supported linters and type checkers

Requirements

  • Python 3.7 or higher (3.8 or higher for MacOS on GitHub hosted runners)
  • For Pytype, Python 3.10 or lower
  • For Fixit, Python 3.8 or higher
  • GitHub Actions
  • GitHub Advanced Security (for private repositories)

Usage

Actions usage

Configure the linters

Configure the linters using a configuration file in your repository, appropriate to the linter.

Many can use pyproject.toml, but not all.

Example pyproject.toml and .flake8 files for linting this repository are included.

Call the Action with a workflow

First check out the repository with github/checkout of a supported version, so the code is available to the workflow.

The simplest use is to use just one linter at a time:

uses: advanced-security/python-lint-code-scanning-action@v1
with:
  linter: flake8

You can run it with more than one linter using a matrix:

jobs:
  lint:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        linter: [flake8, pylint, ruff, mypy, pytype, pyright, fixit, pyre]
    steps:
      - uses: advanced-security/python-lint-code-scanning-action@v1
        with:
          linter: ${{ matrix.linter }}

Similarly, you can run it with more than one Python version:

jobs:
  lint:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: [3.7, 3.8, 3.9, 3.10, 3.11]
    steps:
      - uses: advanced-security/python-lint-code-scanning-action@v1
        with:
          linter: flake8
          python-version: ${{ matrix.python-version }}

You could even combine both.

If you want to use plugins for one of the linters, you can install that before running the action, e.g.

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - run: python3 -mpip install flake8-bugbear
      - uses: advanced-security/python-lint-code-scanning-action@v1
        with:
          linter: flake8

Pin the version of a linter, e.g. if the latest version is incompatible with this Action.

Note

Remember to put quotes around version strings so they are not interpreted as floating point numbers.

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: advanced-security/python-lint-code-scanning-action@v1
        with:
          linter: ruff
          ruff-version: "0.0.257"

Command line usage

First install the Flake8 SARIF formatter, if you are using Flake8:

python3 -m pip install flake8-sarif-formatter

Then run the linter, which must already be installed in your environment:

python3 ./python_lint.py <linter> [<linter> ...] [<options>]

The linter/type checker can be one or more of flake8, pylint, ruff, mypy, pytype, pyright, fixit, pyre.

FAQ

Why not use existing Python linting Actions?

They don't all produce SARIF, and they don't upload to Code Scanning.

Why not use MegaLinter or Super-linter?

They aggregate lots of linters, for a lot of languages, but do not focus on producing output in SARIF, nor on Python.

Although MegaLinter has a SARIF output formatter, only those linters natively able to produce SARIF are usable this way.

This Action is specialised for useful linters for Python, and produces SARIF.

Why not create N different Actions?

It's far more convenient to have one Action that can run all of the popular linters, so you can configure it once and then run it with different linters.

Could you let me configure the linters using the Action's inputs?

No, because the configuration files are specific to each linter. Providing convenience abstractions over the inputs for all of the linters would be significantly more work than just using the configuration files.

It's possible that a future release might allow you to specify some very common shared options, such as line-length, but for now that's not been tackled.

Why not add SARIF output directly to the linters, and then call them?

Good idea. That's something to consider for the future. For now it was quicker and easier to call the linters and process their output into SARIF, vs raising PRs against each linter.

You really should provide some sensible defaults for the linters

Wow, so opinionated! We decided not to be opinionated 😁. Linting is very individual, and deciding on defaults beyond those of the tools themselves could prove to be a thankless task. Hopefully if you want to use these linters then you'll be able to configure them to your liking.

What about tool X?

Lots of linters are wrapped up or replicated by these linters.

pydocstyle can be run using a plugin to Flake8, and mccabe is included in Flake8.

If there's one you really need that isn't runnable, please raise an issue or a PR to include it.

Why can't I run all of the linters in one go?

Actions lets you do a matrix job, which does great work in parallelising things.

We could use Python multi-processing to run them all in parallel, but that doesn't make such sense on standard GitHub runners.

If you want to run them all at once you can call the underlying script with multiple linters, but that feature is really just to make testing easier, since they run in series.

Why do I see an error, but the run is not marked as having failed?

This avoids errors with a single linter resulting in the whole run being marked as "in error". It is the Code Scanning results that are of interest, not whether every linter ran successfully.

You should check for errors in the Actions log and resolve them. It might be better to have an option to report failure if a linter does not run properly - raise an issue or a PR if you want that.

License

This project is licensed under the terms of the MIT open source license. Please refer to the LICENSE for the full terms.

Maintainers

See CODEOWNERS for the list of maintainers.

Support

Note

This is an unofficial tool created by Field Security Services, and is not officially supported by GitHub.

See the SUPPORT file.

Background

See the CHANGELOG, CONTRIBUTING, SECURITY, SUPPORT, CODE OF CONDUCT and PRIVACY files for more information.

About

Lint and type check Python with your choice of popular linters, and upload results to GitHub Code Scanning

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published

Languages