Skip to content

Jobs, Steps, and Runners

A workflow is a tree: workflow → jobs → steps. Understanding how the levels relate — especially what runs where and in what order — prevents most confusion.

Jobs: parallel by default

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: ruff check .

  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pytest

Check (validated): lint and test run simultaneously on two separate VMs. Jobs don't share files, memory, or state — each is a fresh machine. Fast (parallel), but isolated.

Depending on another job

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - run: pytest

  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - run: ./deploy.sh

needs: test — deploy waits for test, and skips if test fails. This is the pipeline pattern: test → build → deploy, each gated on the last. (needs also accepts a list: needs: [lint, test].)

Steps: sequential within a job

steps:
  - name: Check out code
    uses: actions/checkout@v4

  - name: Run tests
    run: pytest -x -q

  - name: Upload report
    if: failure()
    uses: actions/upload-artifact@v4
    with:
      name: test-report
      path: report.xml

Steps run in order, on the same machine, sharing the filesystem. Each step gets a name (shown in the UI — write good ones, future you reads these logs). run: is a shell script; uses: borrows an action; with: passes it parameters; if: failure() runs a step only when earlier steps failed (see Debugging).

Runners: whose computer?

Runner What it is Cost
ubuntu-latest GitHub-hosted Linux VM Free minutes included
windows-latest GitHub-hosted Windows VM 2× minutes
macos-latest GitHub-hosted macOS VM 10× minutes
self-hosted Your own machine Your electricity

Public repos get generous free minutes; private repos on the free plan get 2,000/month (Linux minutes — Windows/macOS multiply). Self-hosted runners are for special hardware, private networks, or heavy use — powerful, but now you maintain the machine.

The mental model

workflow "CI"
├── job "lint"   → VM #1 → step → step → step
└── job "test"   → VM #2 → step → step → step   (parallel!)

Jobs are machines; steps are commands on one machine. When a workflow confuses you, ask: "which machine is this step on, and what's on its disk?" — the answer is usually "a fresh VM with only what previous steps in this job put there."

Next: The Marketplace