Variables precedence policy
When using upstream/downstream pipelines, secret project level variables do not override yaml variables passed down from the upstream config file.
Steps to reproduce
# gitlab-ci.yml
variables:
MY_PATH_VARIABLE: "/builds/gitlab-org-forks/${CI_PROJECT_NAME}"
print_custom_variable:
stage: build
script:
- echo $MY_PATH_VARIABLE # this will print out the secret project variable
child_with_default_variable:
stage: test
trigger:
strategy: depend
include: 'child-pipeline.yml'
# child-pipeline.yml
print_custom_variable:
stage: build
script:
- echo $MY_PATH_VARIABLE # this will print out "/builds/gitlab-org-forks/the-project" instead on the project variable
Example Project
https://gitlab.com/mbobin/ci-playground/-/pipelines/215804723
What is the current bug behavior?
We pass the YAML variables from the triggering job to the child pipeline and they change precedence in the process:
-
https://gitlab.com/gitlab-org/gitlab/-/blob/39ae4c83219facf937dcd49638bb6436b8e11365/app/services/ci/create_downstream_pipeline_service.rb#L35-38 - here we create the downstream pipeline and we define
pipeline.variables
based on bridge downstream variables - https://gitlab.com/gitlab-org/gitlab/-/blob/39ae4c83219facf937dcd49638bb6436b8e11365/app/models/ci/bridge.rb#L197-205 - we see that bridge downstream variables are the YAML variables
-
https://gitlab.com/gitlab-org/gitlab/-/blob/39ae4c83219facf937dcd49638bb6436b8e11365/app/models/concerns/ci/contextable.rb#L26 - we see that
pipeline.variables
are overridingsecret_project_variables
.
In other words, YAML variables from the parent pipeline become pipeline variables in the child pipeline and yaml_variables
< secret_project_variables
< pipeline.variables
.
Workarounds
Use job scoped variables to override global variables and pass the expected value downstream using variable expansion.
variables:
MY_PATH_VARIABLE: "/builds/gitlab-org-forks/${CI_PROJECT_NAME}"
child_with_preserved_project_variable:
variables:
MY_PATH_VARIABLE: $MY_PATH_VARIABLE
trigger:
strategy: depend
include: 'child-pipeline.yml'
Edited by Marius Bobin