Triggers
Triggers fire workflows. The four worth knowing: push to a branch / tag, pull_request, schedule (cron), and manual dispatch. Filter paths and branches to keep CI cheap.
GitHub Actions trigger recipes
EXAMPLE
# .github/workflows/ci.yml
name: CI
# Multiple triggers — runs on ALL matching events
on:
# 1) Push to specific branches + tags
push:
branches:
- main
- 'release/**'
tags:
- 'v*.*.*'
paths-ignore:
- '**.md'
- 'docs/**'
# 2) PRs targeted at main, when interesting files change
pull_request:
branches: [main]
types: [opened, synchronize, reopened, ready_for_review]
paths:
- 'src/**'
- 'package*.json'
- '.github/workflows/**'
# 3) Scheduled (cron — UTC, NEVER your local time)
schedule:
- cron: '0 6 * * 1-5' # 06:00 UTC Mon-Fri
# 4) Manual — appears as a 'Run workflow' button
workflow_dispatch:
inputs:
environment:
description: 'Target env'
required: true
default: 'staging'
type: choice
options: ['staging', 'production']
dry_run:
type: boolean
default: true
# 5) Repository event-only triggers
issues:
types: [opened]
jobs:
test:
# 'if' lets you filter per-job too
if: github.event_name != 'schedule' || github.repository == 'me/app'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: echo "event=${{ github.event_name }} ref=${{ github.ref }}"
- run: echo "env=${{ inputs.environment || 'unknown' }}"
# Tips
# • paths-ignore: docs-only changes shouldn't run the full pipeline
# • types: filter PR events so you don't re-run on every label change
# • concurrency: cancel-in-progress avoids stacked CI on rapid pushes
Why it matters
Cron in CI is UTC. The most common mistake: scheduling “9 am” in local time and being surprised when DST shifts the run. Convert intentionally; document the timezone in a comment.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
# GitHub Actions
on:
push:
branches: [main]
pull_request:
schedule:
- cron: '0 6 * * *'
workflow_dispatch:
Try it Yourself »
Discussion
Loading…