Skip to main content

CI/CD provider

ISSUE-402MediumQuickCLIPipeline Composition

Include ref collides with both a tag and a branch upstream

Control: Includes must not use ambiguous tag/branch refs· Config key: externalRefsMustNotCollide

📋 What is this?

A pipeline include: pins a symbolic ref (an include:project with ref: v1, or a CI/CD component @v1) where the same name exists upstream as both a tag and a branch.

⚠️ Impact

GitLab resolves the tag first, so the pipeline pulls the tagged revision today, but a tag deletion, a rename, or a typo can switch the binding to the mutable branch, which tracks every push. The included template runs in your pipeline with your CI/CD variables and tokens, so the ambiguity is a supply-chain landmine: a reviewer cannot tell from the YAML which of the two revisions will run.

🔧 How to fix

Pin the include to a 40-character commit SHA, which is unambiguous (a commit SHA also takes precedence over a same-named tag). Alternatively, ask the upstream maintainer to remove one of the two colliding refs.

✗ BeforeThe include ref resolves to either the tag or the branch depending on GitLab's resolution order.
# .gitlab-ci.yml — ❌ Ambiguous ref
include:
- project: my-group/ci-templates
ref: v1
file: /templates/build.yml
# ^ `v1` exists as both a tag AND a branch upstream
✓ AfterPin by commit SHA, so a tag/branch collision no longer matters.
# .gitlab-ci.yml — ✅ SHA-pinned removes the ambiguity
include:
- project: my-group/ci-templates
ref: a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4
file: /templates/build.yml

💡 Tips

  • API-backed: the collector probes the source project's tag and branch namespaces and fires only on a confirmed double-hit. Without a token (or on a failed probe) the control abstains, with no false positives.
  • Applies to CI/CD component @version refs too, since components resolve the version against the same tag and branch namespaces.

⚙️ Configuration

This control is configured in .plumber.yaml under the gitlab section:

gitlab:
  controls:
    externalRefsMustNotCollide:
      enabled: true

See the CLI documentation for the full configuration reference.