Blog Write a GitHub Action that lints your pull requests

Write a GitHub Action that lints your pull requests

2 min read

Write a GitHub Action that lints your pull requests
TL;DR Add a workflow file that triggers on pull_request, checks out the code, installs dependencies, and runs your linter. It fails the check when the linter finds problems, so style and obvious errors are caught before review, not during it.

Code review should be about logic and design, not about missing semicolons and inconsistent quotes. A GitHub Action that lints every pull request takes the mechanical checks off the reviewer's plate. Here is how to set one up.

The workflow file

Actions live in .github/workflows/. Create lint.yml that runs on pull requests.

name: Lint

on:
  pull_request:

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm run lint

That checks out the code, installs dependencies with a cached, reproducible install, and runs your lint script. If the linter exits non-zero, the check fails and the failure shows up right on the pull request.

Make it a required check

A check people can ignore eventually gets ignored. In your branch protection settings, mark the lint job as required. Now nothing merges into your main branch until it passes, and the style conversation disappears from human review entirely.

Keep it fast

  • Cache dependencies. The cache: npm line reuses the install between runs, so the job stays quick.
  • Lint only what you must. For large repos, you can lint changed files, though for most projects linting everything is fast enough not to bother.

Where to take it next

Once linting runs on every pull request, the same pattern extends naturally. Add a job for type-checking, one for tests, one for a build. Each is another mechanical check moved off the reviewer and onto the machine. I lean on this heavily for my WordPress plugins, where a CI gate keeps releases consistent, which is the whole idea behind my WP Plugin CI Action.

The payoff is cultural as much as technical. When the machine owns style and obvious errors, reviews get to be about the things only a human can judge.

FAQ

Why lint in CI instead of just locally?

Local linting depends on everyone remembering to run it and having it set up. A CI check runs the same way for every pull request, so nothing merges without passing, regardless of a contributor's local setup.

Should the lint check block merging?

Yes, make it a required check. A lint job that people can ignore drifts into being ignored. Requiring it keeps the main branch clean and takes the style conversation out of code review.

Will this slow down my pull requests?

Barely. Linting is fast, and caching dependencies keeps the job quick. The few seconds it costs are far cheaper than a reviewer spending time on formatting nits a machine could catch.