How runs are created and executed

GitHub Actions · Expert · 12 min

Understanding the execution model explains puzzling behaviour like edits not taking effect or runs that never start.

When an event arrives, GitHub reads .github/workflows/ at a specific commit, which depends on the event: the pushed commit for push, the PR merge commit for pull_request, the default branch for schedule, workflow_dispatch defaults and pull_request_target. That is why a fix to a scheduled workflow only matters once merged to the default branch, and why pull_request_target uses the base branch's trusted copy.

Each matching workflow becomes a run with a run_id, a run_number and an attempt count for re-runs. GitHub evaluates the job graph: jobs whose needs are met and whose job-level if is true are queued; matrices are expanded into individual jobs at that point, which is why a matrix can depend on an earlier job's output.

A queued job waits for a runner matching its runs-on labels. Hosted runners are limited by your plan's concurrent job quota; self-hosted ones by how many are online. A job with no matching runner waits up to 24 hours before failing.

On the runner, the runner application downloads all referenced actions first (so a broken uses: fails before any step), then executes steps, streaming logs back. Limits to remember: jobs run at most 6 hours on hosted runners, workflow runs at most 35 days, and re-running failed jobs reuses the same commit and workflow definition.

Example

# Inspect runs and attempts with the GitHub CLI
gh run list --workflow ci.yml --limit 3
# STATUS  TITLE        WORKFLOW  BRANCH  EVENT         ID
# ✓       Fix parser   CI        main    push          123456789
gh run view 123456789 --log-failed     # only the failing steps' logs
gh run rerun 123456789 --failed        # new attempt, same commit and YAML
gh workflow run deploy.yml -f environment=staging   # workflow_dispatch
gh run watch                            # follow a run live

Remember

  • The workflow file is read at the event's commit (default branch for schedule)
  • Matrices expand when a job becomes ready, so they can use earlier outputs
  • Re-runs reuse the original commit and workflow definition

Watch out for

  • Editing a workflow and re-running an old run, expecting the edit to apply.

Check yourself

  1. You fix a bug in a workflow on a feature branch, then re-run last night's failed scheduled run. Does it use the fix?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.github.com/en/actions/about-github-actions/understanding-github-actions