Advanced

Setting up your first automated workflow

GitHub Actions runs scripts in your repository automatically, in response to events like a push or a pull request. It can run tests, build your app, or deploy it wherever you like. Once you write a workflow file, the work repeats itself on every relevant change, no one has to remember to run it by hand.

What you will see

Every push now runs npm test automatically A red mark means someone should look before merging

About 2 min of reading

Quick check

Before this new lesson, one small question about the lesson you just finished. Recall it, do not look it up.

Try It

I used to run tests by hand before every merge, then forgot once and shipped something broken. Let me write my first workflow file that runs the tests automatically on every push, so the pipeline does the work and a red mark on the PR does the catching.

1

First, make sure your project has something to run. A workflow only works if there is a test or build command it can invoke. Check the package.json for a test script so you know what to put in the workflow.

Get-Content package.json | Select-String -Pattern "scripts" -Context 0,4

Before you run it, say out loud what it will print. Then open the answer.

What it prints
"scripts": { "test": "npm run build && node run-tests.js", "build": "node build.js" }
If there is no test script, your workflow has nothing to run. Add one to package.json before you write a workflow, or the pipeline will pass without checking anything.
2

Create the workflow file in .github/workflows/. The name is a label you read later, the on line is the trigger that starts it, and the job runs on a fresh machine every time. This is the smallest possible automation: run the tests whenever someone pushes.

New-Item -ItemType Directory -Force -Path .github/workflows iyam @" name: CI on: [push] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm test "@ | Out-File -FilePath .github/workflows/ci.yml -Encoding utf8

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Directory: C:Usersadamyapp.github
The on line fires on a push to every branch. If you want it to run only on pull requests, list pull_request instead, so tests do not run for every stray commit.
3

Push the workflow file. GitHub reads it automatically and runs the job on its first push, so there is nothing to deploy or configure. The test job runs on a fresh machine, checks out the code, then runs npm test.

git add .github/workflows/ci.yml git commit -m "Add CI workflow" git push

Before you run it, say out loud what it will print. Then open the answer.

What it prints
[main abc1234] Add CI workflow 1 file changed, 7 insertion(+) Everything up-to-date
The workflow file must be committed to the branch you push. If you forget to commit it, GitHub has no file to read and nothing runs, the red X never appears.
4

Open the Actions tab and watch it run. The first run shows the job, the steps, and a green or red result. If npm test passed, every step is green. If it failed, the last step is red and you can click it to see exactly which test failed, no need to run it by hand yourself.

gh workflow view ci.yml

Before you run it, say out loud what it will print. Then open the answer.

What it prints
CI job: test status: success steps: 2 of 2 succeeded
A failed step shows the error in the logs, not just a red mark. Read the failing step before you assume the code is broken, a wrong test command is a broken workflow, not a broken app.
5

Now the tests run on every push without anyone remembering. If a future push breaks the tests, that red mark on the PR shows before the merge, and it is enough to make someone investigate first. The work repeats itself; you only have to react when it turns red.

echo "Every push now runs npm test automatically" echo "A red mark means someone should look before merging"

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Every push now runs npm test automatically A red mark means someone should look before merging
Automation only helps if you actually respond to it. A red mark you ignore is worse than no automation at all, because it gives you a false sense that something was checked.

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

A trigger starts a workflow, it runs its jobs and steps, then reports the result.
1 Event fires
↓
2 Start the job
↓
3 Run the steps
↓
4 Report the result
Why this works
Triggers

A workflow starts when an event fires, a push, a pull request, a schedule. Set the trigger so it runs exactly when it needs to; a wrong trigger is the most common reason an automation seems to 'not work'.

Jobs and steps

A job runs on a machine and is made of steps. Each step is a command. One workflow can have many jobs, and they can even run in parallel, which is useful when you have independent things to test.

Examples

Making tests run on every push

name: CI
on: [push]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm test

Now every push runs npm test, and if it fails the pull request shows a red X. Nobody remembers to run tests and nobody forgets, the pipeline does it. That red mark on a PR is usually enough to make someone investigate before they merge.

Testing across several versions at once

jobs:
  test:
    strategy:
      matrix: [node-18, node-20, node-22]
    runs-on: ubuntu-latest
    steps:
      - run: npm test

Apps often need to run on several platforms, and checking each one by hand is tedious. A matrix lets a single job run them all at once. The report shows exactly which version passed and which failed, so you can chase the specific problem.

Jobs that run on a clock

name: Nightly
on:
  schedule:
    - cron: '0 2 * * *'
jobs:
  backup:
    runs-on: ubuntu-latest
    steps:
      - run: echo "Running backup"

The 0 2 * line means every day at 2 AM. Great for backups, reports, or checking for stale issues while the lights are off. Some jobs should simply run on a schedule, and cron makes that trivial.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← How teams actually stay in sync
Previous Lesson
How teams actually stay in sync
Next Lesson
Giving feedback people actually respond to
Giving feedback people actually respond to →