Included image is overridden by top-level image

When there’s an image declared at the top level of .gitlab-ci.yml and inside an included file, the one in .gitlab-ci.yml is used. This is unexpected. I’d expect includes to be considered as an inner scope, and anything declared in the inner scope should override anything declared in the outer scope.

Relevant parts of .gitlab-ci.yml:

image: nixos/nix:2.11.1

lint files:
  stage: test
  script: nix-shell --pure --run 'pre-commit run --all-files'

lint commit messages:
  stage: test
    GIT_DEPTH: ""
    nix-shell --pure --run "gitlint --debug --commits

  - project: "renovate-bot/renovate-runner"
    file: "/templates/renovate-dind.gitlab-ci.yml"
    ref: 326c8a25654e3bd8f9d9c3eb7d2e7646e0715c37 # v10.14.2

From a job:

Using docker image sha256:467492ebb5e298dbc5f85fe4d168b427ad87a6bea70414521710b47c26b17f13 for nixos/nix:2.11.1 with digest nixos/nix@sha256:d8c6b97091d6944dd773c3c239899af047077dbf5411ef229bb50e5b21404b0d ...

Horrible hack workaround: copy every top-level setting inside every job in .gitlab-ci.yml, to avoid the possibility of breaking included jobs.


maybe you should should post an issue in the project WhiteSource Renovate / renovate-runner · GitLab so they can fix this behaviour.

The image should be referenced by the declaration of the job renovate and not declared as global image to be used for all jobs.

If the image is set as default image for the whole pipeline, the include cannot be used in pipelines that define an own default image.

While merging all contents to a full .gitlab-ci-yml GitLab just follows the rules you can see in many tools which use configuration stored in different levels. Let’s compare your case with the image to git config to have an example what I mean.

  • The image definition within a job in your .gitlab-ci.yml would be like setting a config for the run of one git command git -c foo=bar <rest of git command>.
  • The image definition within the .gitlab-ci.yml in your project is like git config --local foo bar.
  • The image definition in /templates/renovate-dind.gitlab-ci.yml (your include) is like git config --global foo bar
  • The image definition within the config of your runner is like git config --system foo bar

command > local > global > system

So if you set an own image in your .gitlab-ci.yml it overrides the value set by the include and also the image defined by the runner configuration. The same applies for defining an image within a job.

kind regards

1 Like

Very nice explanation, thank you! The definition of local and global are opposite of what I’d expect (.gitlab-ci.yml is the top-level file, after all, and having each include be a “global” configuration could get very messy). However, it’s clear that with the current implementation the fix needs to be implemented in Renovate, so I’ve filed an issue.

The global keywords are deprecated. You can use default instead. I think it has higher priority than the global ones, but I am not 100% sure.

1 Like

Yes the global keyword image is deprecated. Totally forgot about that :smile:

But setting the image in the default block in the own .gitlab-ci.yml and/or the included renovate-dind.gitlab-ci.yml from renovate-bot/renovate-runner would behave exactly the same way.

Welp, looks like I’ve got work to do:

$ rg --files-with-matches '^(image|services|cache|before_script|after_script)' ~/dev/*/.gitlab-ci.yml | wc -l

Fortunately a quick

sed -i -e 's/^image:/default:\n  image:/' ~/dev/*/.gitlab-ci.yml

fixed 11 of those.