We usually have tools that can automatically format or lint code for us, running on file save or as a precommit hook.
However, if the tool takes a long time to run, it can be disruptive to your flow. Github Actions can be used to run commands on your behalf and commit the fixes back to your branch. Here’s how to configure an action that does that. In this example, I will use Scalafix as an example of a tool that can take a significant amount of time to run (on the order of minutes for larger projects), but any other tool can be substituted (e.g. eslint --fix
).
Create a file in <project root>/.github/workflows
, and put the following:
name: "Scalafix"
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.ref }}
- name: Set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Run Scalafix
# JVM settings as recommended by Scalafix
env:
JAVA_OPTS: -Xmx8G -Xms1G -Xss8M
run: sbt all compile:scalafix test:scalafix
- name: Commit files and push
# We run git diff first to check if there are any files changed
# before committing, since git commit will throw exit code 1 if there
# are no files to commit
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git diff --quiet HEAD || git commit -am "Github Action: Scalafix"
git push
This is a workflow that is triggered on the pull_request
event. Feel free to tweak it trigger on other events.
By default, actions/checkout
will checkout to a detached HEAD, since pull request refs (stored in refs/pulls/12/merge
) are not regular branches (e.g. refs/heads/update-readme
). In order to be able to able to commit back to the branch itself, checkout the branch corresponding to the pull request, using the ${{ github.event.pull_request.head.ref }}
Github context variable.
Next, do Scalafix things, or insert the tool of your choice. Giving Scalafix enough memory is important to prevent the Github Actions runner from crashing from OOM errors. Github Actions runners are all standardized with a 2-core CPU and 7GB of memory, which seems to be sufficient for Scalafix.
Once the tool(s) is done running, there may be some changed files in the working directory. git commit
returns an exit code of 1 if there are no files to commit, so check for the presence of changed files with git diff --quiet HEAD
before committing all changed files, otherwise the workflow will appear to fail. Finally, push the commit to the branch.