autofix.ci logo

Getting Started

To setup autofix.ci, do the following:

  1. Install our GitHub App.

    This provides autofix.ci with the necessary permissions to update pull requests.

  2. Create .github/workflows/autofix.yml with the following content:

    name: autofix.ci  # needed to securely identify the workflow
    
    on:
      pull_request:
      push:
        branches: [ "main" ]
    permissions:
      contents: read
    
    jobs:
      autofix:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
    
          # TODO: add all code-fixing here.
    
          - uses: autofix-ci/action@dd55f44df8f7cdb7a6bf74c78677eb8acd40cd0a
    

    Limiting the runner's permissions and pinning the autofix action to a specific commit hash instead of a tag is not required, but makes our workflow more resilient against supply chain attacks.[1]

  3. Add a job that auto-fixes your codebase.

    Replace the comment in the file above with the code-fixing tools of your choice.
    Take a look at the examples below!

Examples

You can combine all the example steps below, but keep them in a single job with only one call to the autofix action! :)

Python

This example demonstrates the use of ruff with autofix.ci. We use uv to install deterministic versions of all tools, but you can also pip install or use an existing requirements.txt file.

ruff
name: autofix.ci
on:
  workflow_call:
  pull_request:
  push:
    branches: [ "main" ]
permissions:
  contents: read

jobs:
  autofix:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # Use uv to ensure we have the same ruff version in CI and locally.
      - uses: astral-sh/setup-uv@77c28f02b3322332d4a4446b3177f426da8bf086
        with:
          version: "0.4.20"
      # Fix lint errors
      - run: uv run ruff check --fix-only .
      # Format code
      - run: uv run ruff format .

      - uses: autofix-ci/action@dd55f44df8f7cdb7a6bf74c78677eb8acd40cd0a

Of course, there are more autofixers than just ruff! You may also want to check out black, pyupgrade, reorder_python_imports, autoflake, yesqa, isort, blacken-docs, yapf, autopep8, docformatter, or μsort.

TypeScript / JavaScript / HTML / CSS

Here's a simple workflow that formats your TypeScript or JavaScript code using Prettier:

name: autofix.ci
on:
  pull_request:
  push:
    branches: [ "main" ]
permissions:
  contents: read

jobs:
  autofix:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 16

      - run: npm ci
      - run: npx prettier --write .

      - uses: autofix-ci/action@dd55f44df8f7cdb7a6bf74c78677eb8acd40cd0a

Alternatively, you may want to check out standardjs!

Rust

Here's a simple workflow that rustfmts your repo and applies clippy's suggestions:

name: autofix.ci
on:
  workflow_call:
  pull_request:
  push:
    branches: [ "main" ]
permissions:
  contents: read

env:
  rust_clippy: 1.65  # MSRV

jobs:
  autofix:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            target/
          key: autofix-${{ hashFiles('**/Cargo.lock') }}
          
      - run: rustup toolchain install ${{ env.rust_clippy }} --profile minimal --component rustfmt --component clippy
      - run: rustup default ${{ env.rust_clippy }}

      - run: cargo clippy --fix --workspace
      - run: cargo fmt --all

      - uses: autofix-ci/action@dd55f44df8f7cdb7a6bf74c78677eb8acd40cd0a

You can of course switch to a different Rust toolchain first, for example if you are using nightly rustfmt.

Crab fact: autofix.ci's backend is written in Rust. 🦀

Go

Here's a simple workflow that gofmts your repo:

name: autofix.ci
on:
  pull_request:
  push:
    branches: [ "main" ]
permissions:
  contents: read

jobs:
  autofix:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: '1.17'

      # goimports works like gofmt, but also fixes imports.
      # see https://pkg.go.dev/golang.org/x/tools/cmd/goimports
      - run: go install golang.org/x/tools/cmd/goimports@latest
      - run: goimports -w .
      # of course we can also do just this instead:
      # - run: gofmt -w .

      - uses: autofix-ci/action@dd55f44df8f7cdb7a6bf74c78677eb8acd40cd0a

Images

With a bit of creativity, autofix.ci is not limited to code formatting. For example, the following workflow shrinks all PNG files:

name: autofix.ci
on:
  pull_request:
  push:
    branches: [ "main" ]
permissions:
  contents: read

jobs:
  autofix:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # Optimize all PNGs with https://pngquant.org/
      - run: sudo apt-get update && sudo apt-get install -y pngquant
      - name: Run pngquant
        run: |
          shopt -s globstar
          pngquant -f --ext .png --skip-if-larger -- **/*.png

      - uses: autofix-ci/action@dd55f44df8f7cdb7a6bf74c78677eb8acd40cd0a

pre-commit hooks

If your existing workflow is based on pre-commit.com hooks, you should use pre-commit.ci instead of autofix.ci. Of course, you can also integrate pre-commit hooks in your autofix.ci workflow:

name: autofix.ci
on:
  pull_request:
  push:
    branches: [ "main" ]
permissions:
  contents: read

jobs:
  autofix:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - run: pip install pre-commit
      - run: pre-commit run --all-files

      - uses: autofix-ci/action@dd55f44df8f7cdb7a6bf74c78677eb8acd40cd0a