# Gitlab CI/CD

# Терминология

  • Runner (Gitlab Runner) - это сервер, на котором выполняются команды CI.
  • Runner executor - от этого зависит как runner выполняет команды.
  • Pipeline - набор стадий, через которые проходит сборка или тестирование проекта.
  • Job - какое-то действие в Pipeline. Например, запуск unit-тестов.
  • Stage - стадия в Pipeline, которая может выполнять одновременно несколько Job'ов.
  • CI / CD - абревиатура Continious Intergration (автоматическое тестирование) и Continious Deployment (деплой).

# Подключение проекта к CI/CD

Для этого нужно создайть файл .gitlab-ci.yml (документация).

# Рекомендации по написанию gitlab-ci.yml

  1. Как можно раньше заложите контроль качества кода: прогон тестов, проверка форматирования, статический анализатор кода.
  2. Файлы для ci, необходимо хранить в директории проекта ./ci (ci/bin, ci/chart и т.д.).
  3. Если для запуска тестов нужно поднять базу или другой сервис, используйте встренную фичу [Services] (https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#define-image-and-services-from-gitlab-ciyml)
  4. Не используйте Makefile для запуска команд в gitlab-ci. Файл Makefile используется только как инструментарий разработчика.
  5. Если нужно писать условия или многстрочный script, вынесите его в отдельный bash файл в директорию ci/bin.
  6. Если нужно передать артефакты из одной стадии в другую, используйте artifacts и dependencies. Обязательно устанавливайте артефактам expires_in. (Документация).
  7. Старайтесь сразу настроить стадию проверки успешности деплоя или артефактов.
  8. Один репозиторий должен создавать только один конечный артефакт или деплоить один сервис.

# Отладка

# YAML Linter

Зайдите в Gitlab, затем Проект > Pipelines > CI Lint.

# Логи job'ов

Зайдите в Проект > CI / CD > Jobs.

# Просмотр env-параметров:

Добавьте к спецификации job':

do_something:
  variables:
    CI_DEBUG_TRACE: "true"

# Локальная отладка

Вы можете запуска gitlab-runner локально, но у него есть ряд особенностей:

  1. Под должен быть закоммичен, т.к. при выполнении делается checkout.
  2. Не поддерживается extends.
  3. Не поддерживается глобальные (before|after)_script, image, services.
  4. Не поддерживается локальный кэш (можно настроить подключение на minio/s3.

Установка https://docs.gitlab.com/runner/install

После этого сможете запускать job'ы локально.

Пример с docker-executor:

gitlab-runner exec docker do_something

Пример с shell-executor:

gitlab-runner exec shell do_something

# Используйте Bash-файлы

Выносите код из секции script в bash-файлы, чтобы запускать и проверять скрипты локально.

# Тэги

  • docker - выполнение в контейнере (документация)
  • shell - выполнение в shell. Вы можете использовать только те утилиты, что были предусстановленны для runner'а.
  • ansible - если требуется запуск Ansible.
  • ruby - если требуется ruby. Рекомендуем ипользовать docker c объявлением image: ruby.

# DinD (Docker In Docker)

Если вы используете тег docker и вам также нужeн docker для сборки образа, используйте технику Docker in Docker (DinD).

.dind: 
  tags: [docker]
  image: docker
  services: 
    - docker:dind

build_image:
  extends: [.dind]
  stage: build  
  dependencies:
    - bundle
  script:
    - docker build
      --cache-from ${BUILDER_IMAGE}
      --build-arg APP_VERSION=${APP_VERSION}
      --build-arg TIMESTAMP=`date +%Y%m%d`
      --tag ${CI_REGISTRY_IMAGE}:latest
      --tag ${CI_REGISTRY_IMAGE}:${APP_VERSION}
      --file ci/docker/Dockerfile.build
      .

# Публикация образов в Gitlab Registry

  1. Настройте подключение:

    before_script:      docker login -u gitlab-ci-token -p ${CI_JOB_TOKEN} ${CI_REGISTRY};

CI_JOB_TOKEN и CI_REGISTRY - уже доступны) при запуске pipeline в CI/CD.

  1. Публикуйте с тегом, содиржащий полный адрес образа (doc):

    docker build -t GITLAB_REGISTRY:1443/group/subgroup/project . docker push GITLAB_REGISTRY:1443/group/subgroup/project

# Установка Git-тега из CI

В Gitlab еще не реализован механизм создания тегов через CI, но можно использовать API:

#!/usr/bin/env bash
set -e -x -o pipefail

curl -X POST --show-error --fail "https://${CI_SERVER_HOST}/api/v4/projects/${CI_PROJECT_ID}/repository/tags?ref=${CI_COMMIT_SHA}&tag_name=${APP_VERSION}&private_token=${GITLAB_TOKEN}"
  • GITLAB_URL - URL Gitlab'а.
  • CI_PROJECT_ID - ID проекта. Пробрасывается самим Gitlab CI.
  • CI_COMMIT_SHA - SHA коммита. Пробрасывается самим Gitlab CI.
  • APP_VERSION - версия продукта или деплоя.
  • GITLAB_TOKEN - персональный токен (Personal Access Tokens). Желательно использовать не свой токен, а создавать его у пользователя Bot.

# DRY

# Повышение производительности

  1. Выполняйте независимые друг от друга job'ы параллельно:

    stages:

    • checks

    check_1: stage: checks script: ... check_2: stage: checks script: ...

  2. Используйте cache и artifacts/dependencies. Cache - для кэширования результата и переиспользования в том же job'е. Artifacts - для использования результата в других job'ах.

  3. Используйте (parallel)[https://docs.gitlab.com/ee/ci/yaml/#parallel]