self-host →

Understanding GitHub Actions Triggers

Learn how to set up GitHub Action triggers for push, pull requests, scheduled events, and manual runs to streamline your CI/CD pipeline.

Today, we’re exploring one of the most powerful features of GitHub Actions: triggers. Triggers define when and why a workflow should start. Whether it’s pushing code, creating a pull request, or even scheduling tasks, knowing how to work with triggers is key to automating your workflows like a pro. Let’s dive in!

What are triggers in GitHub Actions?#

Triggers, or “events”, are specific activities in your GitHub repository that can start a workflow. These can range from code pushes, pull request actions, tag pushes, to even external events calling your GitHub Actions workflows.

The full list of events can be found at GitHub’s documentation.

Common GitHub Actions triggers#

  1. Push and pull requests: probably the most used triggers, they can automate testing, linting, or deployments based on code changes or proposed merges.

  2. Scheduled events: want to run a cleanup script every week or send out a report every day? Scheduled events let you run workflows at predefined times using cron syntax.

  3. Manual triggers: sometimes, you need to run a workflow on-demand, not automatically. GitHub Actions allows for manual workflow runs with the workflow_dispatch event.

Let’s explore how to implement each of these triggers in your workflows.

Setting up triggers: examples#

1. On push or pull request#

name: CI on Push and PR
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Run a script
run: echo "Running on push or pull request to main!"

This workflow triggers on push events or pull requests targeting the main branch. It’s perfect for running tests or builds to ensure your main branch stays healthy.

Note that for pull_request, the branches filter matches the base branch (the branch the PR wants to merge into), not the contributor’s source branch. So branches: [main] means “run for any PR opened against main”, regardless of where the changes come from.

2. Scheduled workflows#

name: Weekly Cleanup
on:
schedule:
- cron: "0 2 * * 0" # Runs at 2 AM every Sunday
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: Run cleanup script
run: echo "Performing weekly cleanup!"

The schedule trigger uses cron syntax to schedule when the workflow runs. This example triggers a workflow at 2 AM every Sunday, great for regular maintenance tasks.

A few important caveats about scheduled workflows:

  • The cron time is interpreted in UTC, not your local timezone.
  • Scheduled runs only execute on the workflow file as it exists on the repository’s default branch.
  • The shortest interval GitHub allows is once every 5 minutes, and runs can be delayed or skipped entirely during periods of high load — so never rely on schedule for precise, time-critical jobs.
  • A scheduled workflow is automatically disabled if there has been no commit activity in the repository for 60 days.

3. Manual trigger#

name: Deploy on Demand
on:
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Deploy script
run: echo "Deploying application!"

The workflow_dispatch trigger allows for manual execution. This flexibility is perfect for workflows that shouldn’t run automatically, like deploying to production. The trigger button will be available from the GitHub UI:

Workflow dispatch trigger

One thing that trips people up: the Run workflow button only appears once the workflow file exists on the repository’s default branch. You can also define typed inputs that are prompted for in the UI (and exposed via the inputs context):

name: Deploy on Demand
on:
workflow_dispatch:
inputs:
environment:
description: "Target environment"
required: true
default: staging
type: choice
options:
- staging
- production
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy script
run: echo "Deploying to ${{ inputs.environment }}!"

Seeing triggers in action#

Now that you’ve set up your workflows with different triggers, commit them to your repository and watch them in action. For scheduled and push/pull request triggers, they’ll run automatically as defined. For manual triggers, you can start them from the Actions tab of your repository by selecting the workflow and clicking “Run workflow”.

Wrap-up#

Triggers are the heartbeat of GitHub Actions, determining when and why your workflows run. Be careful to be specific with your triggers, as they can end up triggering a lot of GitHub Action runners, which are costly.

Note that you can also restrict which paths, branches, tags are allowed or ignored on push and pull_request events, which can be very useful to avoid wasting resources when you know there is nothing to be done. To stop redundant runs from piling up when you push to a PR several times in a row, reach for the concurrency keyword.

Next time, we’ll take a closer look at jobs and steps. See you then, and happy automating!