Skip to content
Latchkey

How to Scope a Monorepo Build With git diff in GitHub Actions

A git diff against the base ref reveals which package directories changed, with no plugin required.

Check out full history, run git diff --name-only <base>..., reduce paths to package names, and loop the build over just those packages.

Steps

  • Check out with fetch-depth: 0.
  • Diff against origin/<base> to list changed files.
  • Map paths to package dirs and build each.

Workflow

.github/workflows/ci.yml
jobs:
  scoped:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - run: |
          BASE="origin/${{ github.base_ref || 'main' }}"
          PKGS=$(git diff --name-only "$BASE"... -- packages \
            | cut -d/ -f2 | sort -u)
          for p in $PKGS; do
            echo "Building packages/$p"
            pnpm --filter "./packages/$p" run build
          done

Gotchas

  • Use three-dot base... to diff against the merge base, not the literal base tip.
  • A shallow clone has no merge base; fetch-depth: 0 is required for a correct diff.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →