10. Shared functionality

In this section we’ll talk about how to include GitLab templates and other code snippets into your project. This helps you to avoid code duplication and gives you the ability to store, share and reuse your pipeline code. Even across different projects.

10.1: Include keyword

Use include to include external YAML files in your CI/CD configuration. You can break down one long gitlab-ci.yml file into multiple files to increase readability, or reduce duplication of the same configuration in multiple places.

You can also store template files in a central repository and include them in projects.

include requires the external YAML file to have the extensions .yml or .yaml, otherwise the external file is not included.

You can’t use YAML anchors across different YAML files sourced by include. You can only refer to anchors in the same file. To reuse configuration from different YAML files, use !reference tags or the extends keyword.

KeywordMethod
localInclude a file from the local project repository.
fileInclude a file from a different project repository.
remoteInclude a file from a remote URL. Must be publicly accessible.
templateInclude templates that are provided by GitLab.

Task 10.2: Shared functionality Lab

In this lab we will show you how to extend a job with an other job from a shared template.

Execute following tasks:

  • Define a new job named deploy_to_k8s
  • Include the repository template with the local keyword. Use the predefined Gitlab Environments variable to set the project field value
  • Extend the job with .kubectl from the template.
  • Add a script section in the job with following command kubectl version

Commit and push your changes and then verify the output of the pipeline run.

Solution

Updated .gitlab-ci.yml file for this lab:

show solution
stages:
  - info
  - build
  - test
  - package
  - deploy

include:
  - project: '${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}'
    file: 'templates/k8s.yml'

variables:
  GIT_STRATEGY: 'clone'
  COMPILE: 'false'
  IMAGE_HOST: 'quay.io'
  IMAGE_REPOSITORY: 'puzzle'
  IMAGE_NAME: 'example-spring-boot'

default:
  timeout: 5 minutes

info:
  stage: info
  retry: 2
  script:
    - echo "This is your first stage (ツ)"
    - echo "Username is ${USERNAME} with ${PASSWORD}"

build_application:
  stage: build
  tags:
    - build
    - mobiliar
  image: registry.access.redhat.com/ubi9/openjdk-17:latest
  script:
    - ./gradlew assemble

test_application:
  stage: test
  image: registry.access.redhat.com/ubi9/openjdk-17:latest
  script:
    - ./gradlew check
  artifacts:
    when: always
    reports:
      junit: build/test-results/test/**/TEST-*.xml

build_image:
  image: diemobiliar.azurecr.io/dlp-cicd-dockercli-image:254
  tags:
    - build
    - mobiliar
  services:
    - docker:dind
  stage: package
  before_script:
    - docker info
  script:
    - docker build --no-cache -t $IMAGE_NAME .
    - IMAGE_PATH=$IMAGE_HOST/$IMAGE_REPOSITORY/$IMAGE_NAME:${CI_COMMIT_SHA:0:8}
    - echo "docker image path is - $IMAGE_PATH"
    - docker tag $IMAGE_NAME $IMAGE_PATH
    # - docker login -u ${DOCKER_USERNAME} -p ${DOCKER_PASSWORD} ${IMAGE_HOST}
    # - docker push $IMAGE_PATH

deploy_to_prod:
  stage: deploy
  when: manual
  only:
   - release
  script:
    - echo "Deployment triggered"

deploy_to_k8s:
  stage: deploy
  extends: .kubectl
  tags:
    - build
    - mobiliar
  script:
    - echo "deploy your stuff here with kubectl commands"
    - kubectl version --client --short