After this lesson, you will be able to: Use GitHub Actions in depth: triggers, jobs, steps, runners, matrix builds, and reusable workflows.
GitHub Actions is the default CI/CD platform for most new projects. This lesson covers the surface area you'll use daily.
A workflow is YAML in `.github/workflows/*.yml`. Workflow has triggers (when to run), jobs (parallel units of work), steps (commands within a job). Each job runs in a fresh ephemeral VM (the runner). Jobs share state via `needs:` (dependency) + artifact upload/download.
The common patterns. See docs.github.com/actions for the full list.
on:push:branches: [main]paths: ['src/**', 'package.json'] # only when these changepull_request:schedule:- cron: '0 6 * * *' # daily 06:00 UTCworkflow_dispatch: # manual button in GitHub UIinputs:env:type: choiceoptions: [staging, production]workflow_call: # callable from other workflows
Lint + test in parallel, then build (depends on both).
name: CIon:pull_request:push:branches: [main]concurrency:group: ci-${{ github.ref }}cancel-in-progress: truepermissions:contents: readpull-requests: writejobs:lint:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- uses: actions/setup-node@v4with: { node-version: 20, cache: npm }- run: npm ci- run: npm run linttest:runs-on: ubuntu-lateststrategy:matrix:node: [18, 20, 22]fail-fast: falsesteps:- uses: actions/checkout@v4- uses: actions/setup-node@v4with: { node-version: ${{ matrix.node }}, cache: npm }- run: npm ci- run: npm test -- --runbuild:needs: [lint, test]runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- uses: actions/setup-node@v4with: { node-version: 20, cache: npm }- run: npm ci && npm run build- uses: actions/upload-artifact@v4with:name: distpath: dist/
A matrix expands one job into many parallel runs across one or more dimensions. Common dimensions: language versions (node 18/20/22, python 3.10/3.11/3.12), OS (ubuntu/macos/windows), test shard (split tests across N runs). `fail-fast: false` (recommended) keeps running the other matrix entries even if one fails, so you see ALL failures.
Reusable workflow: a workflow callable from another (`uses: ./.github/workflows/release.yml`). Share entire pipelines. Composite action: a step bundle (a 'mini-action' in `.github/actions/foo/action.yml`). Share groups of steps. Both let you DRY across many repos in your org without copy-paste.
Skipping `concurrency:` cancel-in-progress. A 30-commit push runs 30 workflows; only the last matters. Forgetting `permissions:`. Modern GitHub defaults are read-only; jobs that need write access (deploys, releases) must declare them explicitly. Reinventing actions you can buy off-the-shelf. actions/checkout, actions/setup-node, docker/build-push-action are vetted and fast. Workflows that take 30 min. Cache aggressively, parallelize jobs, shard tests. Echoing secrets to logs. GitHub auto-masks SECRETS named ones, but `echo $SECRET` to stdout leaks if the var isn't a secret.
Pick the highest-leverage diagnostic.
Sign in and purchase access to unlock this lesson.