Building a Lightweight CI/CD Pipeline Using GitHub Actions for Monorepos (2026)

Step-by-step tutorial to configure lightning-fast, cost-effective GitHub Actions CI/CD pipelines for Turborepo and npm monorepos using path filters and dependency caching.

Monorepos housing frontend web apps, backend APIs, and shared documentation libraries offer tremendous developer velocity. However, naive CI/CD workflows run full test and build suites on every single pull request—wasting precious GitHub Actions minutes and frustrating teams with 25-minute build queues.

By orchestrating Turborepo remote caching and GitHub's paths-filter action, engineers execute builds exclusively for packages that actually changed, reducing pipeline durations down to under 90 seconds.

Pipeline Optimization Benchmark

Deploying granular path triggers cuts GitHub Actions runner billing by up to 75% while providing instantaneous feedback on pull requests.

1. Complete Workflow YAML (.github/workflows/deploy.yml)

name: Monorepo Production CI/CD

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  detect-changes:
    name: Detect Changed Workspaces
    runs-on: ubuntu-latest
    outputs:
      web: ${{ steps.filter.outputs.web }}
      api: ${{ steps.filter.outputs.api }}
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            web:
              - 'apps/web/**'
              - 'packages/ui/**'
              - 'package.json'
            api:
              - 'apps/api/**'
              - 'packages/database/**'
              - 'package.json'

  build-web:
    needs: detect-changes
    if: ${{ needs.detect-changes.outputs.web == 'true' }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: 'npm'

      - name: Install Dependencies
        run: npm ci

      - name: Build Web Application
        run: npm run build --workspace=apps/web

  build-api:
    needs: detect-changes
    if: ${{ needs.detect-changes.outputs.api == 'true' }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: 'npm'

      - name: Install Dependencies
        run: npm ci

      - name: Run Database Tests & API Build
        run: npm run build --workspace=apps/api

2. Key Acceleration Tactics

  • Dependency Caching: Always pass cache: 'npm' or pnpm to actions/setup-node@v4.
  • Cancel Outdated PR Runs: Use concurrency: { group: ${{ github.ref }}, cancel-in-progress: true } to auto-abort older builds when new commits are pushed.