Tricky
Tricky

Reputation: 4461

Pattern Matching for rules parameter Gitlab CI

I am trying to make use of the rules: parameter to make a job only appear in a pipeline if specified users did the push. I dont want to define the list of users for each job, so I have the following global variable:

variables:
  USER_LIST: "user1 user2 user3"

and in the job, I have the following:

rules:
 - if '$USER_LIST =~ /$GITLAB_USER_LOGIN/'
    when: on_success
 - when: never

This does not appear to be working, as I suspect the regex pattern being used is not being replaced by the variable, and using $GITLAB_USER_LOGIN as the search string. If I use an explicit search:

rules:
 - if '$USER_LIST =~ /user1/'
    when: on_success
 - when: never

then the pattern matches just fine.

NOTE: I am aware that GITLAB_USER_LOGIN is a protected variable. I get the same problem with GITLAB_USER_EMAIL too.

So the question is, how can I put a GITLAB predifined variable into a string that will be used for pattern matching?

Upvotes: 11

Views: 20585

Answers (6)

François Guertin
François Guertin

Reputation: 31

In our case, we wanted to run the job only if the current branch matched a list of specific branches.

We created a project level variable named PROTECTED_BRANCHES_REGEX with the value

/^develop$|^release-[0-9][0-9][0-9][0-9].[1,2]$|^hotfixes-[0-9][0-9][0-9][0-9].[1,2].[0,1]$|^master$/

Then we defined the following rule in the job:

rules:
    - if: $CI_COMMIT_REF_NAME =~ $PROTECTED_BRANCHES_REGEX

That works fine with Gitlab version 15.4.6-ee.

Upvotes: 2

Drozt
Drozt

Reputation: 91

We can't use variables inside pattern for some (gitlab) reason. But we can swap list of privileged users and the current user in rule. Just transform list of users to regexp pattern:

.job:
    variables: 
        PRIVILEGED_USERS_PATTERN: '/user1|user2|userN/i'
    rules:
        - if: $GITLAB_USER_LOGIN =~ $PRIVILEGED_USERS_PATTERN
          when: manual

This solution has two minuses:

  1. List of privileged users visible to all, who have reading access to the project

  2. Pattern length limit (no testing)

But for now i don't see other solution how to not running the job at all.

Upvotes: 9

bruegth
bruegth

Reputation: 691

My workaround is to build an dynamic-child-pipeline where the variable within pattern already evaluated and inserted as constant string.

Upvotes: 0

Christoph
Christoph

Reputation: 54

I have more or less the same problem setup. The issues mentioned in the comments were addressed in 15.1, see https://docs.gitlab.com/ee/ci/jobs/job_control.html#store-the-regex-pattern-in-a-variable.

Nevertheless '$USER_LIST =~ /$GITLAB_USER_LOGIN/' still doesn't work. Also, if you define a variable like pattern: /$GITLAB_USER_LOGIN/ and use that in the way described in the documentation, it doesn't work.

'$USER_LIST =~ $pattern'

What works, but isn't the solution to your or my problem is defining pattern with a fixed pattern, like pattern: /user1/. Then it works if used like this:

'$USER_LIST =~ $pattern'

But obviously, I want to use the actual user, that tries to create a pipeline.

What works on my instance (15.4) is this:

'$GITLAB_USER_LOGIN =~ $USER_LIST'

I have no idea why, cos in my opinion this is no behaviour suggested by the documentation. I looked around in several places and found no documented examples of this use, but it works.

This job gets created with a delayed start:

variables:
  pattern: "user"
  string: "this contains user and other stuff"

show-env:
  stage: env
  tags:
    - ops
  rules:
    - if: $pattern =~ $string
      when: delayed
      start_in: 15m
    - when: always
  script:
    - env

And if you remove user from string and push it again, it gets executed right away.

And it also works when I define USERLIST in the project ci/cd variables and test that against $GITLAB_USER_LOGIN.

Upvotes: 1

TheLoneKing
TheLoneKing

Reputation: 235

You are using a variable and not a regular expression in your rule. So you don't need the slashes around the $GITLAB_USER_LOGIN variable. Try something like this:

rules:
  - if '$USER_LIST =~ $GITLAB_USER_LOGIN'

Upvotes: 3

Manuel
Manuel

Reputation: 542

The documentation shows that the content matching regex should look like this:

$VARIABLE =~ /^content.*/

for your code you need to add ^ and .*:

rules:
 - if '$USER_LIST =~ /^user1.*/'
    when: on_success
 - when: never

Upvotes: 1

Related Questions