Prettier in GitHub Actions
Prettier is an awesome opinionated code formatted. It is used to set a consistent code style across a project which developers can easily follow.
Usually while working on the code base, developers might have a setting like “Format on Save” enabled so that the files are automatically formatted using Prettier (along with the Visual Studio Code Extension) when they are saved. They might even commit those settings to the project like in the Visual Studio Code workspace settings so that other developers are automatically doing it too.
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
}
But for some reason a developer might not format the code before committing it (not configured properly, extension not installed, using a different IDE etc…) and a manual review of the pull request might not catch this before it is merged to a deployment branch. As a safeguard, there should be a check to make sure that unformatted code is prevented from being merged into certain branches. We can do this by running Prettier using GitHub Actions, and preventing the merge until the action completes successfully.
I will be using pnpm as the package manager in this post but feel free to swap out any pnpm related sections of the code for the package manager of your choice.
Setting up Prettier in your project
Start by installing prettier
as a dev dependency (with the -D
flag). We will get into why installing it as a dev dependency makes sense later.
pnpm install prettier -E -D
Then add a script to your pacakage.json
file that makes formatting all you files in one go easier.
{
"scripts": {
"prettier:format": "prettier --write \"**/*.{ts,tsx,js,md,mdx,css,yaml}\""
}
}
After that add any files and folders that you do not want to be formatted by Prettier to the .prettierignore
file. I have added the patterns used in my portfolio as an example.
next-env.d.ts
.next
.vercel
pnpm-lock.yaml
.eslint.json
.vscode
.contentlayer
Finally you can run the script to format the files.
pnpm prettier:format
Configuring the Github Action
We can run Prettier with the check flag to see if there are any unformatted files. If we run this in any CI/CD workflow such as GitHub Actions, it should fail based on the exit codes if any file is not formatted. First add another script, prettier:check:ci
, to the package.json
file to run Prettier with the check flag in GitHub Actions.
{
"scripts": {
"prettier:format": "prettier --write \"**/*.{ts,tsx,js,md,mdx,css,yaml}\"",
"prettier:check:ci": "prettier --check \"**/*.{ts,tsx,js,md,mdx,css,yaml}\""
}
}
Next let’s configure the GitHub Action. Create the quality.yaml
file in the .github\workflows
folder and give the action a name.
name: Code Quality checks
Then we need to specify when to run the action. For our case, we need to run it when a pull request is created to the main
branch. You can also add any other branches you want to protect here as well. We will also be using concurrency to make sure that the action reruns after the pull request has been updated.
name: Code Quality checks
on:
pull_request:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
After that we can specify the job
to run.
name: Code Quality checks
on:
pull_request:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
prettier:
name: Prettier
runs-on: ubuntu-22.04
strategy:
matrix:
node-version: [18]
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
with:
version: 8
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: "pnpm"
- name: Install dependencies
run: pnpm install -D
There is quite a bit happening here so let’s go through the steps
. First we checkout our code with the actions/checkout@v3
action. Then we set pnpm as the package manager with the pnpm/action-setup@v2
action. Next Node.js is setup with actions/setup-node@v3
. Finally we install the dependencies with pnpm install -D
. It does not make sense to install all the dependencies just to check the code with Prettier hence we are only installing the dev dependencies (which Prettier is in as we specified in the install earlier).
All that is left to do is to run the Prettier check in the action through the script.
name: Code Quality checks
on:
pull_request:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
prettier:
name: Prettier
runs-on: ubuntu-22.04
strategy:
matrix:
node-version: [18]
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
with:
version: 8
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: "pnpm"
- name: Install dependencies
run: pnpm install -D
- name: Check formatting with Prettier
run: pnpm prettier:check:ci
Now the action will run whenever there in pull request created to the main
branch.
Protecting the repo branches
At the moment, the action would not stop the pull request from being merged if there are unformatted files. So we need to add a status check to the “Branch protection rule”.
Go to your branch settings in GitHub under Settings > Branches
. Edit the rule for the main
branch by checking “Require status checks to pass before merging” and adding the “Prettier” check under “Status checks that are required.”.

Now pull requests will be blocked until the “Prettier” check runs successfully.

Conclusion
Now your branches should be protected against code that is not properly formatted. You can also setup other checks such as ESLint with a similar configuration. You can check out the code checks that I run in my portfolio here.