Параметризованные сборки в GitLab

Привет, на связи Олег Казаков из Spectr. Сегодня мы разберем тему параметризованных сборок в GitLab и чем они могут быть полезны.

Введение в параметризованные сборки

Понятие параметризованных сборок очень популярно в Jenkins — это функционал, который позволяет запускать сборки с пользовательскими параметрами. Это значительно расширяет возможности автоматизации и делает процессы более гибкими.

Одна из ключевых задач, для которой этот функционал может применяться, — тестирование функционала в разных окружениях. Можно запускать тесты на окружении (например, dev, staging, test), просто задавая нужные параметры.

Параметризованные сборки в GitLab

В GitLab подобный функционал тоже имеется, и сегодня я расскажу, как его можно использовать.

В документации GitLab этот функционал можно посмотреть тут: Prefill variables in manual pipelines. Здесь описывается, как можно задавать переменные, которые будут предварительно заполняться при запуске пайплайна вручную. То есть при создании пайплайна в интерфейсе данные переменные уже будут предзаполнены и их можно поменять перед запуском. 

А еще чуть ниже описан механизм установки списка значений, из которых можно выбирать при создании пайплайна.

Тестовый пайплайн

Пробуем сделать так, как в документации, — добавить переменную с выбором. Добавляем .gitlab-ci.yml, переменную и тестовый первый джоб (т. к. без него не запустится пайплайн), получаем следующее:

stages:
  - build

variables:
  DEPLOY_ENVIRONMENT:
    value: "test_1"
    options:
      - "test_1"
      - "test_2"
      - "test_3"
    description: "The deployment target. Set to 'test_1' by default."

build:
  stage: build
  script:
    - echo "test build"
    - echo $DEPLOY_ENVIRONMENT

В данном примере считаем, что у нас есть три тестовых окружения, а в тестовом джобе просто выводим содержимое переменной. Далее пушим, видим, что у нас сразу запускается пайплайн, где устанавливается значение по умолчанию, т. е. «test_1»:

f1d498b0842f9b766ba49fe91c3dd7e9.png

Теперь попробуем создать пайплайн вручную, для этого переходим в список пайплайнов, нажимаем на кнопку создания пайплайна:

9bff1c12584e43bb76480d89544a85a5.png

В появившейся форме можно выбрать ветку (у нас пока только main) и можно указать значение нашей переменной, — для проверки поменяем на «test_2»:

96f367a6a75b41bdca18433f9309c135.png

Далее запускаем пайплайн, дожидаемся его выполнения:

aeb6adbe7ec180950303ba58cb57e198.png

И видим результат: значение переменной теперь «test_2»:

64c9ca0285385879f3c72da5bd20fc49.png

То есть, как видим, если запускать пайплайн вручную, можно влиять на значение переменных, — это, собственно, и есть параметризованный пайплайн. Если же пайплайн запускается автоматически по какому-то событию, то там всегда дефолтное значение.

Ограничение условий запуска пайплайна

Вернемся опять к Jenkins, параметризованные пайплайны там запускаются только вручную. Это объяснимо, так как в таких пайплайнах нужно заранее задавать параметры, что требует взаимодействия с пользователем, и автоматически запускать такие пайплайны нет особого смысла. Поэтому и нам надо сделать так, чтобы такие пайплайны запускались только вручную.

Для этого модифицируем наш джоб:

build:
  stage: build
  rules:
    - if: $CI_PIPELINE_SOURCE == "schedule"
    - if: $CI_PIPELINE_SOURCE == "web"
    - if: $CI_PIPELINE_SOURCE == "api"
    - if: $CI_PIPELINE_SOURCE == "trigger"
    - if: $CI_PIPELINE_SOURCE != "push"
      when: never
    - if: $CI_PIPELINE_SOURCE != "merge_request_event"
      when: never
  script:
    - echo "test build"
    - echo $DEPLOY_ENVIRONMENT

Добавился блок rules, в котором указываем условия срабатывания. В переменной CI_PIPELINE_SOURCE находится информация о том, как запускается пайплайн. В этом случае мы запрещаем запускать данный джоб, если был пуш или если был создан мерж-реквест. В остальных случаях джоб будет выполняться (и в этих случаях можем указывать свои параметры).

Приближенный к реальности пример

Теперь модифицируем наш CI/CD, чтобы он стал больше походить на реальный:

stages:
  - build

variables:
  IMAGE_NAME: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA
  DEPLOY_ENVIRONMENT:
    value: "test_1"
    options:
      - "test_1"
      - "test_2"
      - "test_3"
    description: "The deployment target. Set to 'test_1' by default."

.auth_in_registry: &auth_in_registry
  - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY

.docker_build: &docker_build
  - docker buildx create --use
  - docker buildx build --push --platform linux/amd64 -f docker/Dockerfile -t ${IMAGE_NAME} .
  - docker buildx stop
  - docker buildx rm

build:
  stage: build
  environment:
    name: ${DEPLOY_ENVIRONMENT}
  before_script:
    - *auth_in_registry
  image: docker:24.0.5
  services:
    - docker:24.0.5-dind
  rules:
    - if: $CI_PIPELINE_SOURCE == "schedule"
    - if: $CI_PIPELINE_SOURCE == "web"
    - if: $CI_PIPELINE_SOURCE == "api"
    - if: $CI_PIPELINE_SOURCE == "trigger"
    - if: $CI_PIPELINE_SOURCE != "push"
      when: never
    - if: $CI_PIPELINE_SOURCE != "merge_request_event"
      when: never
  script:
    - *docker_build

Что добавилось:

  • Переменная IMAGE_NAME: используется для удобства сборки и тегирования Docker-образов на основе коммитов.

  • Анкор .auth_in_registry: для аутентификации в реестре GitLab.

  • Анкор .docker_build: для сборки Docker-образа из Dockerfile.

  • В рамках джоба build используем анкоры выше, а также «Docker-in-Docker», чтобы делать сборку.

Также можно увидеть такую конструкцию:

  environment:
    name: ${DEPLOY_ENVIRONMENT}

Что она нам дает?
Во-первых, у нас под каждое тестовое окружение создается окружение в GitLab:

a1cbaf2c59a8f5b7426b84cc1895fc43.png

Можно отслеживать историю:

af28ed39f644b6f9e0727e165de85bf6.png

Во-вторых, мы таким образом можем удобно управлять переменными окружения в самом GitLab (не prefilled-переменными, а переменными проекта/группы в GitLab), то есть можно задавать для каждого тестового окружения свои значения.

0bcbca2a8860dd90db8906fe4ca6eda4.png

Заключение

Мы рассмотрели тему параметризованных сборок в GitLab и сделали пайплайн со стадией сборки образа. Далее по аналогии можно добавить стадии деплоя и тестирования, чтобы реализовать полный пайплайн тестирования функционала.

Полезные ссылки

Руководство по параметризованным сборкам Jenkins: https://for-each.dev/lessons/b/-ops-jenkins-parameterized-builds

Предварительно заполненные переменные в GitLab: https://docs.gitlab.com/ee/ci/pipelines/index.html#prefill-variables-in-manual-pipelines

© Habrahabr.ru