Skip to content

!reference ["workflow", "rules"] is part of a circular chain

Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.

Summary

As mentioned in the subject line

Steps to reproduce

include:
- template: "Workflows/MergeRequest-Pipelines.gitlab-ci.yml"

workflow:
  rules:
  - if: '$CI_PIPELINE_SOURCE == "api" && $CI_COMMIT_REF_PROTECTED != "true"'
  - !reference [workflow, rules]

... <jobs> ...

Example Project

What is the current bug behavior?

The backend flags this as a circular reference. Which, to be fair, it is. I had hoped that it would be possible to reference the workflow keyword as an override like this so that I could add the one new condition before the template workflow:rules apply.

What is the expected correct behavior?

I hoped to use the Gitlab template, but prevent pushes to main by a "bot account" with maintainer privileges from triggering a pipeline.

The goal is to avoid needing to redefine the MergeRequest Pipelines template internally with this additional condition, so that any future changes to the template (however infrequent they may be) would be able to still apply to our pipelines.

Correct behavior would be to circuit break this and allow the configuration to not be considered a circular reference. Alternatively a new feature to allow merging the list from the template into user-defined workflow rules via <<: would be fine.

Maybe the template could do:

workflow:
  rules: &workflow
... <merge request rules> ...

Then we can simply do in our projects:

workflow:
  rules:
  - <custom rule>
  - *workflow

Edit: nevermind, that won't work because YAML anchors can't be used across files that are included...

The problem stems from the fact that YAML arrays are overridden wholesale instead of being merged. This is part of the YAML spec, so I realize you have no control over it; but perhaps it'd be possible to find a good way to make this work. I'm open to alternative suggestions that I can either implement on my end alone, or that would fit under the small fixes label on your end.

The goal is that the end result after backend processing looks like this:

## This comes in from the include
workflow:
  rules:
  - if: $CI_MERGE_REQUEST_IID
  - if: $CI_COMMIT_TAG
  - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

## This is the result after merging the above into my actual .gitlab-ci.yml; the "rendered" pipeline manifest
workflow:
  rules:
  - if: '$CI_PIPELINE_SOURCE == "api" && $CI_COMMIT_REF_PROTECTED != "true"'
  - if: $CI_MERGE_REQUEST_IID
  - if: $CI_COMMIT_TAG
  - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

Relevant logs and/or screenshots

Output of checks

Results of GitLab environment info

Results of GitLab application Check

Possible fixes

Edited by 🤖 GitLab Bot 🤖