Полный .gitlab-ci.yml для Application-пакета

Уровень: expert ~55 мин Практика: Umami (продолжение M5) (MIT)

Что нужно знать перед уроком

  • M9.05 — semver-теги и релизный процесс — нужна модель релизного процесса перед сборкой полного пайплайна
  • M8.02 — Cache-репозитории — нужно понимание --cache-repo, используемого в build-стадии пайплайна

Что нужно знать перед уроком

Все предыдущие уроки M9 (15) — анатомия registry, линтеры, релизный процесс. M8 урок 2 — cache-репозитории. Этот урок собирает всё в единый, полный .gitlab-ci.yml.

Теория

Четыре стадии: setupbuildverifypublish

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
stages:
  - setup
  - build
  - verify
  - publish

variables:
  PACKAGE_BUILD_REPOSITORY: "$CI_REGISTRY_IMAGE/packages/umami"
  PACKAGE_BUILD_REPOSITORY_DEV: "$CI_REGISTRY_IMAGE/packages/umami-dev"

setup-tools:
  stage: setup
  script:
    - d8 package --help
    - trdl use werf 2 stable
  only:
    - merge_requests
    - main
    - tags

build-images:
  stage: build
  script:
    - werf build --repo "$PACKAGE_BUILD_REPOSITORY_DEV" --cache-repo "$PACKAGE_BUILD_REPOSITORY_DEV/cache"
  only:
    - merge_requests
    - main

verify-package:
  stage: verify
  script:
    - d8 package verify
  only:
    - merge_requests
    - main
    - tags

publish-dev:
  stage: publish
  script:
    - d8 package build --version "0.0.0-dev.$CI_COMMIT_SHORT_SHA" --repo "$PACKAGE_BUILD_REPOSITORY_DEV"
  only:
    - main

publish-prod:
  stage: publish
  script:
    - d8 package build --version "${CI_COMMIT_TAG#v}" --repo "$PACKAGE_BUILD_REPOSITORY" --sign --sign-cert "$SIGN_CERT" --sign-key "$SIGN_KEY"
  when: manual
  only:
    - tags

dev vs prod registry — раздельные потоки публикации

Разделение переменных PACKAGE_BUILD_REPOSITORY/PACKAGE_BUILD_REPOSITORY_DEV отражает практическую необходимость: dev-публикации (на каждый коммит в main, с версией вида 0.0.0-dev.<short-sha>) предназначены для внутреннего тестирования и не должны попадать в каталог, видимый конечным пользователям, тогда как prod-публикации (только по семверным тегам, с ручным подтверждением) — это именно то, что появляется в каталоге Application-пакетов кластера. Смешение этих потоков в одном registry-пути рискует случайно «протечь» непроверенной dev-сборкой в production-каталог.

Переменные PACKAGE_BUILD_REPOSITORY* полностью

Разобранные в M5 уроке 9 переменные окружения, дублирующие флаги d8 package build:

ПеременнаяСоответствующий флаг
PACKAGE_BUILD_REPOSITORY--repo
PACKAGE_BUILD_REPOSITORY_USER--user
PACKAGE_BUILD_REPOSITORY_TOKEN--token
PACKAGE_BUILD_SIGN_CERT--sign-cert
PACKAGE_BUILD_SIGN_KEY--sign-key

Использование переменных вместо явных флагов в CI-скрипте — стандартная практика, позволяющая хранить чувствительные значения (_TOKEN, _KEY) как защищённые (Protected+Masked) переменные GitLab CI, не встраивая их в текст самого .gitlab-ci.yml.

Ручной gate на prod через when: manual

when: manual в publish-prod — это именно тот механизм, который реализует «осознанное решение человека», разобранное в M9 уроке 5: job появляется в интерфейсе GitLab CI как доступный к запуску, но не выполняется автоматически даже при успешном прохождении всех предыдущих стадий — ответственный релиз-менеджер должен явно нажать «Run» после финальной проверки.

Частые ошибки и подводные камни

  • Публиковать dev- и prod-версии в один и тот же registry-путь. Это создаёт риск случайной публикации непроверенной сборки в production-каталог — необходимо явное разделение путей (как в примере, через отдельные переменные _DEV).
  • Хранить PACKAGE_BUILD_REPOSITORY_TOKEN/PACKAGE_BUILD_SIGN_KEY прямо в тексте .gitlab-ci.yml. Эти значения должны быть настроены как защищённые CI/CD-переменные проекта GitLab, а не как захардкоженные строки в конфигурации, попадающей в git-историю.
  • Забывать when: manual для production-публикации. Без явного ручного gate любой пуш тега автоматически публикует версию в production-каталог, доступный конечным пользователям — без возможности финальной проверки перед публикацией.
  • Пропускать стадию verify перед publish. Публикация без предварительной проверки pkglint рискует опубликовать пакет с проблемами, которые линтер обнаружил бы (структура, документация, лицензии).

Практика в кластере

Практики в кластере в этом уроке нет — материал относится к конфигурации CI-пайплайна.

Практика разработки

🧩 Практика урока: Umami (продолжение M5) · лицензия MIT

Соберите полный .gitlab-ci.yml для пакета Umami по образцу из теории, настройте защищённые переменные (PACKAGE_BUILD_REPOSITORY_TOKEN и подобные) в настройках GitLab-проекта, и проведите полный цикл: коммит в main → dev-публикация → создание тега → ручной запуск publish-prod.

Шпаргалка команд урока

1
2
git tag v0.1.0 && git push origin v0.1.0
# затем вручную запустить job publish-prod в интерфейсе GitLab CI

Полная шпаргалка .gitlab-ci.yml для Application — 📋 werf .

Вопросы для самопроверки

Зачем нужно раздельные переменные PACKAGE_BUILD_REPOSITORY и PACKAGE_BUILD_REPOSITORY_DEV?

Смешение потоков рискует протечь непроверенной сборкой в production-каталог.

Источник: Рекомендуемая литература

Что делает when: manual в job publish-prod?

Это реализация осознанного ручного gate на production-релиз.

Источник: Рекомендуемая литература

Где должны храниться значения PACKAGE_BUILD_REPOSITORY_TOKEN и PACKAGE_BUILD_SIGN_KEY?

Хранение секретов в тексте конфигурации, попадающем в git-историю, — небезопасная практика.

Источник: Deckhouse — Разработка Application-пакета

Почему стадия verify должна выполняться перед publish?

verify — защитный барьер перед необратимой публикацией версии.

Источник: Рекомендуемая литература

Рекомендуемая литература

Официальная документация

Статьи и блоги

Книги

  • Gene Kim, Jez Humble, Patrick Debois, John Willis. The DevOps Handbook. 2nd ed., 2021. ISBN 978-1942788003.

Связанные материалы