DEV Community

Cover image for Automate Python Linting and Code Style Enforcement with Ruff and GitHub Actions
Zoo Codes
Zoo Codes

Posted on

Automate Python Linting and Code Style Enforcement with Ruff and GitHub Actions

Introduction

Maintaining a consistent code style and following best practices is important for any Python project. However, manually fixing linting issues can be tedious and easy to forget. In this tutorial, we'll see how to set up GitHub Actions to automatically lint Python code with Ruff on every push and commit any fixes.

In the previous tutorial, we saw how to use Ruff to lint Python code.
However, manually fixing linting issues can be tedious and easy to forget.

Prerequisites

  • A GitHub repository with Python code
  • GitHub Actions enabled
  • Ruff installed locally

Creating the Workflow

The workflow will run on pushes to lint with Ruff and commit fixes:

name: Lint and Commit
on: push

jobs:
  lint:
    runs-on: ubuntu-latest 
    steps:
    - uses: actions/checkout@v2
    - uses: actions/setup-python@v2
    - run: pip install ruff
    - run: | 
      ruff check .
      ruff fix .
    - uses: stefanzweifel/git-auto-commit-action@v4
      with:
        commit_message: 'style fixes by ruff'
Enter fullscreen mode Exit fullscreen mode

The new key step is the git-auto-commit-action, which will detect changes made by Ruff and commit them with a message.

Configuring Ruff

We can create a .ruff.toml or ruff.toml file to customize Ruff:


line-length = 120
target-version = "py39"
select = ["E", "W"]
Enter fullscreen mode Exit fullscreen mode

The code above sets the line length to 120 characters, the target Python version to 3.9, and the rules to E and W. Read more about the configuration options here

Using the Ruff GitHub Action

We can also use the Ruff GitHub Action to run Ruff in our workflow:

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

jobs:
  lint:
    runs-on: ubuntu-latest 
    steps:
    - uses: actions/checkout@v3
    - uses: actions/setup-python@v2
    - uses: chartboost/ruff-action@v1
      with:
        args: --check .
        fix_args: --fix .
    - uses: stefanzweifel/git-auto-commit-action@v4
      with:
        commit_message: 'style fixes by ruff'
Enter fullscreen mode Exit fullscreen mode

The code above is equivalent to the previous workflow. The main difference is that we are using the Ruff GitHub Action instead of running Ruff directly. Read more about the Ruff GitHub Action here

Each approach has its own advantages:

  • Running Ruff directly gives us more control over the Ruff process. We can specify a custom configuration file, for example.
  • Using the Ruff GitHub Action is simpler and requires less code.
  • Running Ruff directly is marginally faster because we don't need to install Ruff every time.

This will run Ruff with the --check and --fix arguments. We can also use the config argument to specify a custom configuration file:

name: Lint and Commit
on: push

jobs:
  lint:
    runs-on: ubuntu-latest 
    steps:
    - uses: actions/checkout@v2
    - uses: actions/setup-python@v2
    - uses: chartboost/ruff-action@v1
      with:
        args: --check .
        fix_args: --fix .
        config: .ruff.toml
    - uses: stefanzweifel/git-auto-commit-action@v4
      with:
        commit_message: 'style fixes by ruff'
Enter fullscreen mode Exit fullscreen mode

This will adjust the rules to our preference. This is useful if we want to use different rules for different projects.

Pick the approach that works best for your project.

Auto Commit Action

We are also using the auto-commit action to commit the changes. We can configure the commit message and other options. Read more about the auto-commit action here. This is optional - we can also use the git action to commit the changes manually.

The combination of Ruff and the auto-commit action allows us to automatically fix linting issues and commit the changes on every push. This helps us maintain a consistent code style and follow best practices over time.

Viewing Results

The Actions output will now show files changed and committed by Ruff. The commits will also be visible in the repository history.

Workflow run

Feel free to check out my for an example workflow usage/run.

GitHub logo KenMwaura1 / FastAPI-Backend-Template

A backend project template with FastAPI, PostgreSQL with asynchronous SQLAlchemy 2.0, Alembic for asynchronous database migration, and Docker.

FastAPI Backend Application Template

This is a template repository aimed to kick-start your project with a setup from a real-world application! This template utilizes the following tech stack:

When the Docker is started, these are the URL addresses:

  • Backend Application (API docs) $\rightarrow$ http://localhost:8001/docs
  • Database editor (Adminer) $\rightarrow$ http//localhost:8081

The backend API without Docker can be found in http://localhost:8000/docs.

Why the above Tech-Stack?

Well, the easy answer is Asynchronousity and Speed!

  • FastAPI is crowned as the fastest web framework for Python and thus we use it for our backend development.
  • The database of my choice is the asynchronous version of PostgreSQL (via SQLAlchemy 2.0). Read this blog from Packt if you want to educate yourself further about the topic Asynchronous, Synchronous, Concurrency, and Parallelism.
  • Docker is a technology that packages an application into standardized units called containers that have…

Conclusion

With auto-commit enabled, we no longer need to manually fix linting issues flagged by Ruff - the fixes are applied automatically on each push. This helps enforce a consistent code style over time.

Some next steps:

  • Set Ruff to run on pull requests too.
  • Configure commit options like commit user and branch.
  • Set up Slack/email notifications.

By integrating linters like Ruff into our GitHub workflows, we can automate parts of the coding process and reduce manual work.

Let's connect on Twitter and LinkedIn.

References

Next time gif

Top comments (1)

Collapse
 
hartley94 profile image
Hartley94

Informative post, 👏.