GitLab CI/CD: переменные и границы секретов
Курс «Лаборатория GitLab CI/CD»
Каталог course-card пока всегда имеет одно название. Введём переменную SITE_TITLE, чтобы показать конфигурацию, не меняя генератор при каждом варианте. Затем передадим вычисленные сведения о сборке через dotenv-артефакт. Это два разных момента: исходные переменные доступны до работы, а значения из файла появляются после завершения производителя.
Одновременно разберём секреты. Учебный pipeline не обращается к внешнему серверу и не требует настоящих токенов. Однако важно понимать, почему секрет нельзя положить в .gitlab-ci.yml, release.json или кэш. Эти файлы распространяются иначе, чем специально ограниченное значение окружения.
Не секретная конфигурация
Добавьте в общий файл переменную с названием сайта. Полный build.mjs читает её из process.env и экранирует перед вставкой в HTML, как остальные текстовые данные. Если переменная не задана, используется «Каталог учебных курсов».
variables:
SITE_TITLE: 'Маршрут — каталог курсов'
Такое значение можно хранить в репозитории: оно предназначено для публичной страницы. Изменение SITE_TITLE меняет результат сборки и должно отражаться в метаданных. Это не просто подпись журнала. Программы должны различать переменные, которые влияют на bytes выпуска, и диагностические сведения, которые описывают среду.
Не используйте названия встроенных переменных GitLab для собственных параметров. Подмена CI_COMMIT_SHA скрыла бы реальное происхождение артефакта. Выберите отдельное смысловое имя. В нашей лаборатории SITE_TITLE описывает содержание, а сведения CI читаются как контекст конкретного задания.
Созданные значения и dotenv
После сборки программа пишет build.env с BUILD_COMMIT и BUILD_PIPELINE. Эти сведения не являются секретами. Сохраним файл как dotenv report вместе с артефактом сайта:
artifacts:
paths:
- dist/
reports:
dotenv: build.env
expire_in: 7 days
В следующем job переменные становятся доступными при получении этого отчёта согласно зависимости. При этом release.json остаётся главным описанием результата на диске. Dotenv удобен для коротких значений окружения, но не заменяет проверку содержимого файлов. Позднее staging сверит метаданные, а не доверится единственной строке имени версии.
Формат dotenv имеет ограничения: используем простые строки NAME=value без сложных многострочных данных. Не пытайтесь передать в нём большой JSON со случайным экранированием. Для структурированных сведений уже есть отдельный файл артефакта. Разделение форматов делает передачу понятной и уменьшает число скрытых преобразований.
Момент применения
Rules оцениваются до выполнения job. Поэтому BUILD_COMMIT, записанный генератором, нельзя использовать для включения самого build или другого job в тот же pipeline. Значение ещё не существует в момент составления графа. Для выбора работы используйте доступные заранее переменные события, а результат программы передавайте потребителю после выполнения.
Рассмотрим ошибочное намерение: «Если build нашёл новые курсы, добавить verify». Граф уже определён, когда build начинает читать JSON. В такой задаче потребуются другие способы организации процесса, например условная проверка внутри заранее включённого job или отдельный динамический pipeline. В лаборатории verify всегда обязателен, поэтому нет причины усложнять граф таким условием.
Подробные виды и области переменных описаны в документации CI/CD variables, а reports — в справочнике YAML. Мы используем лишь небольшой набор, сохраняя его назначение явно. Большое число скрытых значений быстро делает проект зависимым от настроек, отсутствующих в репозитории.
Секрет не становится безопасным от звёздочек
Для настоящего внешнего доступа переменную создают в подходящем разделе настроек проекта или используют специальное хранилище секретов. Маскирование помогает не показывать значение в обычном журнале, но не делает произвольную программу безопасной. Код job может отправить значение наружу, изменить форму вывода или прочитать файл. Поэтому доверие к коду и runner остаётся обязательным.
Protected ограничивает доступ по защищённым контекстам, а masked и hidden относятся к другим сторонам отображения. Эти свойства не взаимозаменяемы. Не следует назначить только masked и считать, что любая ветка теперь безопасно получает рабочий токен. Условия доступа нужно сопоставить с workflow, правами Merge Request и назначением конкретного job.
Если переменная имеет тип File, её значением в job становится путь к временно подготовленному файлу. Программа должна читать этот файл, а не интерпретировать путь как содержимое сертификата или ключа. Для лаборатории такие данные не требуются. Мы объясняем механизм, не добавляя фиктивный секрет, который читатель мог бы случайно принять за реальный доступ.
| Значение | Где хранится | Можно ли включать в выпуск |
|---|---|---|
| SITE_TITLE | YAML или настройки | Да, это текст страницы |
| BUILD_COMMIT | Dotenv и release metadata | Да, если сведения допускаются проектом |
| Токен внешней отправки | Ограниченная переменная/хранилище | Нет |
| Содержимое приватного ключа | Ограниченный file secret | Нет |
Для каждого параметра полезно записать владельца и способ изменения. SITE_TITLE может редактировать автор учебного каталога; runner authentication token обслуживает администратор инфраструктуры; BUILD_COMMIT создаёт система текущей работы. Если все значения собраны в одном списке «переменных проекта» без этих различий, сопровождение становится рискованным и непонятным. В архиве сохранены только несекретные defaults и программы чтения. Настоящий чувствительный параметр не следует добавлять как красивый placeholder в готовый YAML, если job его вообще не использует. Предметный договор позволяет оставить минимальный необходимый набор значений.
Dotenv-файл содержит короткие строки KEY=value, предназначенные для последующих jobs. Он не является произвольным текстовым документом с комментариями, многострочным HTML или JSON. В нашем генераторе commit и pipeline ограничены простыми символами, поэтому запись двух строк имеет понятную структуру. Если нужно передать сложный объект, оставьте его в файловом артефакте и явно прочитайте парсером. Не пытайтесь упаковать всю спецификацию выпуска в одну переменную ради удобства. Для отладки достаточно назвать полученное поле и его безопасное значение, сохраняя основной договор в release.json.
Диагностика без утечки
Не печатайте весь process.env и не включайте set -x для job, который работает с чувствительными значениями. Для диагностики лучше вывести наличие нужного параметра, имя этапа и безопасную часть контекста. В course-card журнал может сообщить название сайта и ID pipeline; это предусмотренные несекретные сведения.
Отдельно проверьте состав артефактов. Даже если secret не напечатан в журнале, программа может записать его в dist/, после чего Runner сохранит файл. Маскирование stdout не проверяет автоматически каждый output. В нашем договоре каталог строится только из известных полей JSON и названия сайта, а build.env содержит лишь происхождение сборки.
Ожидаемый результат — конфигурационный параметр, понятная передача созданных метаданных и отсутствие настоящих секретов в учебном архиве. Никакие настройки пользователя в GitLab не менялись и внешние операции не выполнялись. Следующий урок покажет структурированные отчёты проверки, которые помогают оценить failed job без чтения всего журнала.