rzaripov.kz

Как настроить CI/CD для Delphi-проекта с помощью GitLab и Docker

Автоматизация сборки Delphi-приложения помогает сократить число ручных операций, быстрее находить ошибки и выпускать предсказуемые версии для Windows. GitLab CI/CD подходит для хранения исходного кода, запуска проверок, формирования установочных пакетов и публикации артефактов, а Docker делает окружение сборки воспроизводимым.

У Delphi есть особенность: полноценная компиляция обычно выполняется в Windows, поскольку проект зависит от Delphi Compiler, MSBuild, библиотек FireMonkey или VCL и установленных SDK. Поэтому оптимальная схема часто сочетает Windows Runner для сборки приложения и контейнеры для вспомогательных задач: статического анализа, упаковки, генерации документации и публикации результатов.

Подход Где выполняется сборка Преимущества Ограничения
Windows Runner без Docker На выделенной Windows-машине Простая интеграция с Delphi IDE и лицензией Сложнее воспроизводить окружение
Windows-контейнер В Windows Docker-контейнере Изоляция зависимостей и одинаковая среда Требуются Windows Server или Windows 10/11 и подходящие образы
Гибридная схема Delphi — на Windows, служебные задачи — в Linux Docker Практичный баланс скорости и совместимости Нужно настроить несколько типов Runner
Полностью Linux Docker Только в Linux-контейнере Дешёвые и быстрые Runner Непригодно для обычной нативной сборки Delphi под Windows

Архитектура конвейера

Типичный pipeline состоит из этапов prepare, build, test, package и deploy. На подготовительном шаге проверяются переменные, версии зависимостей и структура репозитория. Затем Windows Runner собирает проект командой MSBuild или консольным компилятором Delphi, после чего автоматические тесты проверяют основные модули.

На этапе упаковки формируется ZIP-архив, установщик Inno Setup или комплект файлов для последующего развёртывания. GitLab сохраняет результат как job artifact, а отдельный этап публикации может отправить файл в Package Registry, на внутренний сервер или в релиз GitLab. Такая последовательность разделяет компиляцию и доставку, поэтому неудачная публикация не требует повторной сборки.

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

Подготовка Docker-образа

Docker-образ должен содержать все инструменты, которые нужны конкретному этапу. Для Linux-задач подойдут официальные образы с PHP, Python, Node.js или утилитами упаковки. Для Delphi-сборки потребуется Windows-образ, совместимый с версией операционной системы хоста. В него устанавливают Delphi command-line tools, MSBuild, Git, NuGet и дополнительные SDK.

Установка Delphi в образ должна учитывать лицензионную модель Embarcadero. Дистрибутив и лицензионные ключи нельзя бездумно добавлять в публичный Dockerfile или отправлять в открытый Container Registry. Обычно образ собирают во внутреннем реестре, а секреты передают через защищённые переменные GitLab или временный файл конфигурации.

Пример упрощённого Dockerfile для служебного Linux-этапа может выглядеть так:

FROM ubuntu:22.04

RUN apt-get update && \
    apt-get install -y git zip unzip ca-certificates && \
    rm -rf /var/lib/apt/lists/*

WORKDIR /build

Версию базового образа лучше фиксировать явно. Использование плавающего тега latest может неожиданно изменить набор системных библиотек и привести к различиям между сегодняшней и завтрашней сборкой.

Настройка GitLab Runner

Для компиляции Delphi регистрируют GitLab Runner на Windows-компьютере, где уже установлены нужная версия RAD Studio, лицензия, SDK и драйверы, если они необходимы приложению. В качестве executor часто выбирают shell: команда запускается непосредственно в Windows-среде, а Docker применяется для других jobs. Если инфраструктура поддерживает Windows containers, можно использовать Docker executor, но совместимость образа и хоста нужно проверять заранее.

Runner получает тег, например delphi-windows. Этот тег указывают в job сборки, чтобы GitLab не отправил задачу на Linux-агент. Для упаковки можно зарегистрировать отдельный Linux Runner с тегом docker-linux. Такое разделение упрощает обслуживание и позволяет масштабировать компиляцию независимо от публикации.

После регистрации стоит проверить запуск команд вручную от имени той же учётной записи, под которой работает служба Runner. Частые проблемы возникают из-за отсутствия переменной PATH, недоступного сетевого диска, неверной кодировки консоли или лицензии, активированной для другого пользователя. Диагностическая job с командами ver, where msbuild и выводом версии компилятора быстро выявляет подобные расхождения.

Описание файла .gitlab-ci.yml

Конфигурация pipeline хранится в корне репозитория в файле .gitlab-ci.yml. В ней задаются стадии, кэш, артефакты, правила запуска и теги Runner. Пример минимальной схемы:

stages:
  - build
  - test
  - package

build_delphi:
  stage: build
  tags:
    - delphi-windows
  script:
    - msbuild App.dproj /t:Build /p:Config=Release /p:Platform=Win32
  artifacts:
    paths:
      - bin/Release/
    expire_in: 7 days

run_tests:
  stage: test
  tags:
    - delphi-windows
  script:
    - bin\Release\AppTests.exe

package_app:
  stage: package
  image: ubuntu:22.04
  script:
    - apt-get update && apt-get install -y zip
    - zip -r app-${CI_COMMIT_SHORT_SHA}.zip bin/Release/
  artifacts:
    paths:
      - app-*.zip

В реальном проекте путь к .dproj, имя конфигурации и платформа могут отличаться. Для Win32 и Win64 лучше создать отдельные jobs либо матрицу, чтобы видеть результат каждой целевой платформы. Переменные CI_COMMIT_SHORT_SHA, CI_COMMIT_TAG и CI_PIPELINE_ID удобно использовать в имени файла и версии сборки.

Правила запуска можно ограничить так, чтобы тесты выполнялись на каждой ветке, а публикация — только для тега:

release:
  stage: package
  script:
    - echo "Публикация релиза"
  rules:
    - if: '$CI_COMMIT_TAG'

Тестирование, артефакты и релизы

Для Delphi-проекта полезно разделять модульные тесты, интеграционные проверки и запуск приложения. DUnitX или другой тестовый фреймворк можно вызывать из консоли, сохраняя XML-отчёт в формате JUnit. GitLab тогда покажет количество успешных и неуспешных тестов непосредственно в интерфейсе pipeline.

test_units:
  stage: test
  tags:
    - delphi-windows
  script:
    - bin\Release\Tests.exe --format=junit --output=test-results.xml
  artifacts:
    when: always
    reports:
      junit: test-results.xml

Артефакты следует сохранять только на нужный срок. Исполняемые файлы, логи и отчёты могут быстро занять место, особенно если pipeline запускается на каждый commit. Для длительного хранения релизов лучше использовать GitLab Releases или Package Registry, а временные результаты удалять через expire_in.

Перед публикацией стоит проверить хеши файлов, номер версии и наличие обязательных DLL или ресурсов. Если приложение использует внешнюю базу данных, интеграционный этап можно запускать вместе с контейнером PostgreSQL, MySQL или другой тестовой СУБД. Это позволяет проверить миграции и работу слоя доступа к данным до передачи сборки заказчику.

Безопасность и обслуживание конвейера

Секреты не должны находиться в .gitlab-ci.yml, Dockerfile или исходном коде. Токены, пароли, ключи подписи и параметры подключения добавляют в GitLab CI/CD Variables с признаками Masked и Protected. Подписывать Windows-приложение лучше на отдельном защищённом Runner, доступном только для доверенных веток и тегов.

Зависимости нужно фиксировать: версии библиотек Delphi, сторонних компонентов, Docker-образов и инструментов упаковки должны быть известны pipeline. Для ускорения можно кэшировать каталоги скачанных пакетов, но кэш не должен подменять артефакты конкретной сборки. После изменения компилятора или SDK кэш рекомендуется очистить.

Логи pipeline помогают поддерживать систему в рабочем состоянии. Полезно сохранять текст компилятора при ошибке, выводить версии инструментов в начале job и устанавливать ограничения времени выполнения. Если сборка стала медленной, сначала проверяют повторное скачивание зависимостей, антивирусное сканирование и доступ к сетевому хранилищу, а затем выносят независимые проверки в параллельные jobs.

Такая конфигурация превращает GitLab в единый центр контроля исходного кода, проверок и релизов, а Docker фиксирует окружение там, где это технически возможно. Windows Runner сохраняет совместимость с Delphi, а гибридная модель позволяет использовать преимущества контейнеров без попытки перенести нативную компиляцию в неподходящую Linux-среду.