Support variables in extends:

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

Release notes

Being able to use variables in the extends: value would allow it to be combined with parallel: to combine duplicate jobs into one, reducing the boilerplate.

Problem to solve

As a DevOps Engineer I want to use variables in the extends: value to combine it with the parallel: keyword, so I can combine duplicate jobs into one, reducing the boilerplate.

Intended users

Everyone who touches the CI, ie.:

User experience goal

The user should be able to combine duplicate jobs into one through the use of the parallel: keyword.

Proposal

Add the "resolve variables" pass before evaluating the value of the extends: keyword.

Further details

See "What does success look like, and how can we measure that?" below for a real-world use-case.

Permissions and Security

No change in permissions or security needed.

Documentation

Availability & Testing

The risk is that someone might have used the $ character in a job name and extended that job. For them, this change will mean that suddenly this will be evaluated as a variable, resulting in unexpected behaviour (most likely the "CI/CD YAML configuration error!" message).

Available Tier

Free?

As a dev myself I see no reason to limit access to this feature, but maybe sales people have a different opinion.
One argument against tiering this feature is that it would break the CI based on whether/how much the user pays.

What does success look like, and how can we measure that?

The following .gitlab-ci.yml is considered valid, and produces 8 jobs:

.foo:
  script:
    - echo foo $CONFIG

.bar:
  script:
    - echo bar $CONFIG

build:
  stage: build
  parallel:
    matrix:
      - JOB: [foo, bar]
        CONFIG: [a, b, c, d]
  extends:
    - .$JOB

Currently (GitLab 13.8) this results in the following "CI/CD YAML configuration error!" message:

Found errors in your .gitlab-ci.yml:
  - build: unknown keys in `extends` (.$JOB)

As a real-world use-case, this is the kind of things I would've wanted to do when I decided to file this feature request.
The goal is to run each test suite in its own job that only exists if there are changes in the code that could affect them. There is also a split of "quick" tests and "long" tests, the former being always run and the latter being run on-demand.

.test-quick:
  script:
    - ./run_quick_test.sh $TEST_PATH

.test-long:
  when: manual
  script:
    - ./run_long_test.sh $TEST_PATH

.changes-foo:
  only:
    changes:
      - src/foo/**
      - tests/foo/**

.changes-bar:
  only:
    changes:
      - src/bar/**
      - tests/bar/**

tests:
  stage: test
  parallel:
    matrix:
      - TEST_PATH: [foo, bar]
        TEST_TYPE: [quick, long]
  extends:
    - .changes-$TEST_PATH
    - .test-$TEST_TYPE

(Also technically I'm using rules: instead of the plain when: to make the long tests manual on branches but automatic on merge requests or the default branch, but I don't think this is important here, so I used the simpler form in the example above.)

What is the type of buyer?

Unknown

Is this a cross-stage feature?

Unknown

Links / references

Similar issues:

Both sound like very complicated solutions that would take a lot of work, unlike the simple "variable resolution" pass I'm suggesting here.

Edited by 🤖 GitLab Bot 🤖