Skip to main content

Trigger

A CI/CD trigger is the event that starts a pipeline run. Common triggers include a Git push to a branch, a pull request opening, a scheduled cron expression, a manual dispatch, or a webhook from an external system like a monitoring alert.

Understanding CI/CD Triggers

What Is a Trigger in Simple Terms

A trigger is the alarm clock for your pipeline. Without a trigger, a pipeline sits idle forever — knowing what to run but waiting for a reason to run it. The trigger says: now is the time, this is the context, start the pipeline.

Different events should start different pipelines. A commit to a feature branch should run tests only. A merge to main should run tests, scan, and deploy to staging. A Git tag like v1.2.3 should deploy to production. Getting triggers right means the right automation runs at the right time.

How It Works

Bash
+------------------------------------------+
| Trigger Types |
| |
| push: git push to branch |
| -> run CI on the new commit |
| |
| pull_request: PR opened or updated |
| -> run tests, post status |
| |
| tag: git tag v1.2.3 pushed |
| -> deploy to production |
| |
| schedule: cron expression |
| -> nightly security scans |
| |
| workflow_dispatch: manual button click |
| -> run with custom inputs |
+------------------------------------------+

Complete trigger configuration (GitHub Actions):

YAML
on:
## Trigger on push to main and release branches
push:
branches:
- main
- 'release/**'
## Only trigger if these paths changed
paths:
- 'src/**'
- 'Dockerfile'
- '.github/workflows/**'
## Trigger on pull requests to main
pull_request:
branches:
- main
types: [opened, synchronize, reopened]
## Trigger on version tags
push:
tags:
- 'v*.*.*'
## Nightly security scan at 2 AM IST (8:30 PM UTC)
schedule:
- cron: '30 20 * * *'
## Manual trigger with inputs
workflow_dispatch:
inputs:
environment:
description: 'Target environment'
required: true
default: 'staging'
type: choice
options: [staging, production]
skip_tests:
description: 'Skip tests (emergency only)'
type: boolean
default: false

GitLab CI trigger rules:

YAML
deploy-production:
stage: deploy
script:
- ./deploy.sh production
## Only run on main branch tags, never on MRs
rules:
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
when: manual
- when: never

Practical Commands

Bash
## GitHub Actions -- trigger workflow manually
gh workflow run deploy.yaml \
--field environment=staging \
--field skip_tests=false
## GitHub Actions -- trigger via API
curl -X POST \
-H "Authorization: Bearer $GITHUB_TOKEN" \
https://api.github.com/repos/OWNER/REPO/actions/workflows/deploy.yaml/dispatches \
-d '{"ref":"main","inputs":{"environment":"staging"}}'
## Create a Git tag to trigger production deploy
git tag -a v1.2.3 -m "Release v1.2.3"
git push origin v1.2.3

Troubleshooting

Symptom Check What to Look For
Pipeline not triggering on push Branch name filter Exact branch name match
Trigger loop (pipeline triggers itself) Workflow permissions Use github.actor != 'github-actions' guard
Schedule not running Cron syntax Validate at crontab.guru
Tip

Use path filters on push triggers to avoid running the full pipeline when only documentation changes. paths: ['src/**', 'Dockerfile'] skips the pipeline when someone only edits a README — saving runner minutes and engineer attention.

Security

Be careful with pull_request_target trigger in GitHub Actions. It runs in the context of the base repository (has access to secrets) even for forks. An attacker can craft a malicious fork PR that exfiltrates secrets. Use pull_request (no secret access) for untrusted contributions and pull_request_target only when secret access is explicitly needed and the code is audited first.

Common Mistake

Triggering the full production deployment pipeline on every push to main instead of every merge. If your main branch allows direct pushes, each push triggers a deployment. This leads to many small deploys that are hard to track. Use branch protection rules to require PRs to main, so deployments only happen on deliberate merges.

Remember

Scheduled triggers only fire if the repository has had activity in the last 60 days on GitHub Actions. Inactive repositories have their scheduled workflows disabled automatically. If your nightly security scan stops running, check whether the repository was dormant and re-enable the schedule.

Frequently Asked Questions

Besides a Git push, what other trigger types actually matter in production pipelines?

Pull-request triggers run checks before merge without deploying anything; scheduled (cron) triggers run nightly builds, dependency scans, or drift-detection jobs independent of code changes; manual/workflow-dispatch triggers gate production deploys behind a human click; and external webhook triggers let systems outside the VCS — a monitoring alert, an upstream artifact registry publishing a new base image — kick off a pipeline. Each trigger type implies different assumptions about what state the pipeline should verify.

What's a common trigger misconfiguration that causes wasted CI minutes or accidental deploys?

Triggering the full pipeline (build, test, deploy) on every push to every branch, including feature branches with no intent to deploy — this burns CI minutes and, worse, can accidentally deploy from a branch if the deploy stage isn't properly scoped to `main`. Scope triggers with branch filters and path filters (e.g. skip pipeline runs that only touch `docs/`), and keep deploy stages behind an explicit environment/branch condition, not just 'pipeline succeeded'.