[CI] Loops to create jobs in YML

Description

add foreach loops to create simmilar jobs with less code duplication

It currently currently is possible to create a template and define variables to be used in the templates. But each job and its variables need to be specified. With just build and test stages it already amounts to quite a bit of code duplication. With even more stages (like package_deb, deploy, etc) the yml file gets big and hard complex pretty fast

Here a simplified example for how we build and test cmake projects:

stages:
    - build
    - test

.build:linux_job: &linux_build
    script:
        - mkdir build_${release}_${arch}
        - cd build_${release}_${arch}
        - schroot -c Ubuntu_${release}_${arch}_ribuilder -- cmake .. -DCMAKE_BUILD_TYPE=Release
        - schroot -c Ubuntu_${release}_${arch}_ribuilder -- make -j
    artifacts:
        paths:
            - build_${release}_${arch}/*
        expire_in: 1 days

.test:linux_job: &linux_test
    script:
        - cd build_${release}_${arch}
        - schroot -c Ubuntu_${release}_${arch}_ribuilder -- make test

build:linux_trusty_amd64:
    stage: build
    tags:
        - ubuntu_amd64
    variables:
        release: trusty
        arch: amd64
    <<: *linux_build

build:linux_xenial_amd64:
    stage: build
    tags:
        - ubuntu_amd64
    variables:
        release: xenial
        arch: amd64
    <<: *linux_build

test:linux_trusty_amd64:
    stage: test
    tags:
        - ubuntu_amd64
    variables:
        release: trusty
        arch: amd64
    dependencies:
        - build:linux_trusty_amd64
    <<: *linux_test

test:linux_xenial_amd64:
    stage: test
    tags:
        - ubuntu_amd64
    variables:
        release: xenial
        arch: amd64
    dependencies:
        - build:linux_xenial_amd64
    <<: *linux_test

Another version with loops (much shorter)

stages:
    - build
    - test

# templates
.build:linux_job: &linux_build
    script:
        - mkdir build_${release}_${arch}
        - cd build_${release}_${arch}
        - schroot -c Ubuntu_${release}_${arch}_ribuilder -- cmake .. -DCMAKE_BUILD_TYPE=Release
        - schroot -c Ubuntu_${release}_${arch}_ribuilder -- make -j
    artifacts:
        paths:
            - build_${release}_${arch}/*
        expire_in: 1 days

.test:linux_job: &linux_test
    script:
        - cd build_${release}_${arch}
        - schroot -c Ubuntu_${release}_${arch}_ribuilder -- make test
    dependencies:
        - build:linux_${release}_${arch}

# builds
for release, arch in ((trusty, amd64), (trusty, i386), (xenial, amd64))
do
build:linux_${release}_${arch}:
    stage: build
    tags:
        - ubuntu_${arch}
    variables:
        release: ${release}
        arch: ${arch}
    <<: *linux_build

test:linux_${release}_${arch}:
    stage: test
    tags:
        - ubuntu_${arch}
    variables:
        release: ${release}
        arch: ${arch}
    <<: *linux_test
done

This would significantly reduce code duplication and clean up our yml files

Proposal

Add some kind of foreach loop to create jobs which are very similar to each other.

Links / references