GitLab CI rules incorrectly classify variable as defined/non-empty if it is assigned by parent job (via extends keyword, to a possibly empty value)

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

Summary

When using rules:if within a .gitlab-ci.yml file, all of the currently supported types of checks for variable existence/emptiness are resolved as true even if the variable is actually empty, as long as the variable is assigned in a parent job (via the "extends" keyword).

The below pattern would be useful if properly supported as it would allow specific_job to:

  1. Use SPECIFIC_USERNAME if it is defined, or fallback to USERNAME if it is not.
  2. Only run if either of the two variables is defined, which includes not processing the above operation in the job script.
  3. Inherit all the above behavior from a "parent" job.

Steps to reproduce

  1. Open CI Lint. The issue is present outside of CI Lint as well, however, this method of reproduction is faster than creating a new repository with CI enabled and set up.
  2. Paste in the following document:
     workflow: # Not a necessary part for reproduction, suppresses an unrelated CI Linter warning.
       rules:
         - when: always
    
     stages:
       - build
    
     variables:
       USERNAME: ""
    
     dummy_job:
       stage: build
       script:
         - echo "This job only exists so that the pipeline is never empty."
    
     .specific_base:
       stage: build
       variables:
         SPECIFIC_USERNAME: ${USERNAME} # Line 19
       rules:
         - if: $SPECIFIC_USERNAME == null
           when: never
         - if: $SPECIFIC_USERNAME == ""
           when: never
         - if: $SPECIFIC_USERNAME == ''
           when: never
         - if: $SPECIFIC_USERNAME =~ /^\s*$/
           when: never
         - if: $SPECIFIC_USERNAME
           when: on_success
       
     specific_job:
       extends: .specific_base
       script:
         - 'echo "Given that this job is executed, it surely cannot be that the following variable is empty: ${SPECIFIC_USERNAME}"'
    
  3. Submit the document to the CI Lint tool / commit to the project.
  4. Observe that specific_job is scheduled to run, despite the exhaustive attempts to avoid its run while SPECIFIC_USERNAME is empty.

What is the current bug behavior?

The job is scheduled to run although the variable is empty.

What is the expected correct behavior?

The job should not be scheduled to run because the variable is empty.

Results of GitLab environment info

I am using a private instance of GitLab Enterprise Edition 14.2.5-ee.

Possible fixes

  1. Comment out or delete line 19 (marked with a comment) in the reproduction source code snippet.
  2. Observe that the specific_job is no longer scheduled to run as expected.
Edited by 🤖 GitLab Bot 🤖