Your first workflow file

GitHub Actions · Essentials · 10 min

A build-and-test workflow on every change is the single most valuable thing Actions does for a project.

A workflow file has three top-level keys you will always write: name (optional label), on (the triggering events) and jobs.

Each job needs runs-on, the runner label, and steps. A typical CI job follows the same recipe in every language:

  • actions/checkout to clone the commit that triggered the run (the runner starts empty).
  • A setup-* action such as actions/setup-node or actions/setup-python to install a toolchain version.
  • run: steps to install dependencies, lint and test.

A run step executes in bash on Linux and macOS runners (with -e, so the first failing command fails the step) and in PowerShell on Windows. A multi-line command uses the YAML block scalar |. Any step that exits non-zero fails the job, marks the run red and, by default, skips the remaining steps.

Commit the file and push: the run appears under the Actions tab within seconds. With on: [push, pull_request] the result also shows up as a check on pull requests, and branch protection can require it to pass before merging.

Steps can be given a name for readable logs and a working-directory when the project lives in a subfolder. Keep CI workflows fast and boring: the same commands a developer runs locally, in the same order.

Example

name: CI
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-node@v7
        with:
          node-version: 22
      - name: Install
        run: npm ci
      - name: Lint and test
        run: |
          npm run lint
          npm test

Remember

  • Checkout, set up a toolchain, then run your commands
  • A non-zero exit code fails the step and the job
  • Use | for multi-line run scripts

Watch out for

  • Forgetting actions/checkout and wondering why the repository files are missing.

Check yourself

  1. A run step contains three commands on separate lines and the second one fails. What happens on a Linux runner?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.github.com/en/actions/writing-workflows/quickstart