Skip to content

Define variables based on another Variable

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

Introduction

So we already have many differents ways to define a variable but we yet do not have any way of controlling it without needs for accessing gitlab-ci.yml, projects settings or any other methods that doesn't need manual intervention (like Run Pipelines for an example)

Think about this use case:

Problem

We have a user that is only allowed to commit in a branch that he owns (developer) and the pipeline runs only for merge requests. So the only way that he is able to communicate with the pipeline is through the Commit message and Merge Request infos.

In the case that the pipeline fails and he'd like to use CI_DEBUG_TRACE or the code beneath the pipeline allows a DEBUG variable he does not have any source to enable.

Ps. This usecase is used for our IAC platform.

Since the releases of the rules there is a possibility to use this syntax to add and overwrite some variables depending on any points that we decide, like this:

rules:
  - if: '$CI_COMMIT_MESSAGE =~ /.*#debug.*/'
    variables:
      TF_LOG="debug"

And here comes the problem...

rules:
  - if: '$CI_COMMIT_MESSAGE =~ /.*#debug.*/'
    variables:
      TF_LOG="debug"
  - if: '$CI_COMMIT_MESSAGE =~ /.*#trace.*/'
    variables:
      CI_DEBUG_TRACE: "true"

This is just an example using debug, but there are several usecases that we have here that are affected by this. Terraform: Force Not Refresh, Import....

Whenever we'd like to add any other variable, we couldn't because, as the documentation says:

Rules are evaluated when the pipeline is created, and evaluated in order until the first match.

Then the CI_DEBUG_TRACE: "true" wouldn't be added in the case we do a commit message that add both. #debug #trace for example

Solution

At first I thought that by simple evaluating all ifs instead of leaving would solve, but then i came with a simpler better idea:

Instead of we use the if in the rules: we could use on variables, like this:

variables:
  TF_LOG_PATH: "/tmp/terraform.log"
  rules: 
  - if: '$CI_COMMIT_MESSAGE =~ /.*#debug.*/'
    TF_LOG: "debug"
  - if: '$CI_COMMIT_MESSAGE =~ /.*#trace.*/'
    CI_DEBUG_TRACE: "true"

in this case, if the commit message is #debug #trace the final variables yaml would be:

variables:
  TF_LOG_PATH: "/tmp/terraform.log"
  TF_LOG: "debug"
  CI_DEBUG_TRACE: "true"

and if any clausule is negative it wouldn't be added to the variables.

Obs. In the case that there are any overwrite variables, the basic order would be enough to fulfill this matter, I guess.

Workaround

What is possible doing is to validate the message in a before_script and exporting in a bash file all the true cases.

I hope that this helps more Gitlab users and, maybe, gets implemented.

BR André Bovendorp

Edited by 🤖 GitLab Bot 🤖