2.1.1. Repository, Webhook, and Scheduled Events
💡 First Principle: Almost every activity GitHub records emits a webhook event, and Actions lets a workflow subscribe to essentially any of them — so the question is never "can I trigger on this?" but "which event, which activity type, and which filter expresses exactly the moment I mean?"
Start with the workhorses. push fires on commits reaching a ref, and its filters (branches, branches-ignore, tags, paths, paths-ignore) are how you stop a docs typo from rebuilding your container images. pull_request fires on PR activity, defaulting to the activity types opened, synchronize, and reopened — meaning a PR that is merely labeled won't trigger it unless you add types: [labeled]. That default set is a favorite exam detail: candidates assume "any PR activity" and pick the wrong answer.
Beyond those, issues, issue_comment, release, create, delete, fork, and watch cover repository lifecycle automation, each with its own activity types (release with published vs created vs prereleased is a recurring gotcha). For triggering from outside GitHub, repository_dispatch accepts a POST to the repository's dispatches endpoint with a custom event_type and a JSON client_payload your workflow reads through the github.event context — the standard answer whenever a scenario says "our ticketing system should kick off a run."
Scheduled runs use POSIX cron in the schedule: block:
on:
schedule:
- cron: '30 5 * * 1-5' # 05:30 UTC, Monday-Friday
push:
branches: [main]
paths-ignore: ['docs/**', '**.md']
repository_dispatch:
types: [deploy-requested]
The shortest supported interval is every 5 minutes, and GitHub explicitly warns that runs near the top of the hour are frequently delayed by load. Scheduled workflows are also disabled automatically after 60 days of repository inactivity, which explains "our nightly job just stopped running" scenarios on quiet repos.
⚠️ Exam Trap: Three properties of schedule: are tested constantly and independently: cron is UTC (never your local time, and never adjusted for daylight saving), scheduled workflows run only from the default branch (the version of the file on main, regardless of which branch defines it), and delivery is best-effort (delayed or dropped under load — never for time-critical work).
Reflection Question: A workflow subscribes to pull_request with no types: key and a teammate complains it doesn't run when they add the ready-for-review label. Nothing is broken — explain why, and give the one-line fix.