Chapter 03Lesson 03~115 minutes

Events, Triggers, Filters, Schedules, Manual Runs, and Repository Dispatch: Configuration, Design Patterns, and Trade-Offs

Trigger design is policy design. A narrow trigger can save compute but remove visibility; a broad trigger can simplify required checks but create noisy runs. Manual and custom dispatch solve different trust problems, and schedules solve different orchestration problems from event-driven automation. This lesson turns those distinctions into explicit design choices.

Design patternsBroad vs narrowDispatch choicesSchedulesTrust context

Learning objectives

  • Choose between trigger-level filters and job-level conditions based on visibility, required checks, and cost.
  • Compare broad and narrow event subscriptions without confusing event activity with job execution.
  • Choose between workflow_dispatch, repository_dispatch, and schedule based on caller identity and dataflow.
  • Reason about push versus pull_request as different trust and revision contexts.
  • Document trigger decisions as governed interfaces with testable examples and rollback paths.

1. Trigger configuration is an interface contract

Every on block defines who or what may request automation, what repository state is associated with the request, and which events are silently ignored. That means trigger changes deserve the same review discipline as API changes: identify callers, accepted input shape, trust assumptions, expected side effects, and how a breaking change will be detected.

2. Broad versus narrow triggers

Design Strength Risk/trade-off Good fit
Broad trigger Consistent run/check visibility across changes More runs and possible cost/noise Required CI where every PR should show a result
Narrow trigger filters Prevents irrelevant runs entirely Can leave no run/check for unmatched changes Independent optional automation or clearly scoped monorepo component
Broad trigger + job if Run exists; expensive work can skip More orchestration overhead; conditions need care Required check plus selective heavy jobs

There is no universal “optimize paths” rule. If branch protection requires a check that never appears because the workflow was filtered out, a compute optimization can become a merge-blocking reliability problem.

3. Branch filters and job conditions operate at different layers

# Trigger-level: may prevent run creation entirely
on:
  push:
    branches: [main]
    paths: ['app/**']

# Job-level: run exists, but job can be skipped
jobs:
  app-test:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-24.04
    steps:
      - run: echo 'test app'

Use trigger filters when the workflow itself is irrelevant. Use job conditions when the run is still valuable evidence but only some work should execute. Chapter 04 will go deeper into expression evaluation; this chapter stays focused on the selection boundary.

4. workflow_dispatch versus repository_dispatch

Question workflow_dispatch repository_dispatch
Primary caller Human or automation intentionally starting a named workflow External system emitting a repository-level custom event
Input contract Declared typed workflow inputs event_type + custom client_payload
Ref choice Caller can select a ref for the run after default-branch workflow presence requirement is met Event context uses default branch ref/tip
Best fit Operator-controlled maintenance/test/release request External service says “event X happened”
Governance concern Who may dispatch; input validation; selected ref Who may call API; event-type contract; untrusted payload handling

Do not use repository_dispatch merely because it sounds more “API-like.” If the intent is “run this workflow with these declared parameters,” workflow_dispatch provides a clearer typed workflow contract.

5. Schedule versus external orchestration

Native schedules are excellent for repository-local periodic work that can tolerate GitHub Actions scheduling semantics. They are less suitable for hard real-time requirements, complex calendars spanning many systems, or workflows that must coordinate with external business state.

Need Prefer Why
Nightly repo maintenance with minutes of timing tolerance schedule Simple, versioned with workflow, no external scheduler.
Run after an external batch actually finishes repository_dispatch or purpose-built API call Event expresses real completion rather than guessing clock time.
Cross-system calendar with strict SLA External orchestrator Central timing/retry/monitoring can own the contract.

Scheduled workflows currently run from the latest default-branch commit. If your business requirement is “run version 1.4 every night even after main changes,” schedule alone does not express that immutable version policy.

6. Push versus pull request is also a trust decision

push to a protected branch generally represents code that has already crossed repository review/merge policy. A pull_request run may execute code proposed by a contributor, including from a fork. Secrets and token behavior are intentionally restricted in low-trust contexts. The trigger is therefore not just “when”; it contributes to “who controls the code being executed.”

Security boundary: do not move privileged mutation/deployment logic onto pull_request_target simply to regain secrets or write permissions. That event uses a trusted base context and requires specialized threat modeling; Chapter 22 covers it in depth.

7. Design patterns that survive growth

  • Stable event contract: name custom repository_dispatch event types as versioned interfaces when external clients depend on them.
  • Visible required CI: prefer a broad PR trigger plus selective jobs when branch protection expects a consistent check.
  • Manual safety valve: use typed workflow_dispatch inputs for operator-controlled retries or dry runs instead of editing workflow YAML for one-off behavior.
  • Clock tolerance: document that schedule time is approximate and avoid top-of-hour bursts when exact timing is unnecessary.
  • Ref intent: state whether PR work should validate merge result, head SHA, or base branch and record that choice.

8. Worked decision table

Scenario Trigger design Prerequisite/trust Observable proof
Every PR must show a required CI result; docs changes need no tests Broad pull_request; condition heavy jobs Untrusted PR-safe jobs only Run exists for docs PR; heavy job skipped; required summary/check present
External QA service finishes a synthetic test repository_dispatch with named event type Authorized API caller; payload treated as untrusted Event type/payload fields + default-branch run ID
Maintainer wants an on-demand diagnostic on a selected branch workflow_dispatch typed inputs Workflow present default branch; write-capable caller Selected ref, typed input values, run ID
Weekday dependency report schedule at off-peak minute Workflow on default branch; timing tolerance Schedule string, event, default-branch SHA, actual start timestamp
Next lesson

Diagnostics and failure modes

Turn “why didn't it run?” into an evidence-first decision tree instead of editing triggers blindly.

Knowledge check

When is a trigger-level path filter better than a job if?

Why is workflow_dispatch often clearer than repository_dispatch for operator actions?

A nightly job must start within seconds of midnight. Is native schedule a sufficient contract?

Why is a PR trigger also a trust decision?

What should you record when deliberately testing the PR head rather than the merge result?

Official references and version notes

Version and compatibility note

Version-sensitive trigger behavior was rechecked against current primary GitHub documentation on 2026-09-09. Executable labs use a disposable repository, ubuntu-24.04, built-in shell steps only, and explicit permissions: {} because no repository API mutation is required from inside the workflow. At verification time, workflow_dispatch, repository_dispatch, and schedule require the workflow file to exist on the default branch; scheduled workflows run from the latest default-branch commit, support POSIX cron plus an optional IANA timezone, and have a minimum five-minute interval but may be delayed under load. GitHub is continuously delivered, so event payload fields, limits, schedule behavior, and default-branch rules must be rechecked before long-lived production use. Plan/visibility differences can affect protected environments and other later features, but the trigger-design exercises here require only standard repository Actions functionality.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.