Run tests and checks automatically on every push with GitHub Actions — understand workflows, jobs, and steps, and read a real CI workflow file line by line.
Why: GitHub Actions runs your commands automatically when something happens in the repo — most commonly, running your tests and linter on every push and pull request. This is "CI" (Continuous Integration): catching broken code before it merges. Note: it is free for public repos and has a generous free tier for private ones.
Workflows are YAML files that live in a special folder:
mkdir -p .github/workflowsA repo can have many workflow files; each one describes WHEN to run and WHAT to do. GitHub finds and runs them automatically — there is nothing to install. The next topics build one up step by step.
Why: every workflow has the same three layers. A workflow is the whole file; it contains one or more jobs (which run on fresh virtual machines, in parallel by default); each job is a list of steps (single commands or reusable "actions"). Understanding these three words is most of Actions.
Workflow the whole .yml file — triggered "on" some event (a push, a PR)Job a task that runs on a fresh machine (e.g. "build-and-test")Step one thing the job does — run a command, or "use" a prebuilt action"Actions" (like actions/checkout) are reusable steps the community shares, so you don't reinvent common tasks such as checking out your code.
Why: this file runs on every push and pull request. It checks out your code, installs Node and dependencies, then runs your linter and tests — so a broken change shows a red ✗ on the PR before anyone merges it. Note: save it as .github/workflows/ci.yml and GitHub picks it up automatically on your next push.
name: CI
# WHEN: run on pushes to main and on every pull request
on:
push:
branches: [main]
pull_request:
jobs:
build-and-test:
runs-on: ubuntu-latest # a fresh Linux machine for each run
steps:
- uses: actions/checkout@v4 # copy your repo onto the machine
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm # cache deps so later runs are faster
- run: npm ci # install exactly what the lockfile pins
- run: npm run lint
- run: npm testWhy: every run shows up under the repo's "Actions" tab and as a green check or red cross on the commit and PR. When something fails, you open the run, expand the failing step, and read the logs — the same output you would see in your own terminal. Note: pair this with branch protection (previous lesson) to block merging until checks pass.
Watch the latest run for the current branch from the terminal
gh run watchList recent runs and view the logs of a failed one
gh run listgh run view --log-failedIn the browser: repo → "Actions" tab → click a run → expand a step.