Which pipelines each component runs on¶
Every component carries its own rules:. Nothing here is inherited from
your pipeline, and including a component does not mean its job appears
on every pipeline — most of them are deliberately silent on most pipeline
types. This page is the lookup table for which.
Two things decide whether a job appears:
- The component's own
rules:, fixed in the template. - Your
workflow:rules, which decide whether the pipeline exists at all. A component cannot run on a pipeline yourworkflow:never created.
The trigger matrix¶
Columns are GitLab pipeline sources. MR is merge_request_event;
branch is a push to a non-default branch with no merge-request
pipeline; default is a push to $CI_DEFAULT_BRANCH; tag is a tag
push; schedule is a scheduled pipeline.
| Component | MR | branch | default | tag | schedule |
|---|---|---|---|---|---|
go-lint |
✅ | — | — | — | ❌ |
go-test |
✅ | — | — | — | ❌ |
go-security |
✅ | — | — | — | ❌ |
goreleaser |
— | — | — | ✅ | ❌ |
rust-lint |
✅ | — | — | — | ❌ |
rust-test |
✅ | — | — | — | ❌ |
rust-docs |
✅ | — | — | — | ❌ |
rust-security |
✅ | — | — | — | ❌ |
release-plz |
— | — | ✅ | — | ❌ |
svelte-build |
✅ | — | — | ✅ | ❌ |
svelte-lint |
✅ | — | — | — | ❌ |
svelte-test |
✅ | — | — | — | ❌ |
svelte-security |
✅ | — | — | — | ❌ |
docs-verify |
✅ | — | — | — | ❌ |
skill-security |
✅ | — | — | — | ❌ |
tofu-lint |
✅ | ✅ | ✅ | ❌ | ❌ |
tofu-security |
✅ | ✅ | ✅ | ❌ | ❌ |
tofu-validate |
✅ | ✅ | ✅ | ❌ | ❌ |
tofu-plan |
✅ | — | ✅ | — | ❌ |
tofu-apply (plan_source: job) |
— | — | ✅ | — | ❌ |
tofu-apply (plan_source: ref) |
— | — | — | ✅ | ❌ |
tofu-stop |
— | — | ✅ (manual) | — | ❌ |
tofu-deploy-generate (mode: generate) |
— | — | — | ✅ | ❌ |
tofu-deploy-generate (mode: verify-fixtures) |
✅ | — | ✅ | — | ❌ |
tofu-module-publish |
— | — | — | ✅ | ❌ |
zensical-pages (zensical-build) |
✅ | ✅ | ✅ | ❌ | ❌ |
zensical-pages (pages) |
— | — | ✅ | — | ❌ |
hugo-pages (hugo-build) |
✅ | ✅ | ✅ | ❌ | ✅ |
hugo-pages (pages) |
❌ | — | ✅ | — | ✅ |
releaser-pleaser |
— | — | ✅ | — | ❌ |
release-stamp |
— | — | — | ✅ | ❌ |
discord-release |
— | — | — | ✅ | ❌ |
renovate-self |
— | — | — | — | ✅ |
renovate-group |
— | — | — | — | ✅ |
renovate-merge |
— | — | — | — | ✅ |
release-train |
— | — | — | — | ✅ |
✅ runs · — no rule matches, so no job is created · ❌ an explicit
when: never suppresses it
Notes on individual rows:
hugo-build's MR and branch runs come frommr_gate, which defaults totrue. That rule carries no pipeline-source condition, so the build gate fires on a merge request and on a plain branch push whenever achangespath was touched. Settingmr_gate: false(the loose direct-to-main mode) turns both columns into—.tofu-applyandtofu-deploy-generateare one job, not two.plan_sourceandmodeselect a hidden job that carries therules:, so choosing the mode chooses the trigger. Two rows, one job.renovate-groupalso runs off-schedule when$RENOVATE_TARGET_FILTERis set — the manual-run escape hatch for a single repo, on any pipeline itsifinput matches.- The default-branch column assumes your
workflow:creates a default-branch pipeline. Many repositories only run one so that a release driver can maintain its Release MR.
Why almost no component runs on a scheduled pipeline¶
Every other component's first rule is
if: $CI_PIPELINE_SOURCE == "schedule" → when: never, unconditionally,
before anything a consumer can influence.
A scheduled pipeline exists to do one job — run Renovate, or rebuild a time-sensitive site. Without the guard, every gate in the repository would also fire on that schedule: a full lint/test/security fan-out, nightly, on a commit nobody pushed and nobody is waiting on. On a fixed-concurrency self-hosted runner that is capacity taken from pipelines somebody is waiting on.
The guard is first and unconditional so that widening a component's if
input cannot pull the job back onto the schedule. renovate-self,
renovate-group, renovate-merge and release-train have no guard because
the schedule is the only place they are meant to run; hugo-pages
deliberately runs on a schedule so future-dated content publishes without a
push.
release-train is the exception among the four: a scheduled run only ever
plans, and it refuses to execute on a schedule even when explicitly told
to, because cutting releases is a per-train decision and never a standing
one.
Why change-detection never applies to a tag or a schedule¶
rules:changes compares a diff, and a tag or scheduled pipeline has no
meaningful diff to compare — GitLab treats the filter as always-true there.
Filtering a release job on something that is always true is not a filter,
and filtering it on something unreliable would occasionally skip a
release. So changes: is attached only to merge-request rules (and, for
the static-site components, to the branch rule that feeds a deploy).
The reasoning is in Explanation: change-detection; the recipe is Add change-detection to a gate.
Which components let you change when they run¶
Only some. A component with an if input exposes its trigger
condition; a component without one has its trigger welded to the job it
does, because the trigger and the work are one decision.
Has an if input (overridable) |
No if input (fixed trigger) |
|---|---|
go-lint, go-test, go-security |
all eight tofu-* components |
rust-lint, rust-test, rust-docs, rust-security |
goreleaser |
svelte-build, svelte-lint, svelte-test, svelte-security |
zensical-pages, hugo-pages |
skill-security |
|
release-plz, releaser-pleaser |
|
renovate-self, renovate-group, renovate-merge |
|
release-train, release-stamp, discord-release |
The fixed ones are fixed for a reason worth knowing:
tofu-plan/tofu-applyauthenticate by OIDC, and the AWS trust policy only accepts subjects from the refs it was written for. A job moved to a ref the trust policy does not name does not run a wrong plan — it fails at assume-role.tofu-apply's trigger is coupled toplan_source:needs:andrules:both live in a per-mode hidden job the component extends, so choosingjoborrefis choosing the trigger.goreleaserandtofu-module-publishpublish artefacts. Their tag match is the release gate; making it overridable would make it possible to publish from a branch.
Widening a trigger you can widen still cannot reach a scheduled pipeline — see above.
Why the Tofu gates run on branch pushes and the Go, Rust and Svelte gates do not¶
This is a real difference, not a documentation slip. tofu-lint,
tofu-security, tofu-validate and the zensical-pages build job have no
if: on their run rule at all — they exclude schedules and tags and then
run on whatever is left, which includes a plain branch push. The Go, Rust
and Svelte gates default their if input to
$CI_PIPELINE_SOURCE == "merge_request_event" and so run on merge requests
only.
On a project with the usual workflow: dedup rule this is invisible,
because no branch pipeline is created once a merge request is open:
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
when: never
- if: '$CI_COMMIT_TAG'
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
- if: '$CI_PIPELINE_SOURCE == "schedule"'
Without that dedup rule, a push to a branch that already has an open merge
request runs the Tofu gates twice — once on the branch pipeline, once on
the merge-request pipeline. Keep the $CI_COMMIT_BRANCH guard on the
never rule: keying it on $CI_PIPELINE_SOURCE == "push" also matches a
tag push and suppresses the entire tag pipeline, which is how a release
silently stops publishing.
What "no rule matched" looks like¶
A component whose rules do not match produces no job. There is no skipped job, no grey icon, no entry in the pipeline graph — the job simply is not there. The pipeline goes green having run nothing.
That is the failure mode to expect when a component appears to have been ignored, and it is the first thing to check: not "why did my job fail" but "is my job in the pipeline at all". See Diagnose a job that did not run.
See also¶
- Limitations — what these components deliberately do not do.
- Explanation: change-detection — why
changesis MR-scoped. - Explanation: security, always-on — why the security components have no
changesinput. - How-to: diagnose a failing job.