Skip to main content
CI/CD

Setting Up CI/CD with GitHub Actions

A step-by-step guide to building a robust CI/CD pipeline with GitHub Actions — from linting and testing to preview deployments and production releases.

Author

Robert Baker

Published

Read time

2 min read

A good CI/CD pipeline catches bugs before they reach production and automates the tedious parts of deployment. GitHub Actions makes this straightforward with YAML-based workflows that live alongside your code.

A Production-Ready Pipeline

Here’s the workflow structure we use on most projects:

# .github/workflows/ci.yml
name: CI

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

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: oven-sh/setup-bun@v2
        with:
          bun-version: latest

      - run: bun install --frozen-lockfile
      - run: bun run typecheck
      - run: bun run lint
      - run: bun run test

This runs on every push and pull request, ensuring code quality stays consistent.

Key Pipeline Stages

1. Install Dependencies

Always use a lockfile to ensure reproducible builds:

bun install --frozen-lockfile   # Bun
npm ci                          # npm
pnpm install --frozen-lockfile  # pnpm

2. Type Checking

Catch type errors before they become runtime bugs. Run tsc --noEmit or your framework’s typecheck command.

3. Linting

Enforce code style and catch common mistakes. We use oxlint for speed — it’s 50-100x faster than ESLint for the checks it supports.

4. Testing

Run your full test suite. In monorepos, use Turborepo to run tests in parallel across packages:

bun turbo run test

5. Build

Verify the project actually compiles. Build artifacts can be uploaded for deployment:

- run: bun run build
- uses: actions/upload-artifact@v4
  with:
    name: dist
    path: dist/

Preview Deployments

Every pull request should get a preview URL. Cloudflare Pages and Vercel do this automatically, but you can set it up manually:

deploy-preview:
  if: github.event_name == 'pull_request'
  needs: quality
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - run: bun install --frozen-lockfile
    - run: bun run build
    - name: Deploy Preview
      run: npx wrangler pages deploy dist --branch=${{ github.head_ref }}

Caching for Speed

Cache dependencies to cut CI time by 60-80%:

- uses: actions/cache@v4
  with:
    path: ~/.bun/install/cache
    key: bun-${{ runner.os }}-${{ hashFiles('bun.lockb') }}
    restore-keys: bun-${{ runner.os }}-

Branch Protection Rules

CI is only useful if you enforce it. Configure branch protection on main:

  • Require status checks to pass before merging
  • Require pull request reviews
  • Require branches to be up to date before merging
  • Do not allow bypassing the above settings

Secrets Management

Never hardcode secrets. Use GitHub’s encrypted secrets:

env:
  DATABASE_URL: ${{ secrets.DATABASE_URL }}
  API_KEY: ${{ secrets.API_KEY }}

Rotate secrets regularly and use environment-specific secrets for staging vs production.

Monitoring Your Pipeline

Track these metrics over time:

  • CI duration — should stay under 5 minutes for most projects
  • Flaky test rate — investigate any test that fails intermittently
  • Deploy frequency — healthy teams deploy multiple times per day

A well-tuned CI/CD pipeline is one of the highest-leverage investments you can make in your development workflow.

Need help setting up your pipeline? →

Topics covered CI/CDGitHub ActionsDevOpsTestingAutomation
Need dev help?

Get expert development help fast

Our engineering team turns complex ideas into production-ready software tailored to your business.

Book a consult
Next up

Continue leveling up your engineering skills

Dive deeper with related guides chosen to complement this topic and accelerate your next project.

Stay connected

Get engineering insights every week

Subscribe for framework updates, architecture patterns, and deep dives tailored to busy engineering teams.

Subscribe to Our Newsletter

Get tech tips, special offers, and updates delivered to your inbox.