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@d3e591514b99d0fca6779455ff8338516663f7cc
    

    Limiting the runner's permissions and pinning the autofix action to a specific release 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

These two examples demonstrate the use of some of the most popular Python code fixing tools. We use the @install-pinned actions 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

      # Fix lint errors with https://github.com/charliermarsh/ruff
      - uses: install-pinned/ruff@fc90447b9d77655231e89ba016e71381e57a3804
      - run: ruff --fix-only .
      - run: ruff format .

      - uses: autofix-ci/action@d3e591514b99d0fca6779455ff8338516663f7cc
pyupgrade, reorder_python_imports autoflake, and black
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

      # Upgrade to the latest Python syntax with https://github.com/asottile/pyupgrade
      - uses: install-pinned/pyupgrade@2ef0e31dd8755f2a8b9f170ebfb241cb88b4f1ed
      - name: Run pyupgrade
        run: |  
          shopt -s globstar
          pyupgrade --exit-zero-even-if-changed --py39-plus **/*.py

      # Sort imports with https://github.com/asottile/reorder_python_imports
      - uses: install-pinned/reorder_python_imports@4919b538f4633769fd61b53a217ee8189332f49e
      - name: Run reorder-python-imports
        run: |
         shopt -s globstar
         reorder-python-imports --exit-zero-even-if-changed --py39-plus **/*.py

      # Remove unused imports with https://github.com/PyCQA/autoflake
      - uses: install-pinned/autoflake@eefdf266065c9cbe80ff5285a8a3307ad97d7958
      - run: autoflake --in-place --remove-all-unused-imports -r .

      # Format code with https://github.com/psf/black
      - uses: install-pinned/black@a892e0753fc4c9f0e1efc6c86966f07b5b1c71b2
      - run: black .

      - uses: autofix-ci/action@d3e591514b99d0fca6779455ff8338516663f7cc

Of course, there's way more in the Python ecosystem! You may also want to check out 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@d3e591514b99d0fca6779455ff8338516663f7cc

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@d3e591514b99d0fca6779455ff8338516663f7cc

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

Crab fact: autocix.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@d3e591514b99d0fca6779455ff8338516663f7cc

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@d3e591514b99d0fca6779455ff8338516663f7cc

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@d3e591514b99d0fca6779455ff8338516663f7cc