2.2 Scheduled & Manual Triggers: schedule, workflow_dispatch, and repository_dispatch
Key Takeaways
- The schedule trigger executes workflows using standard 5-field POSIX cron syntax in UTC timezone, operating exclusively from the default repository branch.
- High runner demand at the top of the hour can introduce scheduling delays; staggering cron schedules to non-peak minutes improves execution timeliness.
- The workflow_dispatch trigger enables manual and programmatic execution from the UI, CLI, and REST API, supporting typed inputs including string, boolean, choice, and environment.
- The repository_dispatch trigger enables external systems to initiate workflows via the GitHub REST API (POST /repos/{owner}/{repo}/dispatches) with custom event_type filters and JSON client_payload data.
- Scheduled workflows are automatically disabled after 60 days of repository inactivity on public and private repositories if no commits occur.
Scheduled & Manual Triggers: schedule, workflow_dispatch, and repository_dispatch
While code events (push and pull_request) automate verification during development, production systems also require deterministic time-based automation and on-demand manual triggers. GitHub Actions fulfills these requirements through three specialized trigger mechanisms:
schedule: Automated recurring workflows driven by POSIX cron expressions.workflow_dispatch: Parameterized manual or API-driven workflows triggered by users or CLI tooling.repository_dispatch: External webhook triggers initiated by external third-party services and microservices.
1. The schedule Trigger Architecture
The schedule event allows workflows to run at scheduled intervals using standard POSIX cron syntax.
The 5-Field POSIX Cron Syntax
GitHub Actions uses standard 5-field cron notation formatted as strings:
┌───────────── minute (0 - 59)
│ ┌───────────── hour (0 - 23, in UTC)
│ │ ┌───────────── day of the month (1 - 31)
│ │ │ ┌───────────── month (1 - 12 or JAN - DEC)
│ │ │ │ ┌───────────── day of the week (0 - 6 or SUN - SAT, 0 = Sunday)
│ │ │ │ │
* * * * *
on:
schedule:
# Runs at 04:15 UTC every Monday through Friday
- cron: '15 4 * * 1-5'
# Runs at 00:00 UTC on the 1st of every month
- cron: '0 0 1 * *'
Critical Scheduling Rules & Exam Points
- Strict UTC Timezone: All cron schedules are evaluated in Coordinated Universal Time (UTC). GitHub Actions does not support local timezones or Daylight Saving Time offsets. Workflow authors must convert local operational windows to UTC.
- Default Branch Requirement: Scheduled workflows are registered and executed exclusively from the default branch (e.g.,
mainormaster). If a workflow with ascheduletrigger is committed to a feature branch, GitHub Actions will not schedule or execute it. - Minimum Execution Interval: The shortest supported interval is once every 5 minutes. Configuring shorter intervals will be throttled or rejected.
- Queueing Delays During Peak Load: Scheduled runs do not guarantee execution at the exact second. High global demand—especially at the top of the hour (
:00)—often causes runs to queue for several minutes before a runner becomes available. Best Practice: Offset your cron schedules to arbitrary minutes (e.g.,'17 3 * * *'instead of'0 3 * * *'). - 60-Day Inactivity Disablement: In public and private repositories, if there has been no commit activity for 60 days, GitHub automatically disables all scheduled workflows. To re-enable them, an authorized user must manually enable them in the Actions tab or push a new commit.
Common POSIX Cron Patterns
| Cron Expression | Schedule Description | Typical Use Case |
|---|---|---|
'0 2 * * *' | Every day at 02:00 UTC | Nightly security scanning & builds |
'15 3 * * 1-5' | Mon–Fri at 03:15 UTC | Weekday dependency vulnerability check |
'0 */4 * * *' | Every 4 hours | Continuous integration artifact cleanup |
'30 23 * * 0' | Every Sunday at 23:30 UTC | Weekly compliance report generation |
'0 0 1,15 * *' | 1st and 15th of every month at midnight UTC | Bi-weekly billing metric aggregation |
2. The workflow_dispatch Trigger & Parameterized Inputs
The workflow_dispatch event allows users to execute workflows manually from the GitHub Web UI, the GitHub CLI (gh), or programmatically via the REST API. It allows workflow authors to define custom input parameters with explicit validation.
Input Data Types and Attributes
Inputs are defined under on.workflow_dispatch.inputs. GitHub Actions supports four distinct input types:
string: Standard textual input.boolean: Rendered as a graphical checkbox in the UI. Resolves to a booleantrue/false.choice: A dropdown selection restricted to a predefined list ofoptions.environment: A dropdown allowing the user to select an existing GitHub Deployment Environment configured in the repository.
name: Manual Production Deployment
on:
workflow_dispatch:
inputs:
target_environment:
description: 'Select deployment target environment'
required: true
type: environment
default: 'staging'
version_tag:
description: 'Semantic version tag (e.g., v1.4.0)'
required: true
type: string
log_level:
description: 'Application logging verbosity'
required: true
type: choice
default: 'info'
options:
- debug
- info
- warn
- error
dry_run:
description: 'Perform a dry run deployment without applying changes'
required: true
type: boolean
default: false
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ inputs.target_environment }}
steps:
- name: Display Parameters
run: |
echo "Deploying Version: ${{ inputs.version_tag }}"
echo "Target Environment: ${{ inputs.target_environment }}"
echo "Log Level: ${{ inputs.log_level }}"
echo "Dry Run Mode: ${{ inputs.dry_run }}"
- name: Execute Deployment
if: ${{ inputs.dry_run == false }}
run: ./scripts/deploy.sh --env ${{ inputs.target_environment }} --tag ${{ inputs.version_tag }}
Accessing Inputs in Workflows
Inputs can be referenced through two contexts:
- Modern Syntax:
${{ inputs.<input_id> }}(Recommended for consistency and type preservation). - Event Payload Syntax:
${{ github.event.inputs.<input_id> }}(Legacy format where boolean inputs are represented as strings'true'or'false').
Triggering via GitHub CLI and REST API
Workflows can be launched programmatically using the GitHub CLI:
gh workflow run deploy.yml \
-f target_environment=production \
-f version_tag=v2.1.0 \
-f log_level=info \
-f dry_run=false
Or using the GitHub REST API:
POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches
Host: api.github.com
Authorization: Bearer <PAT_OR_APP_TOKEN>
Content-Type: application/json
{
"ref": "main",
"inputs": {
"target_environment": "production",
"version_tag": "v2.1.0",
"log_level": "info",
"dry_run": "false"
}
}
3. The repository_dispatch Trigger & External Integrations
The repository_dispatch event allows external systems—such as external CI servers, monitoring alerts, CMS platforms, or third-party webhooks—to trigger workflows inside your repository by sending an HTTP POST request to the GitHub REST API.
REST API Endpoint and Payload Structure
External systems must send a POST request to:
https://api.github.com/repos/{owner}/{repo}/dispatches
Authentication Requirement: The request requires an authentication token (Personal Access Token with repo scope or a GitHub App with Actions: write and Metadata: read permissions).
{
"event_type": "order-service-deployed",
"client_payload": {
"service_name": "order-api",
"version": "3.4.1",
"environment": "production",
"initiator": "devops-orchestrator"
}
}
Workflow Filtering by event_type
A single repository can have multiple workflows listening for repository_dispatch. To prevent every workflow from running on every webhook, filter by types:
name: External Deploy Verification
on:
repository_dispatch:
types: [order-service-deployed, user-service-deployed]
jobs:
run-smoke-tests:
runs-on: ubuntu-latest
steps:
- name: Inspect Payload
run: |
echo "Triggered by Event: ${{ github.event.action }}"
echo "Service: ${{ github.event.client_payload.service_name }}"
echo "Version: ${{ github.event.client_payload.version }}"
echo "Target Env: ${{ github.event.client_payload.environment }}"
- name: Execute End-to-End Integration Suite
run: ./scripts/e2e.sh --target ${{ github.event.client_payload.service_name }}
Comparison of Manual & External Triggers
| Trigger Type | Initiator | Parameter Passing | Security Context |
|---|---|---|---|
schedule | Internal GitHub Cron Service | None (fixed schedule) | Runs on default branch with default repository permissions |
workflow_dispatch | Web UI, GitHub CLI, or REST API | Typed inputs (inputs.*) | Runs on selected branch with actor's caller identity |
repository_dispatch | External Webhook / Third-party API | Arbitrary JSON (client_payload.*) | Runs on default branch by default with repository permissions |
A DevOps team configures a workflow to run automated database maintenance. The workflow file is committed to a feature branch named feature/db-maintenance with the trigger schedule: - cron: '0 2 * * *'. However, the workflow never executes at 02:00 UTC. What is the root cause of this behavior?
An engineer configures a workflow_dispatch trigger with a boolean input named run_integration_tests. In a job step if: conditional, what is the correct syntax to evaluate whether the user checked the box?
A deployment microservice needs to trigger a GitHub Actions workflow in a private repository upon receiving an event from a payment provider. Which API endpoint and payload structure must the microservice call?