How do GitHub Actions workflow triggers work beyond basic push and pull_request events, and how do you use workflow_dispatch and repository_dispatch for manual and API-triggered pipelines?
Quick Answer
GitHub Actions supports over 35 event triggers. workflow_dispatch enables manual runs with custom inputs from the UI or CLI, while repository_dispatch accepts external API calls with custom event types and payloads. Combined with schedule (cron) and workflow_call (reusable workflows), these triggers enable sophisticated automation patterns like ChatOps, cross-repo orchestration, and scheduled maintenance tasks.
Detailed Answer
Think of workflow triggers like different ways to ring the doorbell at a smart home. A push event is the regular doorbell button that visitors press (code is pushed). A pull_request event is the intercom call (someone requests entry via PR). A schedule trigger is the automated sprinkler system that runs at set times. A workflow_dispatch is the homeowner pressing a button on their phone to manually open the garage. And repository_dispatch is the delivery driver using a special API code to signal that a package has arrived, triggering the home to unlock the delivery box. Each trigger serves a different initiation pattern.
Beyond push and pull_request, GitHub Actions supports triggers like schedule (cron-based, runs on the default branch), workflow_dispatch (manual trigger with typed inputs), repository_dispatch (API-triggered with custom payloads), workflow_call (invoked by other workflows), release (when releases are published), deployment (when deployments are created), issues and issue_comment (for bot automation), and many more. Each trigger provides different context in the github event payload. The workflow_dispatch trigger is particularly useful because it allows defining input parameters (string, boolean, choice, environment) that appear as a form in the GitHub Actions UI. When triggered via gh workflow run or the API, these inputs are passed as part of the request, enabling parameterized pipeline runs like deploying a specific version to a specific environment.
The repository_dispatch trigger is designed for external system integration. Any system with a GitHub token can POST to /repos/{owner}/{repo}/dispatches with a custom event_type string and a client_payload JSON object. Your workflow file listens for specific event types: on: repository_dispatch: types: [deploy-request, rollback-request]. The client_payload is accessible as github.event.client_payload in the workflow, passing arbitrary data from the external system. This enables patterns like a Slack bot triggering deployments (ChatOps), a monitoring system triggering rollbacks when alerts fire, or an upstream service triggering downstream rebuilds when it publishes a new artifact. Unlike workflow_dispatch, repository_dispatch has no built-in UI form; it is purely API-driven.
In production, these advanced triggers enable sophisticated automation. Acme Corp's SRE team uses workflow_dispatch for manual deployment with environment and version choice inputs, allowing on-call engineers to deploy specific versions to specific environments from the Actions tab without touching code. They use repository_dispatch for their ChatOps pipeline: a Slack slash command /deploy checkout-service v2.3.1 production hits an API gateway that calls GitHub's dispatch endpoint, triggering the deployment workflow. A schedule trigger runs nightly at 2 AM to perform integration tests against staging, database backup verification, and dependency vulnerability scans. The workflow_run trigger chains workflows: when the build workflow completes successfully, it triggers the deploy workflow, keeping them as separate files for clarity and reusability.
A critical gotcha with schedule triggers is that they only run on the default branch (usually main). If you add a cron workflow on a feature branch, it will not execute until that branch is merged to main. Also, scheduled workflows may be delayed during periods of high GitHub Actions load and are disabled automatically if the repository has no activity for 60 days (no commits, issues, or PRs). For repository_dispatch, the gotcha is that the POST request requires a token with repo scope, which is a broad permission. Use a fine-grained personal access token or GitHub App token scoped to only the contents permission to minimize security exposure. For workflow_dispatch, remember that choice inputs are not validated on the API side; the validation only appears in the UI, so API callers can pass any value, and your workflow should validate inputs explicitly.