Версионируем куски пайплайнов в gitlab-ci

0
(0)

Предположим у нас есть некий репозиторий в gitlab-ci, давайте назовем его devops-ci. Там мы храним куски наших пайплайнов, которые в конечных проектах подключаем через опцию extends и используем либо в первозданном виде, либо с неким переопределением на уровне проекта, напомню, что extend делает именно «мердж» ямла.

Все это мы подключаем в конечном проекте в .gitlab-ci.yml например вот так:

YAML
include:
- project: "root_group/devops-ci"
    ref: <version>
    file:
      - "path/to/file.yaml"

В поле ref можно указать версию нашего «общего» CI.

Для версионирования удобно использовать git tag, но здесь есть нюанс в том, что зарезирвированная переменная gitlab CI_COMMIT_REF_SLUG, которую часто используют в логики CI это и CI_GIT_TAG это одно и тоже. Говоря проще, когда мы комитим тег, для гита тег равняется имени ветки, так он по сути именем ветки и является.

Давайте попробуем реализовать версионирование, учитывая это.

Создаем в корне файл versions.yaml

YAML
version: 
  main: "v1.0.0"
  other: "v0.0.1"

Пишем стейдж для создание релизного тега:

YAML
make_ci_tag:
  stage: make_ci_tag
  variables:
    VERSION_FILE: "versions.yaml"
  before_script:
    - |
       if [[ $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH ]];then
         TAG_VERSION=$(cat $VERSION_FILE | grep main | awk '{print $2}' | tr -d '"')
       else
         TAG_VERSION=$(cat $VERSION_FILE | grep other | awk '{print $2}' | tr -d '"')
       fi;
       echo -e "\033[0;32mTag nubmer: $TAG_VERSION\e[0m"
  script:
    - git tag | xargs git tag -d || true
    - git config --global user.name "${GITLAB_USER_NAME}"
    - git config --global user.email "${GITLAB_USER_EMAIL}"
    - git tag -a $TAG_VERSION -m "CI tag was created by ${GITLAB_USER_NAME}"
    - git push https://tag_access_token:${TAG_ACCESS_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git $TAG_VERSION -o ci.skip
  rules:
    - if: '$CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
      when: always
    - if: '$CI_MERGE_REQUEST_IID && $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH'
      when: always
    - if: '$CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
      when: never
    - if: '$CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH'
      when: always

Разберем логику работы:

В before_script мы «парсим» наш файл, если имя ветки комита равно дефолтной ветки, мы предполагаем, что это шаг будет после мердж комита, следовательно мы получаем версию из main файла versions.yaml. Если комит был в любую другую ветку, то берем other и присваиваем тег переменной TAG_VERSION. Так на этапе МР или еще до его создания мы всегда можем протестировать в конечном проекте наши изменения указав нужную версию.

В секции script основная логика того, как будет создан git tag. Вначале мы «очищаем» наше пространство от любых возможных тегов. Это нужно для активной параллельной разработки в нашем CI, учивая, что джоб может оказаться на том же раннере, что и у вашего коллеги.

Затем выставляем глобальныe переменные гиту из зарезервированных переменных gitlab-ci. Делаем комит используя команду git tag и делаем push в наш репозиторий, используя access token, зарезервированные переменные gitlab-ci и опцию -o ci.skip. Как раз она и нужна нам, чтобы избежать дублирования запуска джобов, потому что когда мы делаем git push вместе с тегами, создастся джоб для нашей ветки, например «dev» и для тега, например «v0.0.1», а мы хотим видеть запуск джобы только для комита тега.

В конце описываем правила:

YAML
- if: '$CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
  when: always

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

YAML
 - if: '$CI_MERGE_REQUEST_IID && $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH'
   when: always

Всегда запускаем, если есть идентификатор МР и ветка комита не равна дефолтной ветки.

YAML
 - if: '$CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
   when: never
 - if: '$CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH'
   when: always

Эти два правила нужны, чтобы избежать дублей при комите в ветку, при наличии МР.

Тем самым мы получаем «подконтрольное» версионирования нашего CI, без необходимости делать git tag локально.

Насколько статья полезна?

Нажмите на звезду, чтобы оценить!

Средняя оценка 0 / 5. Количество оценок: 0

Оценок пока нет. Поставьте оценку первым.

Оставить комментарий