"Мне лень собирать пакеты" - идеальный CI/CD: используем компоненты GitLab для упрощения пайплайнов автосборки и публикации (Часть первая)

19 0

Вступление

Привет! Меня зовут Алексей Анецких, и да — я уже второй разработчик по имени Алексей в СТАРКОВ Групп. Первый, Алексей Присяжный, уже устал рассказывать про CI/CD, так что в этот раз он просто ткнул в меня пальцем и сказал: «Пиши. Ты же теперь в теме». Отлично, думаю. Писать, так писать.

Но для начала немного истории в стиле «как всё начиналось, когда мир был молод, а мы ещё не знали про GitLab Runner». Был сентябрь 2022-го. Конференция разработчиков в Ижевске. Алексей Присяжный вышел на сцену и впервые в партнёрской сети Directum честно признался: «Мне лень собирать пакеты». И не просто признался, а продемонстрировал, как можно перестать это делать — с помощью современных практик CI/CD. До этого всё выглядело уныло:

  • Запустили экспорт — ждём 10 минут;
  • Почистили в гите автоинкремент версий (самая доставучая фича);
  • Отправили пакет на публикацию — ещё 10 минут смотрим в окно;
  • Если что-то пошло не так, то повторять цикл до полного удовлетворения.

В 2022 году это выглядело как реликт эпохи динозавров. Поэтому пришлось организовать небольшую революцию в разработке.

Спустя год на Гильдии разработчиков, мы вернулись к теме — но теперь всё было по-другому. Благодаря Сергею Головнёву и Тимофею Губареву CI/CD в наших проектах перестал быть набором копипаст-скриптов и превратился в настоящую инфраструктурную платформу. А теперь — эстафета у меня. Мы же обещали рассказать на Club! Внимание — счастье можно получить только в экосистеме Gitlab!

Что изменилось?

  • Всё завернуто в GitLab Components — компоненты, которые можно подключить парой строк;
  • Больше не нужно писать и поддерживать огромные .gitlab-ci.yml — достаточно передать пару переменных;
  • Появилась автоматическая выгрузка пакетов в Nextcloud с автоочисткой старых версий (иначе сервер превратится в музей артефактов сборок 2022 года);
  • Добавили автогенерацию package.xml;
  • Планы на ближайшее будущее — статический анализ кода, чтобы некачественный код просто не прошёл дальше Git Push.

В общем, если раньше CI/CD был для избранных, то теперь он стал… ну, как включить чайник: налил, нажал, пошёл пить кофе. А про то, как именно мы этого добились — дальше в статье.

А кому скучно читать и хочется пощупать код, то можете посмотреть его в репозитории: https://github.com/STARKOV-Group/Completed-RXDTDeploy-Component.

Что это такое и что оно может?

На тему самого CI/CD уже есть несколько статей (тут и тут), так что подробно останавливаться мы на этом не будем, но придется затронуть краеугольный камень всего проекта — компоненты CI/CD. Если коротко, то это переиспользуемые блоки конфигурации пайплайна, которые можно соединять между собой. Для общего понимания этой информации хватит, но если хочется углубиться в тему, то есть хорошая статья на Хабре.

Всего было создано 7 компонент:

  • Ручной старт. Название говорит само за себя, эта компонента предназначена для ручного запуска пайплайна, когда он удобнее автоматического запуска. Например, при слиянии сразу нескольких веток одновременно;
  • Подготовка переменных. В этой компоненте проверяется наличие необходимых переменных и директорий в остальных компонентах;
  • Подготовка сервера. Подготовка сервера для сборки пакета. Создание недостающих директорий, очистка существующих директорий, обновление конфигурации DDS согласно указанным переменным, подтягивание указанных веток гита, создание xml для создания пакета;
  • Сборка пакета. Как ни удивительно, сборка пакета с помощью DDS и собранной утилитой xml;
  • Публикация пакета на сервер. Публикация на указанный сервер с помощью DTCore;
  • Выгрузка в корпоративное облако. Выгрузка в облако NextCloud с помощью ещё одной утилиты;
  • Ну и наконец, общая компонента, по факту это собрание всех предыдущих компонент и инициализация значений по умолчанию.

Для корректной работы нужно подключить не 5, не 3, и даже не 2 компонента. Всё, что нужно сделать в проекте, для которого мы хотим настроить всё это великолепие, это добавить в пайплайн всего одну компоненту, что правит всеми, и передать необходимые переменные. Всё. По крайней мере, это верно для конечного пользователя. Администратору ещё необходимо создать и настроить раннер (runner) на сервере, подключить его в GitLab, создать все необходимые директории, своевременно добавлять новые версии DDS и DT. Но это — необходимое зло, честно! И в итоге займет намного меньше времени, чем сэкономит.

Подключаем компоненты: два шага для счастья

Представим, что вы усталый разработчик, который постоянно собирает и публикует пакеты на тест. Что нужно сделать, чтобы больше этим не заниматься? Предположим, что сервер с раннером уже настроен и вы, как и мы, используете свой собственный экземпляр GitLab’а (что я очень советую делать). Тогда всё, что остается сделать — это подключить раннер к проекту и написать в корневом каталоге репозитория Work в файл .gitlab-ci.yml:

variables:
  RXVERSION: 25.2.0.39
  Repositories:
    Base | ssh://git@git.domain.ru:8022/ivanov/project-base.git | test,
    Work | ssh://git@git.domain.ru:8022/ivanov/project-work.git | test

include:
  - remote: 'https://raw.githubusercontent.com/STARKOV-Group/Completed-RXDTDeploy-Component/refs/heads/remote/templates/Completed-RXDTDeploy-Component.yml'

Если же вы захотите склонировать на свой экземпляр гитлаба эти репозитории, то там уже подключать придётся так (разница remote -> component):

variables:
  RXVERSION: 25.2.0.39
  Repositories:
    Base | ssh://git@git.domain.ru:8022/ivanov/project-base.git | test,
    Work | ssh://git@git.domain.ru:8022/ivanov/project-work.git | test

include:
  - component:  $CI_SERVER_FQDN/ci-cd-components/Completed-RXDTDeploy-Component/Completed-RXDTDeploy-Component@main

И создать переменные проекта через UI GitLab:

Название переменной

Значение переменной

DeployUserName

Service User

DeployUserPassword

password

DeployIpServer

10.19.3.22

Как это выглядит в самом GitLab:

Не так уж и страшно, правда? А теперь немного разберемся, что тут написано:

  • В RXVERSION записана версия платформы, включая минорные версии. Это — фрагмент пути до дистрибутива конкретной версии на сервере сборки;
  • В Repositories указываются репозитории, используемые в проекте;
  • DeployUserName и DeployUserPassword — это логин и пароль пользователя, под которым будет публиковаться пакет;
  • DeployIpServer — адрес стенда (можно с хостом), на который собираемся публиковать;
  • В include: component (или remote) лежит ссылка на компонент;

Некоторые настройки, которые необходимы для работы мы не указали, так как они имеют значение по умолчанию:

  • WebProtocol — протокол по которому будет происходить соединение, по умолчанию указан http;
  • ServerHttpPort — порт по которому будет происходить соединение, по умолчанию 80;
  • RunnerTags — теги по которым будет подбираться раннер для выполнения.

Самые внимательные заметили, что мы используем SSH-ссылки вместо HTTPS. Это упрощает доступ: например, если раннер запущен от системной учётной записи (а он ставится так по умолчанию), впервые авторизоваться на GIT сервер будет проблемой (задачка — как в контексте пользователя СИСТЕМА получить окно авторизации в GIT; задачка со звёздочкой — как оправдаться после этого перед безопасником), при этом SSH-ключи решают эту проблему простым образом, и можно гибко настроить срок их жизни.

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

Настройка раннера: инструкция для администраторов (и их нервных клеток)

Установка раннера достаточно подробно указана в официальной документации и статье на клабе, так что углубляться не будем. Но хочется указать на несколько нюансов:

  • Язык системы (и пользователя) должен быть English (USA), для того чтобы избежать проблем с кодировкой (сейчас GitLab runner не поддерживает кодировки, отличные от UTF-8);
  • Установить свежий Powershell (или в .toml файле указать shell = "powershell", если раннер работает на Windows со старыми версиями powershell).

И вот у нас есть раннер, что дальше? А дальше уже настроить работу по ssh для подключения к репозиториям. Для этого необходимо сгенерировать ssh ключ на машине раннера (лучше из контекста того же пользователя, под которым и будет работать раннер) и добавить его в GitLab.

Затем необходимо поставить ПО, необходимое для DDS и DT. ВАЖНО УЧЕСТЬ, что начиная с версии 25.1 был обновлен .Net, а значит для версий вплоть до 4.12 желательна отдельная машина с отдельным раннером, иначе могут быть ошибки при сборке пакетов.

Ну и под конец самое простое - добавить нужные папки и утилиты:

Корневая папка CICD, а в ней подкаталоги:

  • DDS, для экземпляров Directum Development Studio;
  • DTCore, для экземпляров Deployment Tool Core;
  • Projects, в которых будут храниться данные проектов;
  • Tools, в которых лежат утилиты по созданию xml и выгрузке в облако.

Общий вид:

CICD
├──DDS               # все нужные версии среды разработки
│     ├──25.1
│     ├──25.1.1.1
│     └──25.2.0.39
├──DTCore            # все нужные необходимые версии DeploymentToolCore
│     ├──25.1
│     ├──25.1.1.1
│     └──25.2.0.39
├──Projects          # каталог для клонированных репозиториев и сборки
└──Tools
       ├──NextCloudConnector
       └──PackageXMLGenerator

Также нужно создать экземпляры конфигурационных файлов для DT и DDS, с помощью которых будут задаваться настройки для публикации и сборки пакетов, соответственно.

В папке DDS нужно создать файл _ConfigSettings.xml.example на основе файла по умолчанию. Он будет шаблоном для создания персонального конфига для DDS:

<?xml version="1.0" encoding="utf-8"?>
<settings>
  <var name="GIT_ROOT_DIRECTORY" value="d:\Projects" />
  <block name="REPOSITORIES">
    <repository folderName="base" solutionType="Base" url="" />
    <repository folderName="work" solutionType="Work" url="" />
  </block>
…

Аналогичный _ConfigSettings.xml.example нужно создать в папке DTCore, ключевые значения будут заменены:

<?xml version="1.0" encoding="utf-8"?>
<settings>
  <var name="SERVER_ROOT" value="localhost" />
  <var name="SERVER_HTTP_PORT" value="80" />
…
</settings>

И последнее, и самое главное — загрузить необходимые версии DDS и DT в соответствующие папки. Так как раннер будет искать их по названию, совпадающим со значением переменной RXVERSION, то лучше называть их полной версией используемого RX. После этого можно смело пробовать запустить пайплайн — PUSH в ветку, но обратите внимание: в данный момент у нас в примере конфига явно задана ветка test, так что публиковаться всегда будет её актуальное состояние, даже при пуше в мастер ветку.

Если даже после этого осталось желание понять, а как же именно это всё работает (и как собрать свой пайплайн мечты, с несколькими ветками и контурами), то милости прошу дальше… во вторую часть, которая выйдет чуть позже. Эта статья и так разрослась до приличных размеров.

И что в итоге?

А в итоге у нас получается очень удобный и расширяемый инструмент для сбора, публикации и выгрузки пакетов для разных веток, разных проектов, на разных версиях Directum RX. Я крайне рекомендую попробовать поиграться с настройками и создать свой пайплайн.

А пока… Всех с наступающим Новым Годом! Увидимся во второй части уже в 2026 году, где мы разберем детали работы компонентов!

Пока комментариев нет.

Авторизуйтесь, чтобы написать комментарий