Advanced

GitHub Actions basics

GitHub Actions is the most popular CI tool. It runs workflows stored in your repo. Learn how to write a workflow file by hand.

What you will see

Deploy step environment: production API_TOKEN: injected from vault, not in log Secret exposed in log: No

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

A workflow is a YAML file in the repo that says what triggers it and lists a job of steps. On every push it checks out code, installs dependencies, and runs tests, then reports a single green or red result that reviewers see before merging.

1

I run a workflow by hand on a push: check out the code, install requirements, run the test suite, and print the single result so it is clear the pipeline passed end to end.

print("GitHub Actions basics") print("Trigger: on push") print("Runs on: ubuntu-latest") steps = ["actions/checkout@v4", "pip install -r requirements.txt", "pytest"] for i, s in enumerate(steps, 1): print("Step %d: %s" % (i, s)) print("Result: PASS")

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

What it prints
GitHub Actions basics Trigger: on push Runs on: ubuntu-latest Step 1: actions/checkout@v4 Step 2: pip install -r requirements.txt Step 3: pytest Result: PASS
A single workflow can hold several jobs. If one job or step fails, the others are red even if only the linter broke. Read the failing step, not just the verdict.
2

I add a second trigger so the pipeline runs on pull requests as well, and print that reviewers get a green check before merging.

print("Triggers: push (main), pull_request") print("Jobs: test") print("Result: green check before merging")

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

What it prints
Triggers: push (main), pull_request Jobs: test Result: green check before merging
A branch will never be mergeable with a failing job. Anyone pushing here should watch for the green check before opening a pull request.
3

I add a deploy step that points at the production environment and injects a secret from the vault instead of writing it in the file, and print that the secret never appears in the log.

print("Deploy step environment: production") print("API_TOKEN: injected from vault, not in log") print("Secret exposed in log: No")

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

What it prints
Deploy step environment: production API_TOKEN: injected from vault, not in log Secret exposed in log: No
The environment can require human approval before the job runs, and the secret value is only ever present in that one job, never in a build log for anyone to copy.

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 workflow file in the repo defines jobs and steps that run automatically on a trigger.
1 Define a trigger
↓
2 Add a job
↓
3 List steps
↓
4 Run on push
Why this works
The on keyword

The on keyword says what triggers the workflow. You can trigger on push, pull request, or a schedule.

Jobs and steps

A workflow has one or more jobs. Each job runs steps. Jobs can run in parallel. Steps run one after another.

Examples

A basic workflow file

name: CI
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pip install -r requirements.txt
      - run: pytest

This file runs on every push. It checks out your code, installs dependencies, and runs tests. That is a complete pipeline in a few lines.

Triggering on pull requests

name: PR check
on:
  pull_request:
  push:
    branches: [main]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pytest

Now the pipeline runs on a push and on every pull request. Reviewers see a green check before merging. That is how teams keep the main branch clean.

Adding an environment

      - name: Deploy
        run: npm run deploy
        env:
          API_TOKEN: ${{ secrets.API_TOKEN }}
        environment: production

The environment links the job to a named deployment. It can require approval and expose secrets safely. The secret never appears in the log.

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.

← Running your first pipeline
Previous Lesson
Running your first pipeline
Next Lesson
Speeding up pipelines
Speeding up pipelines →