GitHub Actions: CI/CD that scales with your repo
Sep 12, 2025•
githubactionscicd
• 0
Why GitHub Actions
GitHub Actions lets you automate everything that happens after a commit: linting, tests, builds, security checks, and deployments. It runs close to your code, integrates with the PR experience, and scales from small repos to large monorepos.
Core concepts (90‑second refresher)
- Workflow: A YAML file in
.github/workflows/
that describes triggers and jobs. - Job: Runs on its own VM/runner. Jobs can run in parallel or sequence.
- Step: A command or an action inside a job.
- Action: A reusable function (e.g.,
actions/checkout@v4
). - Secrets/Vars: Store credentials and configuration safely.
Minimal CI for a TypeScript/Next.js project
name: CI
on:
pull_request:
push:
branches: [ main ]
jobs:
build:
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
- run: npm run build
Fast builds with caching
- Use
actions/setup-node
withcache: npm
orpnpm
. - Cache build artifacts you can reuse (e.g., Turbo or Nx caches) to speed up PRs.
Secrets and environments
Keep credentials out of code:
- Add secrets under GitHub → Repo → Settings → Secrets and variables → Actions.
- Reference them in workflows using
${{ secrets.MY_SECRET }}
.
Example: expose a key to a step without echoing it in logs:
- name: Run script with secret
env:
SERVICE_KEY: ${{ secrets.SERVICE_KEY }}
run: node scripts/secure-task.js
Example: Auto-apply database migrations with Supabase
This repo includes a workflow that applies SQL migrations in supabase/migrations/**
whenever you push to main
. Set two repository secrets:
SUPABASE_ACCESS_TOKEN
– Create in Supabase (Account → Access Tokens)SUPABASE_PROJECT_REF
– Your project ID (Project settings)
Workflow (excerpt):
name: Supabase Migrations
on:
push:
branches: [ main ]
paths: [ 'supabase/migrations/**' ]
jobs:
apply:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: supabase/setup-cli@v1
with:
version: latest
- name: Link & push
env:
SUPABASE_ACCESS_TOKEN: ${{ secrets.SUPABASE_ACCESS_TOKEN }}
SUPABASE_PROJECT_REF: ${{ secrets.SUPABASE_PROJECT_REF }}
run: |
supabase link --project-ref "$SUPABASE_PROJECT_REF"
supabase db push --include-all
Deploy tips
- Use separate workflows for CI (fast checks) and CD (deploy after CI passes).
- Protect
main
with required checks to keep production stable. - Add a preview environment for PRs; deploy only when PR is approved.
Common pitfalls and fixes
- Long installs → cache dependencies and use
npm ci
. - Flaky tests → run retries on a smaller subset, isolate network calls.
- Secret leaks → never print secrets; set
ACTIONS_STEP_DEBUG
only in a temporary environment. - Monorepo complexity → use path filters to run jobs only for changed packages.
Checklist
- Lint, type-check, unit tests on PRs
- Build artifacts cached
- Secrets configured in GitHub
- Database migrations automated
- Preview deploys for PRs
With a few YAML files and disciplined secrets management, Actions gives you a fast, reliable pipeline that grows with your team.