Skip to content

Bad expansion for nested rules reference #1593

Open
@dpetrisko

Description

@dpetrisko

Hello! It seems like there's a bug with nested rules references.

Patterns with compact assignment like below seem fine:

.t1:
  - rules ...
.t2:
  rules: !reference [.t1, rules]
.t3:
  rules: !reference [.t3, rules]

Patterns with a list assignment are breaking:

.t1:
  - rules ...
.t2:
  rules: 
  - !reference [.t1, rules]
.t3:
  rules: !reference [.t3, rules]

Both patterns seem to work in latest gitlab-ci proper.

Minimal .gitlab-ci.yml illustrating the issue
.gitlab-ci.yml:

---
.base_template:
  variables: {MY_VAR: MY_VAL}
  rules:
    - if: $MY_VAR == "MY_VAL"
      when: always

.job_template1:
  extends: [.base_template]
  rules: !reference [.base_template, rules]

.job_template2:
  extends: [.base_template]
  rules:
    - !reference [.base_template, rules]

# expansion fine
test-job1:
  extends: [.job_template1]
  script:
    - echo "hello world job1"
  rules: !reference [.job_template1, rules]

# expansion broken
test-job2:
  extends: [.job_template2]
  script:
    - echo "hello world job2"
  rules: !reference [.job_template2, rules]

Expected behavior

The json-schema validation fails here:

Invalid .gitlab-ci.yml configuration!
	• '0' property type must be object at test-job2.rules.0 [#/items/anyOf/0/type]
	• '0' property type must be string at test-job2.rules.0.0 [#/items/anyOf/2/items/type]

With --json-schema-validation=false, I get

$ gitlab-ci-local --json-schema-validation=false --concurrency=1
parsing and downloads finished in 156 ms.
test-job1 starting shell (test)
test-job1 $ echo "hello world job1"
test-job1 > hello world job1
test-job1 finished in 33 ms
test-job2 starting shell (test)
test-job2 $ echo "hello world job2"
test-job2 > hello world job2
test-job2 finished in 22 ms

 PASS  test-job1
 PASS  test-job2
pipeline finished in 295 ms

Host information
Ubuntu 24.04.2 LTS
gitlab-ci-local 4.60.1

Containerd binary
no

Additional context

It looks like there's a bug in the reference expansion,

.gitlab-ci-local/expanded-gitlab-ci.yml

---
stages:
  - .pre
  - build
  - test
  - deploy
  - .post
.base_template:
  variables:
    MY_VAR: MY_VAL
  rules:
    - &ref_0
      if: $MY_VAR == "MY_VAL"
      when: always
.job_template1:
  variables:
    MY_VAR: MY_VAL
  rules: &ref_1
    - *ref_0
.job_template2:
  variables:
    MY_VAR: MY_VAL
  rules:
    - *ref_0
test-job1:
  variables:
    MY_VAR: MY_VAL
  rules: *ref_1
  script:
    - echo "hello world job1"
test-job2:
  variables:
    MY_VAR: MY_VAL
  rules:
    - *ref_1
  script:
    - echo "hello world job2"
default: {}

full configuration from GitLab CI Pipeline editor:

---
".base_template":
  variables:
    MY_VAR: MY_VAL
  rules:
  - if: $MY_VAR == "MY_VAL"
    when: always
".job_template1":
  variables:
    MY_VAR: MY_VAL
  rules:
  - if: $MY_VAR == "MY_VAL"
    when: always
  extends:
  - ".base_template"
".job_template2":
  variables:
    MY_VAR: MY_VAL
  rules:
  - - if: $MY_VAR == "MY_VAL"
      when: always
  extends:
  - ".base_template"
test-job1:
  variables:
    MY_VAR: MY_VAL
  rules:
  - if: $MY_VAR == "MY_VAL"
    when: always
  extends:
  - ".job_template1"
  script:
  - echo "hello world job1"
test-job2:
  variables:
    MY_VAR: MY_VAL
  rules:
  - - if: $MY_VAR == "MY_VAL"
      when: always
  extends:
  - ".job_template2"
  script:
  - echo "hello world job2"

Let me know if you need any more information. Thank you!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions