GitLab CI

Непрерывная интеграция (CI) — это способ автоматического тестирования, сборки и проверки вашего кода при каждом внесении изменений.

GitLab предоставляет встроенные функции CI/CD через файл .gitlab-ci.yml. Этот файл, помещенный в корень вашего репозитория, сообщает GitLab, как собирать и тестировать ваш проект. Он определяет этапы и сценарии, которые запускаются в чистой среде каждый раз, когда вносятся изменения.

В этом документе описывается, как работает конвейер Lumi GitLab CI/CD, включая роль файла .gitlab-ci.yml, сценариев оболочки и внешних инструментов, таких как Meson и Ninja.

Подробную техническую документацию по процессу сборки Lumi CI см. в README-CI.md в репозитории.

Основы GitLab CI/CD

ЭК управляется файлом с именем .gitlab-ci.yml. Этот файл определяет:

  • Этапы: упорядоченные группы заданий (например, build-this, build-that, package-up)
  • Задания: отдельные задачи для выполнения на каждом этапе.
  • Сценарии: команды оболочки, выполняемые для каждого задания.
  • Исполнители: компьютеры, которые GitLab использует для запуска заданий, определенных в конвейере.

В Lumi этапы конвейера следующие:

  • dependencies
  • build lumi
  • appimage

Сборки на основе контейнеров

Конвейер Lumi использует контейнеризацию для согласованных сборок:

  1. Создание контейнера сборки. На первом этапе Buildah используется для создания образа Docker со всеми зависимостями.
  2. Использование контейнера: последующие этапы выполняются внутри этого контейнера, обеспечивая согласованность среды.
  3. Воспроизводимые сборки: изоляция контейнера гарантирует одинаковые результаты для разных бегунов.

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

Интегрированные источники зависимостей

Образ зависимостей CI Lumi создает разветвленный стек из интегрированных источников (а не внешних клонов):

  • lumi-babl/ (БАБЛ)
  • lumi-gegl/ (GEGL)
  • lumi-gtk3/ (GTK3)

Эти каталоги копируются в контекст сборки контейнера и компилируются в префикс зависимости (обычно /opt/lumi-deps). Это обеспечивает воспроизводимость CI и гарантирует, что сборка AppImage использует тот же источник достоверных данных, что и локальная разработка.

Роль сценариев оболочки

Задания в .gitlab-ci.yml обычно вызывают команды оболочки напрямую. Сложные операции часто выносятся в отдельные скрипты, хранящиеся в репозитории.

Lumi CI использует модульные сценарии оболочки для организации логики сборки:

Пример вызова скрипта:

script:
  - bash build/linux/appimage/lumi-goappimage.sh 2>&1 | tee appimage_creation.log

Преимущества этого подхода:

  • Очистить YAML: сохраняет структуру задания в файле .gitlab-ci.yml.
  • Удобство обслуживания: сложную логику легче отлаживать и изменять в сценариях оболочки.
  • Повторное использование: сценарии можно использовать в разных контекстах и средах.
  • Модульность: различные аспекты сборки можно разделить на отдельные сценарии.

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

Интеграция с системами сборки

Люми использует Meson и Ninja для подготовки и последующей сборки кода.

Например:

script:
  - meson setup _build-${CI_RUNNER_TAG} -Dprefix="${LUMI_PREFIX}"
  - ninja -C _build-${CI_RUNNER_TAG}
  - ninja -C _build-${CI_RUNNER_TAG} install

Здесь:

  • meson setup подготавливает каталог сборки и генерирует build.ninja
  • ninja запускает команды сборки, как определено

Структура системы сборки мезонов

Система сборки Meson использует корневой файл meson.build, расположенный в корневом каталоге проекта. Этот файл определяет конфигурацию сборки верхнего уровня и точку входа для процесса сборки.- Корень meson.build обычно находится в том же каталоге, что и .gitlab-ci.yml.

  • Отсюда он рекурсивно распределяется по подкаталогам, в каждом из которых может быть свой собственный файл meson.build.
  • Эти файлы подкаталогов определяют цели, источники, зависимости и инструкции сборки, относящиеся к этому каталогу.

Переменные среды

Ключевые переменные в конвейере Lumi включают:

variables:
  DEBIAN_FRONTEND: "noninteractive"  # Prevents interactive prompts
  DEB_VERSION: "trixie"              # Debian version for consistency
  CI_RUNNER_TAG: "x86_64"            # Architecture specification

Переменные, специфичные для задания:

build-lumi:
  variables:
    COMPILER: "clang"                                           # Compiler selection
    LINKER: "lld"                                               # Linker selection
    LUMI_PREFIX: "${CI_PROJECT_DIR}/_install-${CI_RUNNER_TAG}"  # Installation path
    DEPS_PREFIX: "/opt/lumi-deps"                               # Prebuilt dependency prefix
    MESON_OPTIONS: "-Dpkgconfig.relocatable=true -Drelocatable-bundle=yes"  # Build configuration

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

Пример структуры

project-root/
├── .gitlab-ci.yml
├── meson.build              <-- Root Meson file
├── src/
│   ├── meson.build          <-- Subdirectory Meson file
│   └── some_source.c
├── data/
│   ├── meson.build
│   └── icons/

В этой структуре:

  • Корневой файл meson.build настраивает общую среду сборки.
  • Файлы подкаталога meson.build содержат сведения о компиляции для конкретных компонентов или модулей.
  • Эта иерархическая структура делает логику сборки модульной и удобной в обслуживании.

Артефакты между этапами

Артефакты — это файлы, созданные заданиями, которые необходимы на последующих этапах:

build-lumi:
  # ...job configuration...
  artifacts:
    paths:
      - "${LUMI_PREFIX}/"      # Installation files
      - _build-${CI_RUNNER_TAG}/meson-logs/meson-log.txt  # Build logs

Этапы конвейера и зависимости

Конвейер Lumi состоит из трех основных этапов:

  1. Зависимости: создает контейнерную среду сборки со всеми необходимыми инструментами и библиотеками.
  2. Сборка Lumi: компилирует Lumi с использованием Meson и Ninja в подготовленной среде.
  3. AppImage: упаковывает встроенное приложение в распространяемый формат AppImage.

Зависимости этапов:

build-lumi:
  needs: [deps-debian]  # Waits for dependency container

lumi-appimage:
  needs: [build-lumi] # Waits for application build

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

Текущие имена заданий

Lumi .gitlab-ci.yml в настоящее время определяет следующие имена заданий:

  • deps-debian
  • build-lumi
  • lumi-appimage

Резюме

  • .gitlab-ci.yml определяет структуру и логику конвейера
  • Задания содержат команды оболочки или внешние скрипты.
  • Такие инструменты, как Meson и Ninja, используются внутри заданий как часть процесса сборки.

Lumi использует GitLab CI для автоматической сборки AppImage для платформ на базе Debian. Конвейер создает зависимости, компилирует Lumi, а затем упаковывает AppImage.

Для получения подробной информации на уровне источника используйте:

  • .gitlab-ci.yml в корне репозитория Lumi
  • build/linux/appimage/lumi-goappimage.sh
  • build/linux/appimage/README-CI.md

Подробные технические сведения о процессе сборки Lumi CI, включая настройку среды, архитектуру сценариев и устранение неполадок, см. в README-CI.md.