How GitHub Actions turns events into runs, drawn — a developer and a senior developer push, open a pull request, review and merge, and every event they make is read against three workflow files that start runners.
An event starts a run of every workflow file that accepts it, and each file's jobs then run on fresh machines.
on: names a file's events, and its filters narrow them down.- A job has no
on:, so dividing jobs by event means dividing them into files. if: on a job reads inside the event, where a filter cannot: an approval's state, a comment's text.- A runner is a fresh machine GitHub starts for one job, and deletes when the job ends.
Reading the drawing
- Runners, top left: one small computer per running job, showing the job's lines.
- The workflow files, under them: three YAML files side by side, a pane each, their parts told apart by tint.
- A line with ▸ has lines inside it, and a click opens or closes it.
- Collapse all leaves the three names; Expand all shows every line.
- Each step opens the lines it needs.
- GitHub, top right: the branches, the events, the pull request and the runs.
main is the long-running line, which runs on past the edge.- A topic branch forks from it, merges back through a pull request, and is deleted.
- The two people, bottom right: their buttons jump to each of their actions.
The three files
The story splits its four jobs by the events each one needs.
| File | Its events | Its jobs |
|---|
ci.yml | push to any branch, pull_request, schedule | test |
review.yml | pull_request_review, issue_comment | e2e |
deploy.yml | push to main, release, workflow_dispatch, repository_dispatch | build, then deploy |
The events in the story
| Event | What makes it | In these files |
|---|
push to a branch | a git push | ci.yml: test |
push to main | a merge | ci.yml: test; deploy.yml: build, deploy |
push of a tag | git push origin v1.4.0 | stopped: both filters name branches: only |
create | a new branch or tag | not named |
delete | a deleted branch or tag | not named |
pull_request opened, synchronize | opening one, or pushing to its branch | ci.yml: test |
pull_request review_requested, closed | asking for a review, merging | stopped by types: |
pull_request_review_comment | a comment on a line in a review | not named |
pull_request_review | submitting a review | review.yml: e2e when state is approved |
issue_comment | a comment on an issue or a pull request | review.yml: e2e on the text /e2e |
release published | publishing a release | deploy.yml, with an approval before deploy |
release created, released | the same action | stopped by types: |
schedule | GitHub's clock | ci.yml: test |
workflow_dispatch | the Run workflow button, or the API | deploy.yml |
repository_dispatch | a program calling the API | deploy.yml |
The events left out
| Event | What makes it |
|---|
workflow_run | another workflow was requested or finished, which lets one file follow another |
workflow_call | another workflow calls this one |
pull_request_target | the same activities as pull_request, run from the base branch's file with its secrets |
merge_group | a pull request entered a merge queue |
check_run, check_suite, status | checks and statuses on a commit |
deployment, deployment_status | deployments and their progress |
issues, label, milestone | issue tracking |
discussion, discussion_comment | discussions |
fork, watch, public, gollum, page_build, branch_protection_rule, registry_package | other repository activity |
- GitHub's
events reference
gives every event's activity types, and which commit and copy of the file each one uses.
- An event made with the job's own
GITHUB_TOKEN starts no new run, apart from workflow_dispatch and
repository_dispatch, so a workflow cannot start itself by accident.