CI_COMMIT_BRANCH is provided by Gitlab at runtime.

Variables are passed from upstream to downstream.

Given this, I’d expect to be able to prefix the upstream’s value and pass it downstream.

# upstream project .gitlab-ci.yml


variables:
  TAG: "test-${CI_COMMIT_BRANCH}"


some-job-that-triggers-downstream:
  variables:
    IMAGE_TAG: ${TAG}
  trigger:
    project: foo/bar
# downstream project .gitlab.yml

some-job:
  variables:
    IMAGE: "something.com/docker/upstream-branch:$IMAGE_TAG"
  script:
    - echo "IMAGE $IMAGE"

Expected

upstream:   CI_COMMIT_BRANCH = 'upstream-branch'
upstream:   IMAGE_TAG = 'test-upstream-branch'
downstream: IMAGE_TAG = 'test-upstream-branch'

That is not what happens, though!

Although TAG: "test-${CI_COMMIT_BRANCH}" looks like we’re evaluating CI_COMMIT_BRANCH and assigning it to a new value, the evidence suggests that Gitlab is not evaluating it at that point. When this gets downstream, it is not 'test-upstream-branch', it is still 'test-${CI_COMMIT_BRANCH}'! Of course, this means CI_COMMIT_BRANCH has a new value in this context.

This issue demonstrates perfectly.

ku  should be 'ku'
test-${CI_PIPELINE_ID}  should be 'test-ku'

How do we evaluate the current value instead of passing down the string?

There are 5 years worth of workarounds and bitching in that Gitlab issue above. You can run these locally with gitlab-runner to figure out what works for you.

This dude nailed it, though.

https://gitlab.com/gitlab-org/gitlab-runner/-/issues/1809#note_99891354

If possible, export the variable in a before_script step so it is evaluated and set there.