Triggers

The Events That Trigger a Workflow

The on key lists the events that start a run, each with optional filters:

The on: block of fundamentals.ymlYAML
on:
  push:
    branches: [main]
    paths: ["**.js", "db/**", ".github/workflows/fundamentals.yml"]
  pull_request:
    branches: [main]
  workflow_dispatch:
    inputs:
      genre: {type: choice, options: [Cooking, Fiction, Travel], default: Cooking}
      runner: {type: string, default: ubuntu-24.04}
      break-syntax: {type: boolean, default: false}

push fires for pushes to main that change JavaScript, the database files or this workflow; pull_request when a pull request into main is opened, updated or reopened. workflow_dispatch adds a Run workflow button with a form of up to 25 inputs, which the gh 29 CLI can fill:

Starting fundamentals.yml by hand, then listing its latest runsYAML
gh workflow run fundamentals.yml -f genre=Fiction -f runner=ubuntu-26.04
gh workflow run fundamentals.yml -f break-syntax=true
gh run list -w fundamentals.yml -L 4 --json event,headBranch,conclusion,databaseId \
  --jq '.[] | "\(.databaseId)  \(.event)  \(.headBranch)  \(.conclusion)"'
Output
https://github.com/binarybehemoth/booknest/actions/runs/36130306874
https://github.com/binarybehemoth/booknest/actions/runs/36130315657
36130315657  workflow_dispatch  main  failure
36130306874  workflow_dispatch  main  success
36130254896  push  main  success
36130170320  pull_request  ci/compact-fundamentals  success

Two rules answer most "why didn't it run?" questions: workflow_dispatch, schedule and many other events use only the default branch's workflow file, and events caused by a run's own GITHUB_TOKEN start no new runs (except dispatch events, and pull requests it opens, whose runs wait for approval), so a committing workflow cannot loop.