Episode 3 β Workflow Syntax & Events (push, PR, cron & manual)
In the previous episodes, we covered:
- what CI/CD is
- the core building blocks of GitHub Actions
Now itβs time to answer one of the most important questions:
When does a GitHub Actions workflow actually run?
The answer lies in the on: section β events and triggers.
The Role of on: in a Workflow
Every workflow has two responsibilities:
- WHEN to run
- WHAT to run
The on: keyword controls WHEN.
on: push
This single line already means:
βRun this workflow whenever someone pushes code.β
1οΈβ£ The push Event
The push event triggers when commits are pushed to a repository.
Basic example:
on: push
This runs on:
- every branch
- every push
Restricting push to specific branches
on:
push:
branches:
- main
- develop
This is commonly used for:
- deployments
- protected branches
- production workflows
2οΈβ£ The pull_request Event (Very Important)
The pull_request event runs before code is merged.
on:
pull_request:
branches: [main]
This is ideal for:
- linting
- testing
- validation checks
Why pull_request matters
Pull requests represent untrusted code.
Thatβs why:
- secrets are blocked
- permissions are restricted
This makes PR workflows safe by default.
3οΈβ£ push vs pull_request (Key Difference)
| Event | When it runs | Typical use |
|---|---|---|
pull_request |
Before merge | CI (tests, lint) |
push |
After push | Build / deploy |
Best practice:
on:
pull_request:
branches: [main]
push:
branches: [main]
- PR β CI
- Merge β CD
4οΈβ£ Path Filters (Run Only When Needed)
Path filters let you run workflows only when certain files change.
Run only when frontend changes:
on:
push:
paths:
- "src/**"
- "package.json"
Ignore documentation changes:
on:
push:
paths-ignore:
- "README.md"
- "docs/**"
This is extremely useful in:
- monorepos
- large codebases
5οΈβ£ Manual Trigger β workflow_dispatch
Sometimes you want a Run workflow button.
on:
workflow_dispatch:
This allows:
- manual deployments
- retrying workflows
- controlled releases
workflow_dispatch with inputs
on:
workflow_dispatch:
inputs:
environment:
description: "Deployment environment"
required: true
default: "staging"
Usage:
run: echo "Deploying to ${{ github.event.inputs.environment }}"
6οΈβ£ Scheduled Workflows β cron
GitHub Actions supports time-based scheduling using cron syntax.
on:
schedule:
- cron: "0 2 * * *"
This means:
- Every day
- At 02:00 UTC
Common use cases:
- nightly tests
- cleanup jobs
- dependency checks
β οΈ Cron always uses UTC timezone.
7οΈβ£ Combining Multiple Triggers
A real-world workflow usually has multiple triggers:
on:
pull_request:
branches: [main]
push:
branches: [main]
workflow_dispatch:
This gives you:
- automatic CI on PRs
- automatic CD on merge
- manual control when needed
8οΈβ£ Event Context (Quick Intro)
Each event exposes metadata via the github context.
Examples:
github.event_name
github.ref
github.actor
github.sha
Debugging example:
- run: echo "Triggered by ${{ github.actor }}"
Weβll explore this deeper in a later episode.
Common Mistakes to Avoid π¨
β Deploying on every push (no branch filter)
β Using secrets in PR workflows
β Forgetting timezone differences in cron
β Over-triggering workflows unnecessarily
Good triggers are:
- intentional
- minimal
- predictable
Final Mental Model
Event happens
β
GitHub checks `on:`
β
Workflow runs
If you control on:, you control your pipeline.
Whatβs Next?
π Episode 4:
Runners, Actions & Marketplace β Where and How Your Code Runs
Weβll answer:
- where jobs actually run
- what runners are
- how marketplace actions work
Follow the series if youβre building real confidence with GitHub Actions π
Thanks for reading!
Happy automating π
Top comments (0)