Include .gitlab-ci.yml multiple times with different configuration each time

Viewed 2545

We have a GitLab Ci/CD .gitlab-ci.yaml file that builds software packages. This .gitlab-ci.yaml has a variable that determines which operating system release the package should be built for. We would like to use the include keyword in other GitLab projects to include this .gitlab-ci.yaml to allow us to build packages. We want to build this package for multiple operating system releases. However, we cannot as GitLab does not allow us to include the same file twice. Is there another way to do this?

To see this more concretely, assume the .gitlab-ci.yaml file we want to include in other projects is this:

# common/gitlab-templates/.gitlab-ci.yaml
variables:
  OS_RELEASE: 10.0

build-package:
  script: echo "building for $OS_RELEASE"

In another GitLab project we would like to do something like this:

# Build for version 8.0
include:
  - project: 'common/gitlab-templates'
    file:    '.gitlab-ci.yml'
    variables:
      OS_RELEASE: 8.0

# Build for version 9.0
include:
  - project: 'common/gitlab-templates'
    file:    '.gitlab-ci.yml'
    variables:
      OS_RELEASE: 9.0

# Build for version 10.0
include:
  - project: 'common/gitlab-templates'
    file:    '.gitlab-ci.yml'
    variables:
      OS_RELEASE: 10.0

However, the above is not valid .gitlab-ci.yaml syntax.

How do we get around this?

3 Answers

I Assume you want to use different variables depending on the environment.

You can use a .gitlab-ci-vars.yml file and define multiple vars sections and load a different vars section based on your environment. Consider the following .gitlab-ci-vars.yml:

variables:
  FORCE_COLOR: 1

.vars-dev:
  variables:
    OS_RELEASE: 9.0
    
.vars-prod:
  variables:
    OS_RELEASE: 10.0
    

And now use it in .gitlab-ci.yml:

include:
  - ".gitlab-ci-vars.yml"

...

publish:dev:
  variables: !reference [.vars-dev, variables]
  resource_group: dev
  environment:
    name: dev
  only:
    - develop

publish:prod:
  variables: !reference [.vars-prod, variables]
  resource_group: prod
  environment:
    name: prod
  only:
    - master

This will merge the environment variables of the global scope with the environments of the targeted scope.

Maybe you can use extends ?

    # common/gitlab-templates/.gitlab-ci.yaml
    variables:
      OS_RELEASE: change_me

    .build-package:
      script: echo "building for $OS_RELEASE"

In another GitLab project we would like to do something like this:

    # Build for version 8.0
    include:
      - project: 'common/gitlab-templates'
        file:    '.gitlab-ci.yml'

    build-package:
      extends: .build-package
      variables:
        OS_RELEASE: 8.0

    # Build for version 9.0
    include:
      - project: 'common/gitlab-templates'
        file:    '.gitlab-ci.yml'

    build-package:
      extends: .build-package
      variables:
        OS_RELEASE: 9.0

    # Build for version 10.0
    include:
      - project: 'common/gitlab-templates'
        file:    '.gitlab-ci.yml'

    build-package:
      extends: .build-package
      variables:
        OS_RELEASE: 10.0

Robert-Jan's answer comes close, but this will work for your primary .gitlab-ci.yml (tested and verified) and do what you are attempting:

include:
  - project: 'common/gitlab-templates'
    file:    '.gitlab-ci.yml'

# Build for version 8.0
build-package1:
  extends: .build-package
  variables:
    OS_RELEASE: "8.0"

# Build for version 9.0    
build-package2:
  extends: .build-package
  variables:
    OS_RELEASE: "9.0"

# Build for version 10.0
build-package3:
  extends: .build-package
  variables:
    OS_RELEASE: "10.0"
Related