Getting Started
To setup autofix.ci, do the following:
-
Install our GitHub App.
This provides autofix.ci with the necessary permissions to update pull requests.
-
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 release is not required, but makes our workflow more resilient against supply chain attacks.[1]
-
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.
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@f6e93113a117b69c0005a80c088b9f3d0265b04a
- run: ruff check --fix-only .
- run: ruff format .
- uses: autofix-ci/action@dd55f44df8f7cdb7a6bf74c78677eb8acd40cd0a
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@25433bd037e5227fd0187b90e306324eceda414d
- 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@9397de6904c0791c23a16ce081245fc7498cf2b0
- 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@3a72c2c2d7c06633baceba03d3549e4b39e60472
- run: black .
- uses: autofix-ci/action@dd55f44df8f7cdb7a6bf74c78677eb8acd40cd0a
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@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