Skip to content

🐍 A comprehensive Python quality gate that automatically runs Black for formatting, Pylint for code analysis, and MyPy for static type checking to keep your codebase clean and bug-free.

License

Notifications You must be signed in to change notification settings

thoughtparametersllc/python-linting

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

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

python-linting

License: MIT GitHub Marketplace

A comprehensive GitHub Action for Python code quality enforcement. Runs Pylint, Black, and MyPy with automatic badge generation and detailed reporting.

Features

  • 🐍 Flexible Python version support - Specify any Python version using actions/setup-python
  • πŸ“¦ Custom requirements - Install additional dependencies from a requirements file
  • πŸ” Comprehensive linting - Run Pylint, Black, and MyPy in a single action
  • πŸ“Š Detailed reporting - View results in GitHub Actions summary
  • πŸ… Automatic badge generation - Creates and commits SVG badges for each linter
  • βš™οΈ Highly configurable - Customize options for each linting tool

Prerequisites

  • Your repository must contain Python code
  • For badge commits: the workflow needs contents: write permission

Usage

Basic Example

name: Python Linting
on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    permissions:
      contents: write  # Required for badge commits
    steps:
      - uses: actions/checkout@v4
      
      - name: Python Linting
        uses: thoughtparametersllc/python-linting@v1

Advanced Example with Custom Options

name: Python Linting
on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
      
      - name: Python Linting
        uses: thoughtparametersllc/python-linting@v1
        with:
          python-version: '3.11'
          requirements-file: 'requirements.txt'
          pylint-options: '--max-line-length=120 --disable=C0111'
          black-options: '--line-length=120'
          mypy-options: '--strict --ignore-missing-imports'
          commit-badges: 'true'
          badge-directory: '.github/badges'

Example without Badge Commits

- name: Python Linting
  uses: thoughtparametersllc/python-linting@v1
  with:
    python-version: '3.10'  # Always quote version numbers
    commit-badges: 'false'  # Disable automatic badge commits

Example with Multiple Python Versions

name: Python Linting
on: [push, pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ['3.9', '3.10', '3.11', '3.12']
    steps:
      - uses: actions/checkout@v4
      
      - name: Python Linting
        uses: thoughtparametersllc/python-linting@v1
        with:
          python-version: ${{ matrix.python-version }}
          commit-badges: ${{ matrix.python-version == '3.11' && 'true' || 'false' }}  # Only the Python 3.11 job commits badges

Inputs

Input Description Required Default
python-version Python version to use for linting No 3.x
requirements-file Path to requirements file for additional dependencies No requirements.txt
pylint-options Additional options to pass to pylint No ''
black-options Additional options to pass to black No ''
mypy-options Additional options to pass to mypy No ''
commit-badges Whether to commit generated SVG badges back to the repository No true
badge-directory Directory to save the generated SVG badges No .github/badges

Outputs

This action does not produce any outputs. Results are displayed in the GitHub Actions summary and as SVG badges (if enabled).

Badges

When commit-badges is set to true (default), the action automatically generates and commits three SVG badge files to your repository:

  • {badge-directory}/pylint.svg - Pylint status badge
  • {badge-directory}/black.svg - Black status badge
  • {badge-directory}/mypy.svg - MyPy status badge

Displaying Badges in README

Add these badges to your README.md to show linting status:

![Pylint](.github/badges/pylint.svg)
![Black](.github/badges/black.svg)
![MyPy](.github/badges/mypy.svg)

Badge Colors

  • 🟒 Green (success) - No issues found
  • πŸ”΄ Red (failure) - Issues detected

Permissions

This action requires the following permissions:

permissions:
  contents: write  # Required only if commit-badges is 'true'

If you set commit-badges: 'false', you can use:

permissions:
  contents: read

Troubleshooting

Badge Commits Failing

Issue: The action fails to commit badges back to the repository.

Solutions:

  • Ensure contents: write permission is set in your workflow
  • Verify that branch protection rules allow the github-actions[bot] to push
  • Check that the badge directory exists or can be created

Linting Tools Not Found

Issue: Pylint, Black, or MyPy commands fail with "command not found".

Solutions:

  • Ensure Python is properly set up (the action handles this automatically)
  • Check that the Python version you specified is available
  • Review the "Install Linting Tools" step logs for errors

Requirements Installation Fails

Issue: Additional requirements cannot be installed.

Solutions:

  • Verify the requirements-file path is correct relative to repository root
  • Ensure the requirements file exists and is readable
  • Check for syntax errors in the requirements file
  • Review dependency conflicts in the workflow logs

False Positive Linting Errors

Issue: Linters report issues that you want to ignore.

Solutions:

  • Use linter-specific options to customize behavior:
    • Pylint: pylint-options: '--disable=C0111,W0212'
    • Black: black-options: '--line-length=120'
    • MyPy: mypy-options: '--ignore-missing-imports'
  • Create configuration files (.pylintrc, pyproject.toml) in your repository

Action Fails on Pull Requests from Forks

Issue: Badge commits fail on pull requests from forked repositories.

Solution: This is expected behavior for security reasons. Forks don't have write access. Consider:

  • Setting commit-badges: 'false' for PRs from forks
  • Using a conditional in your workflow:
    commit-badges: ${{ github.event.pull_request.head.repo.full_name == github.repository && 'true' || 'false' }}

How It Works

  1. Setup Python: Installs specified Python version
  2. Install Tools: Installs Pylint, Black, and MyPy
  3. Install Requirements: (Optional) Installs dependencies from your requirements file
  4. Run Linters: Executes all three linting tools sequentially
  5. Generate Badges: Creates SVG badges showing pass/fail status
  6. Commit Badges: (Optional) Commits badges back to your repository
  7. Generate Summary: Creates detailed GitHub Actions summary with results

Best Practices

When to Use This Action

βœ… Good use cases:

  • CI/CD pipelines for Python projects
  • Pre-merge checks on pull requests
  • Automated code quality enforcement
  • Ensuring consistent code style across teams

❌ Not recommended for:

  • Local development (use pre-commit hooks instead)
  • Projects with custom linting workflows requiring specific tool versions
  • Repositories with complex multi-language setups

Recommended Workflow Configuration

name: Code Quality
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  lint:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
      
      - name: Python Linting
        uses: thoughtparametersllc/python-linting@v1
        with:
          python-version: '3.11'
          requirements-file: 'requirements.txt'

Configuration Files

You can customize linter behavior using configuration files in your repository:

  • Pylint: .pylintrc or pyproject.toml
  • Black: pyproject.toml
  • MyPy: mypy.ini or pyproject.toml

Example pyproject.toml:

[tool.black]
line-length = 120
target-version = ['py311']

[tool.mypy]
python_version = "3.11"
warn_return_any = true
warn_unused_configs = true

[tool.pylint.format]
max-line-length = 120

[tool.pylint.messages_control]
disable = ["C0111", "C0103"]

Examples

Example: Python Package with Tests

name: Test and Lint
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      - run: pip install -r requirements.txt
      - run: pytest

  lint:
    runs-on: ubuntu-latest
    needs: test  # Run after tests pass
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
      - uses: thoughtparametersllc/python-linting@v1
        with:
          requirements-file: 'requirements.txt'

Example: Monorepo with Python Subdirectory

name: Lint Python Code
on: [push]

jobs:
  lint:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
      
      # Note: The action runs from repository root regardless of working-directory settings
      # Specify full paths from root for requirements-file and Python code location
      - name: Python Linting
        uses: thoughtparametersllc/python-linting@v1
        with:
          requirements-file: './python-service/requirements.txt'

Example: Read-Only Mode (No Badge Commits)

name: PR Linting Check
on: pull_request

jobs:
  lint:
    runs-on: ubuntu-latest
    permissions:
      contents: read  # Read-only for PR checks
    steps:
      - uses: actions/checkout@v4
      
      - name: Python Linting
        uses: thoughtparametersllc/python-linting@v1
        with:
          commit-badges: 'false'

Development

This repository includes comprehensive GitHub workflows for CI/CD:

  • Test Action: Validates all action features across multiple Python versions
  • Lint & Test: Ensures code quality with Pylint, Black, MyPy, and Flake8
  • Changelog Check: Requires changelog updates for substantive changes
  • Release & Marketplace: Automated semantic versioning and tagging

For detailed workflow documentation, see .github/WORKFLOWS.md.

Quick Start for Contributors

See .github/WORKFLOW_QUICK_START.md for a quick reference guide.

Releasing

The release workflow supports both automatic semantic versioning and manual version specification:

Automatic Release (when changes are merged to main):

  • Automatically detects version bump from CHANGELOG.md
  • Creates release with extracted changelog notes
  • Updates major version tag (e.g., v1)

Manual Release (for specific versions):

  1. Go to Actions β†’ Release and Marketplace β†’ Run workflow
  2. Enter version as 1.0.0 or v1.0.0 (for specific version) or major/minor/patch (for semantic bump)
  3. The workflow will create the release and update tags

Contributing

We welcome contributions! Please see CONTRIBUTING.md for detailed guidelines.

Quick steps:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Update CHANGELOG.md under the [Unreleased] section
  5. Ensure all tests pass
  6. Submit a pull request

Support

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

Built with:

  • Pylint - Python code analysis
  • Black - Python code formatter
  • MyPy - Static type checker

About

🐍 A comprehensive Python quality gate that automatically runs Black for formatting, Pylint for code analysis, and MyPy for static type checking to keep your codebase clean and bug-free.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

No packages published

Contributors 6