GitHub Actions: CI/CD Workflows From First Run to Secure Deployments · GitHub Actions Workflows: Triggers, CI and Matrices
Triggers and Filters: Choosing When Workflows Run
Control which pushes, pull requests, schedules and manual runs start a workflow, using branch, tag and path filters.
What you'll build
A workflow that runs tests on pushes to main, on pull requests, nightly, and on demand, while ignoring changes that only touch documentation.
The idea
Running every workflow on every event wastes minutes and clutters pull requests, so on: supports filters:
push/pull_requestwithbranches,tagsandpaths(and their-ignoreforms).schedulewith a cron expression, always evaluated in UTC.workflow_dispatchadds a Run workflow button and can define typedinputs.release,issues,workflow_calland many more.
Filters combine with AND: a push must match the branch filter and the path filter. For pull requests, branches refers to the target branch. Paths use glob patterns such as src/** and !docs/**.
The code
name: CI
on:
push:
branches: [main]
paths-ignore:
- "docs/**"
- "**.md"
pull_request:
branches: [main]
schedule:
- cron: "0 3 * * *" # every night at 03:00 UTC
workflow_dispatch:
inputs:
debug:
description: Print extra diagnostics
type: boolean
default: false
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run the tests
run: echo "Running tests (debug=${{ inputs.debug }})"
Output
actionlint: no problems found workflow: CI triggers: push (branches: main), pull_request (branches: main), schedule (cron '0 3 * * *'), workflow_dispatch jobs, in the order they run: test: runs on ubuntu-latest | 2 step(s)
Run this on your computer — see “Get Started” for setup.
Common mistakes
- Using
pathsandpaths-ignoretogether for the same event. GitHub allows only one of them per event; use!patterns insidepathsinstead. - Thinking
scheduleuses your time zone. It is UTC, and it only runs from the default branch. - Required checks skipped by path filters. If a required status check never runs because of a path filter, the pull request waits forever. Use a lightweight always-running job for required checks.
- Expecting
pull_requestto run for a branch conflict. A pull request with merge conflicts does not startpull_requestworkflows.
Key points
on:selects events;branches,tagsandpathsfilter them.- Cron schedules are UTC and run on the default branch.
workflow_dispatchgives a manual button and typed inputs.- Filters on one event are combined with AND. Further reading: GitHub Docs.
Practice questions
A push to a feature branch changes only `README.md`. Does the workflow above run?
Answer
No. The push trigger is limited to the main branch, and Markdown files are ignored. Only pushes to main that change something other than docs or Markdown start it.
Why can a path filter block a pull request from merging?
Answer
If a required status check's workflow is skipped by a path filter, the check never reports a result and stays pending, so the pull request can't satisfy the branch protection rule.
Open in the app to mark lessons complete, take notes and track your progress.