The on key lists the events that start a run, each with optional filters:
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:
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.