Week 5 (Capstone): GitHub Actions & Team Workflows

The last piece: automating everything you've learned so far. This week writes a real GitHub Actions workflow, wires up branch protection so nothing merges without passing checks, and ends with the capstone — a CI pipeline running on an actual repository, the same shape you'd find protecting main at almost any real company.

Module 5 of 5 Week 5 of 5 ~3–4 Hours Capstone Project

By the end of this week, you'll be able to

  • Write a GitHub Actions workflow that runs on every push and pull request
  • Protect main with required status checks and review rules
  • Ship a working CI pipeline end to end on a real repository

1. GitHub Actions: Your First Workflow

GitHub Actions runs scripts automatically in response to repo events — pushes, pull requests, schedules and more. A workflow is a YAML file in .github/workflows/; each one defines when it runs and what jobs to execute:

.github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

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

Commit and push this file, and GitHub picks it up automatically — check the "Actions" tab on the repo to watch it run. uses: steps run a reusable published action (like actions/checkout, which fetches your repo's code onto the runner); run: steps execute a plain shell command.

2. Workflow Triggers, Jobs & Matrix Builds

Workflows can respond to far more than pushes — issues, releases, a schedule, or a manual button click:

.github/workflows/nightly.yml (excerpt)
on:
  schedule:
    - cron: "0 3 * * *"    # 3 AM UTC, every day
  workflow_dispatch:        # adds a manual "Run workflow" button

A matrix build runs the same job multiple times with different variables — the standard way to test against several language or OS versions in parallel:

.github/workflows/ci.yml (excerpt)
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18, 20, 22]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci
      - run: npm test
    # This spins up THREE parallel jobs -- one per Node version.

3. Branch Protection & Required Checks

A workflow that merely runs isn't enough — it needs to actually block a bad merge. In the repo's Settings → Branches → Branch protection rules, add a rule for main:

  • Require a pull request before merging — no more direct pushes to main.
  • Require status checks to pass before merging — select your CI job (e.g. test) by name; GitHub greys out the merge button until it succeeds.
  • Require approvals — at least one reviewer must approve before merge is allowed.
  • Require branches to be up to date before merging — forces a rebase/merge with main first, so the tested code is actually what gets merged.
This is the single change that matters most

Everything from Weeks 1–4 — commits, branches, PRs, CI — only actually protects main once a branch protection rule makes the checks mandatory. Without it, a passing or failing check is just informational and can be merged past.

4. Releases, Tags & Changelogs

A GitHub Release wraps a tag (from Week 4) with release notes and optional built artifacts, giving users a clear "this is version X" page to look at:

terminal
git tag -a v1.0.0 -m "First stable release"
git push origin v1.0.0
gh release create v1.0.0 --title "v1.0.0" --generate-notes
# --generate-notes auto-builds a changelog from merged PRs since the last release

gh is the GitHub CLI — it wraps common GitHub actions (PRs, issues, releases) as terminal commands, useful for scripting things this course has otherwise done through the web UI. It's worth installing alongside Git itself.

5. Capstone: Ship a CI Pipeline for a Real Repo

Bring every piece of this course together on one real repository — this is the project the whole 5 weeks has been building toward.

Capstone

Automate and protect a small project, end to end

Use any small project (or start a fresh one) — a few dozen lines of code with a couple of automated tests is enough.

Requirements:

  1. Push the project to a new public GitHub repo with a clear README.
  2. Add a GitHub Actions workflow that installs dependencies and runs the tests on every push and pull request.
  3. Enable branch protection on main: require a PR, require your CI job to pass, and require at least one review approval (self-approval is fine solo).
  4. Open a feature branch with an intentionally failing test, push it, and open a PR — confirm the merge button is blocked by the failing check.
  5. Fix the test, push the fix to the same branch, and confirm the check turns green and the PR becomes mergeable.
  6. Merge the PR, then tag the resulting commit as v1.0.0 and publish a GitHub Release from it.
You now have the exact loop used at most real companies

Branch → commit → push → PR → CI check → review → merge → tag → release. Every course elsewhere on this site assumes this loop as background knowledge — you've now actually built it once, end to end, yourself.

6. Bonus Exercise

Hands-on

Add a matrix build and a manual trigger

Extend your capstone workflow beyond the minimum requirements.

Requirements:

  1. Add workflow_dispatch to your workflow's on: block so it can also be triggered manually from the Actions tab.
  2. Add a strategy.matrix that runs your test job against at least two different runtime versions.
  3. Confirm in the Actions tab that the matrix produces separate, parallel job runs.

7. Knowledge Check

Four quick questions. Expand each to check your answer.

Q1

Where do GitHub Actions workflow files live, and what format are they written in?

In .github/workflows/ at the repo root, as YAML files. GitHub automatically discovers and runs any workflow file it finds there once it's committed and pushed — no separate registration step is needed.

Q2

A CI check is failing on a PR, but there's no branch protection rule set up. Can the PR still be merged?

Yes. A workflow running and reporting pass/fail is purely informational unless a branch protection rule explicitly marks that check as required. Without that rule, the merge button stays available regardless of whether checks are red or green.

Q3

What does a matrix build actually do?

It runs the same job multiple times in parallel, once per combination of values listed under strategy.matrix — commonly different language/runtime versions or operating systems — so you get separate pass/fail results for each combination instead of testing against only one environment.

Q4

What's the relationship between a Git tag and a GitHub Release?

A tag is a plain Git object marking a specific commit with a fixed name (e.g. v1.0.0) — it exists at the Git level with or without GitHub. A GitHub Release wraps a tag with a human-facing page: release notes, a changelog, and optional downloadable build artifacts, all built on top of that tag.