Building a Pipeline with GitHub Actions
GitHub Actions is GitHub's built-in CI/CD system: workflows defined as YAML files living right in your repository, triggered automatically by events like a push or pull request.
Anatomy of a workflow
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- run: npm test
ondefines the triggers, here, every push tomainand every pull request.jobsis a set of independent units of work, each runs on a fresh runner (a temporary VM,ubuntu-latesthere).stepsrun in order within a job, each is either a shell command (run:) or a reusable action (uses:), a packaged, shareable step someone else already wrote.
Reusable actions
actions/checkout@v4 and actions/setup-node@v4 are official actions maintained by GitHub, checkout clones your repo onto the runner (without it, the runner starts with an empty filesystem), setup-node installs a specific Node.js version. The GitHub Marketplace has thousands of community actions for almost anything (deploying to a cloud provider, sending a Slack notification, scanning for vulnerabilities).
Multiple jobs and dependencies
jobs:
test:
runs-on: ubuntu-latest
steps: [...]
deploy:
needs: test
runs-on: ubuntu-latest
steps: [...]
needs: test makes the deploy job wait for test to succeed first, and skips deploy entirely if test fails. Jobs without a needs relationship run in parallel by default, useful for running lint, unit tests, and type-checking simultaneously to get feedback faster.
TIP
Keep your CI fast. A pipeline people are used to waiting 15 minutes for gets ignored or worked around, one that takes 90 seconds gets checked every time, run independent jobs in parallel, and cache dependencies (next lesson) wherever you can.