GitHub Actions Tutorial — Schedule & Dispatch

3 minute read

Schedule & Dispatch Triggers

Not all workflows are triggered by code changes. The schedule trigger runs workflows at specific times using cron syntax, while workflow_dispatch lets you trigger workflows manually with custom parameters.


Schedule Trigger

The schedule trigger runs your workflow on a cron schedule. This is ideal for:

  • Nightly builds and integration tests
  • Weekly dependency updates
  • Periodic health checks
  • Scheduled reports

Cron Syntax

┌─── minute (0–59)
│ ┌─── hour (0–23, UTC)
│ │ ┌─── day of month (1–31)
│ │ │ ┌─── month (1–12)
│ │ │ │ ┌─── day of week (0–6, Sun=0)
│ │ │ │ │
* * * * *

Examples

on:
  schedule:
    # Every day at midnight UTC
    - cron: '0 0 * * *'

    # Every Monday at 9am UTC
    - cron: '0 9 * * 1'

    # Every 6 hours
    - cron: '0 */6 * * *'

    # First day of every month
    - cron: '0 0 1 * *'

Common Cron Patterns

Schedule Cron Expression
Every day at midnight 0 0 * * *
Every 6 hours 0 */6 * * *
Every Monday at 9am UTC 0 9 * * 1
Weekdays at 8am UTC 0 8 * * 1-5
First of every month 0 0 1 * *
Every 15 minutes */15 * * * *

Important Notes

  • All times are UTC — not your local timezone
  • Minimum interval: 5 minutes (GitHub may delay or skip runs during high load)
  • Scheduled runs only from the default branch (usually main)
  • GitHub may disable scheduled workflows in repos with no activity for 60 days

Nightly Build Example


name: Nightly Build

on:
  schedule:
    - cron: '0 2 * * *'     # 2am UTC daily

jobs:
  nightly:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run build
      - run: npm test


Workflow Dispatch (Manual Trigger)

We introduced workflow_dispatch in Getting Started. Here’s a deeper look at advanced input types and patterns.

Trigger with Multiple Input Types


name: Deployment

on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'Target environment'
        required: true
        type: choice
        options:
          - development
          - staging
          - production
      version:
        description: 'Release version (e.g., v2.1.0)'
        required: true
        type: string
      skip-tests:
        description: 'Skip test suite?'
        required: false
        default: false
        type: boolean

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.inputs.version }}

      - name: Run tests
        if: github.event.inputs.skip-tests != 'true'
        run: npm test

      - name: Deploy
        run: |
          echo "Deploying ${{ github.event.inputs.version }}"
          echo "Target: ${{ github.event.inputs.environment }}"


Repository Dispatch (External Trigger)

The repository_dispatch trigger lets external systems trigger workflows via the GitHub API:


name: External Deploy

on:
  repository_dispatch:
    types: [deploy]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - run: |
          echo "Triggered by: ${{ github.event.client_payload.environment }}"
          echo "Version: ${{ github.event.client_payload.version }}"

Trigger it from any HTTP client:


curl -X POST \
  -H "Accept: application/vnd.github.v3+json" \
  -H "Authorization: token $GITHUB_PAT" \
  https://api.github.com/repos/owner/repo/dispatches \
  -d '{
    "event_type": "deploy",
    "client_payload": {
      "environment": "production",
      "version": "v2.1.0"
    }
  }'


Combining Schedule with Other Triggers


name: CI + Nightly

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 2 * * *'
  workflow_dispatch:

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm test

      - name: Extended tests (nightly only)
        if: github.event_name == 'schedule'
        run: npm run test:e2e

This runs quick tests on every push/PR, plus extended end-to-end tests during nightly runs.


Common Mistakes

Mistake Fix
Schedule never triggers Schedules only run on the default branch; push the workflow file to main
Schedule runs in wrong timezone All cron times are UTC; convert from your local timezone
Too-frequent schedule Minimum interval is 5 minutes; GitHub may throttle shorter intervals
Repo disabled scheduled workflows GitHub disables schedules after 60 days of inactivity; make any commit to re-enable

Quick Reference

Trigger Use Case Key Detail
schedule Cron-based automation UTC only, default branch only
workflow_dispatch Manual with inputs UI button or API call
repository_dispatch External system trigger API only, custom payload

← Previous: Branch & Path Filtering

Next: Release Events →

Updated: