A good pipeline turns "it works on my machine" into "it works because the pipeline proved it." Each stage gates the next, so a failure stops the line before bad code reaches production.
The stage flow
graph LR;
A[Push] --> B[Lint];
B --> C[Test];
C --> D[Build];
D --> E[Deploy to staging];
E --> F[Deploy to production];A workflow definition
Jobs run in order, and a red stage blocks everything downstream:
name: CI
on: [push]
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: pnpm install
- run: pnpm lint
- run: pnpm test
- run: pnpm buildFail fast, fail cheap
Order stages from quickest to slowest. Linting takes seconds and catches the silly mistakes before a multi-minute test suite even starts:
pnpm lint && pnpm test --bailCache the slow parts
Cache dependencies and build output keyed on the lockfile so unchanged installs are near-instant. CI minutes add up fast otherwise.
Promote, do not rebuild
Build the artifact once and promote the same one through staging to production. Rebuilding per environment invites drift.
A reusable deploy job
A deploy job with environment protection rules:
Keep stages ordered, fast feedback first, and ship the exact artifact you tested.