Skip to content
Commitpedia
Log in Join & edit

A minimal GitHub Actions workflow that runs your tests

Add one YAML file under .github/workflows and GitHub runs your tests on every push and pull request. Here is a small, explained example for Node.js and one for Python.

Edit history of A minimal GitHub Actions workflow that runs your tests: 1 recorded edit
Edit history · 1 edit
Type
Article
Edits
1
Editors
1
First issued
15 Oct 2026
Last edit
15 Oct 2026
Reading
2 min

GitHub Actions runs jobs on GitHub’s machines when something happens in your repository. The most useful first job is continuous integration (CI): run the test suite on every push and every pull request, so a broken change shows a red mark before anyone merges it.

Create the workflow file

Workflows live in .github/workflows/ and can have any name ending in .yml. Create .github/workflows/ci.yml:

name: CI

on:
  push:
    branches: [main]
  pull_request:

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [22, 24]
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-node@v7
        with:
          node-version: ${{ matrix.node-version }}
          cache: npm
      - run: npm ci
      - run: npm test

Commit and push it. The run appears under the repository’s Actions tab, and on pull requests as a check next to the merge button.

What each part does

  • on: run on pushes to main and on every pull request.
  • permissions: contents: read: the job’s automatic token can read the code and nothing more. Granting only what a job needs limits the damage if a step misbehaves.
  • concurrency: if you push again while a run for the same branch is still going, the old run is cancelled.
  • runs-on: ubuntu-latest: a fresh Linux virtual machine for each run.
  • strategy.matrix: runs the job once per listed Node.js version, in parallel.
  • actions/checkout: copies your repository onto the machine. Without it the job has no code.
  • actions/setup-node: installs Node.js; cache: npm reuses downloaded packages between runs.
  • npm ci installs exactly what package-lock.json lists (the lock file must be committed), and npm test runs the test script from package.json. A non-zero exit code fails the job.

The same idea for Python

name: CI

on:
  push:
    branches: [main]
  pull_request:

permissions:
  contents: read

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-python@v7
        with:
          python-version: "3.13"
          cache: pip
      - run: pip install -r requirements.txt
      - run: python -m pytest

Quote version numbers such as "3.13". YAML reads an unquoted 3.10 as the number 3.1, which selects the wrong Python.

Version tags for actions

@v7 pins the action to a major version, which receives fixes but no breaking changes. Each action’s README lists its current major version; update the tag when a new one comes out. For extra safety, some teams pin to a full commit hash instead.

Make the check required

A red check alone does not stop anyone from merging. In the repository settings, add a branch ruleset (or a branch protection rule) for main that requires status checks to pass, and pick the test job. When you use a matrix, each version shows up as its own check.

When a run fails

  • Open the failed run and expand the red step; the log shows the same output you would see locally.
  • “Works on my machine” failures are often a missing committed file, such as a lock file, or a different runtime version. Match the matrix to what you use locally.
  • Use the Re-run jobs button for flaky network failures, but fix flaky tests rather than re-running them forever.

Start with this file, then add steps such as a linter or a build once the tests run green.

See also

  • 0256 Manage infrastructure as code with Terraform: from first file to plans on pull requests Learn the full Terraform workflow without a cloud account: variables, a module, outputs, state, plan, apply and destroy, a backend for shared… Beginner · Tutorial · Linux, macOS, Windows Article GitHub Actions · Terraform 15 Oct 2026

History

Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.

  1. commitpedia-admin +3,469 chars

Report a problem

Something wrong, unsafe or copied? Tell the editors.
What is wrong?