GitHub Actions basics
A GitHub Actions workflow is a YAML file that runs jobs on triggers — understand workflows, triggers, jobs, and steps before writing your first automation.
- Identify the four-level hierarchy of a GitHub Actions workflow file — workflow, trigger, job, step
- Read a simple YAML workflow file and explain what it does
- Understand the triggers relevant to automation — push, schedule, workflow_dispatch
GitHub Actions runs your code automatically in response to events: a push, a pull request, a scheduled cron expression, or a manual button click. For automation pipelines, it provides a free, hosted, version-controlled runner environment that is already integrated with your repository.
The four-level hierarchy
A workflow file lives at .github/workflows/<name>.yml in your repository. It has
four levels:
workflow ← the whole file
on: (triggers) ← when does it run?
jobs: ← what groups of work?
steps: ← individual commands or actionsA real file:
# .github/workflows/lint.yml
name: Lint
on:
push:
branches: ["main"]
pull_request:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Check out source
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install ruff
run: pip install ruff
- name: Run linter
run: ruff check .Triggers
The on: key controls when the workflow runs.
push fires on every push to the listed branches. Omitting branches fires
on pushes to any branch:
on:
push:
branches: ["main", "release/*"]pull_request fires when a PR is opened, synchronised (new commit pushed), or
reopened. This is the standard gate for CI checks.
schedule runs on a cron expression in UTC:
on:
schedule:
- cron: "0 3 * * *" # 03:00 UTC dailyScheduled workflows do not run on the runner's clock — they are queued by GitHub at the scheduled time and may start up to a few minutes late under load.
workflow_dispatch adds a "Run workflow" button in the GitHub UI and enables
gh workflow run from the CLI:
on:
workflow_dispatch:
inputs:
environment:
description: "Target environment"
required: true
default: "staging"
type: choice
options: ["staging", "production"]Inputs are passed as environment variables to the workflow and visible in the run log — essential for audit trails.
Jobs and runners
A job is a set of steps that run sequentially on the same runner. Jobs within a
workflow run in parallel by default; use needs: to express dependencies:
jobs:
test:
runs-on: ubuntu-latest
steps: [...]
deploy:
needs: test # waits for test to succeed before starting
runs-on: ubuntu-latest
steps: [...]runs-on: ubuntu-latest provisions a fresh Ubuntu VM for each job. The VM is
destroyed when the job completes — nothing persists between runs unless you use
artifact uploads or a cache action.
actions/checkout@v4 is almost always the first step in every job. Without it,
the runner has an empty workspace — your repository files are not present by
default.
Where to go next
Next: running Python in CI — a complete workflow that sets up Python, installs requirements from a cache, and runs your pipeline script.
Lab: containerise a pipeline
Write a Dockerfile and compose.yaml for the hardened pipeline from Module 1, run it with Docker Compose, and verify that output files appear on the host filesystem.
Running Python in CI
Write a GitHub Actions workflow that sets up Python, installs requirements with pip caching, and runs your pipeline script on every push and on a daily schedule.