Lesson 2 of 7 · 22m
GitHub Actions Anatomy: Events, Jobs, Runners
The three-level model — workflow triggers, parallel jobs, sequential steps — and the YAML structure behind every CI file you've seen.
GitHub Actions' model is three nested levels: workflows trigger on events, jobs run in parallel on separate runners, steps run sequentially inside a job. Everything else — caching, matrices, secrets — hangs off that skeleton.
A real workflow, annotated
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, cache: npm }
- run: npm ci # lockfile install — reproducible
- run: npm run lint
- run: npm teston: chooses events — push and pull_request cover 95% of CI needs. Each job gets a fresh VM (runs-on); jobs in one workflow run in parallel by default. Steps share the job's filesystem — a file written in step 3 exists in step 5.
The pieces that confuse people
uses:steps run someone else's action — pin to a major version (@v4), notmain, for supply-chain sanity.npm cinotnpm install— lockfile-driven, fails on drift;npm installcan silently update.env:exists at workflow/job/step level — step-level scoping limits secret sprawl.if: failure()andif: always()— steps run conditionally; cleanup steps needalways().
Field notes
- Job names show up in branch protection — name them like they'll be required checks.
workflow_dispatch:adds a manual trigger for ops tasks (deploy, rebuild).- One failing step fails the job;
continue-on-errormarks specific steps advisory — use for flaky external services, not tests.