Code of the Day
AdvancedCI/CD for Automation

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.

WorkflowAdvanced6 min read
By the end of this lesson you will be able to:
  • 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 actions

A 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 daily

Scheduled 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.

Finished reading? Mark it complete to track your progress.

On this page