tl;dr
Как передать данные, например переменная $BUILD_VERSION
между заданиями в разных конвейерах в Gitlab CI?
Фон
Рассмотрим следующий пример (полный yml
ниже):
building:
# only on merge requests
stage: staging
script:
- echo "BUILD_VERSION=1.2.3" > build.env
artifacts:
reports:
dotenv: build.env
deploying:
# after merge request is merged
stage: deploy
dependencies:
- building
script:
- echo $BUILD_VERSION
У меня два этапа: постановка и развертывание. Задание building
в staging создает приложение и создает приложение Review (для простоты отдельного этапа сборки нет). Затем задание deploying
в deploy загружает новое приложение.
Конвейер, содержащий задание building
, запускается всякий раз, когда открывается запрос на слияние. Таким образом создается приложение, и разработчик может щелкнуть значок «Обзор приложения» в запросе на слияние. Задание deploying
запускается сразу после слияния запроса на слияние. Идея такая:
*staging* stage *deploy* stage
<open merge request> -> `building` job (and show) ... <merge> -> `deploying` job
│ ▲
└───────────── $BUILD_VERSION ───────────────┘
Проблема для меня в том, что staging / building
создает некоторые данные, например а $BUILD_VERSION
. Я хочу, чтобы это $BUILD_VERSION
было в deploy / deploying
, например для создания нового релиза через Gitlab API.
Итак, мой вопрос: как передать $BUILD_VERSION
(и другие данные) из staging / building
в deploy / deploying
?
Что я пробовал до сих пор
artifacts.reports.dotenv
Описанный случай более менее описан в документации gitlab в Передать переменную среды другому заданию. Также файл yml
, показанный ниже, в значительной степени вдохновлен этим примером. Тем не менее, это не работает.
Артефакт build.env
создается в building
, но всякий раз, когда выполняется задание deploying
, файл build.env
удаляется, как показано ниже в строке 15: Удаление build.env. Я пытался добавить build.env
к .gitignore
, но он все равно удаляется.
После нескольких часов поиска я нашел в этот комментарий к проблеме gitlab и это сообщение stackoverflow о том, что artifacts.reports.dotenv
не работает с dependencies
или needs
ключевыми словами.
Удаление dependencies
не работает. Использование только needs
тоже не работает. Использование обоих недопустимо.
Кто-нибудь знает, как заставить это работать? Я чувствую, что так и должно работать.
Получение артефактов в виде файла
Этот ответ сообщения stackoverflow Gitlab ci cd удаляет артефакт для запросов на слияние предлагает использовать build.env
как обычный файл. Я тоже пробовал это. (Соответствующий) yml
следующий:
building:
# ...
artifacts:
paths:
- build.env
deploying:
# ...
before_script:
- source build.env
Результат такой же, как и выше. build.env
удаляется. Затем команда source build.env
завершается ошибкой, потому что build.env
не существует. (Неважно, входит build.env
в .gitignore
или нет, проверял оба)
Получение артефактов из API
Я также нашел ответ в сообщении stackoverflow Использовать артефакты из задания слияния запроса в GitLab CI, в котором предлагается использовать API вместе с $CI_JOB_TOKEN
. Но поскольку мне нужны артефакты в конвейере без запросов слияния, я не могу использовать предложенный CI_MERGE_REQUEST_REF_PATH
.
Пробовал использовать $CI_COMMIT_REF_NAME
. Тогда (важный раздел) yml
:
deploying:
# ...
script:
- url=$CI_API_V4_URL/projects/jobs/artifacts/$CI_COMMIT_REF_NAME/download?job=building
- echo "Downloading $url"
- 'curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --output $url'
# ...
Но при этом запрос API отклоняется с ошибкой 404 Not Found. Поскольку SHA фиксации не поддерживаются, $CI_COMMIT_BEFORE_SHA
или $CI_COMMIT_SHA
тоже не работают.
Использование needs
Обновление: я нашел раздел Загрузка артефактов между конвейерами в одном проекте в документации gitlab, что мне и нужно. Но: я не могу заставить его работать.
yml
после меньшего количества копий из документов выглядит следующим образом:
building:
# ...
artifacts:
paths:
- version
expire_in: never
deploying
# ...
needs:
- project: $CI_PROJECT_PATH
job: building
ref: staging # building runs on staging branch, main doesn't work either
artifacts: true
Теперь задание deploying
немедленно завершается ошибкой, и я получаю следующий баннер с ошибкой:
Я попытался установить artifacts.expire_in = never
(как показано), но все равно получаю ту же ошибку. Также в Настройках ›CI / CD› Артефакты установлен флажок Сохранять артефакты из самых последних успешных заданий. Значит артефакт должен присутствовать. Что я здесь пропустил? Это должно работать в соответствии с документами!
Я надеюсь, что кто-нибудь поможет мне получить $BUILD_VERSION
работу deploying
. Если есть другие способы, кроме тех, которые я пробовал, я очень рад их слышать. Заранее спасибо.
Пример .gitlab-ci.yml
:
stages:
- staging
- deploy
building:
tags:
- docker
image: bash
stage: staging
rules:
- if: ($CI_PIPELINE_SOURCE == "merge_request_event") && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "staging"
when: always
- when: never
script:
- echo "BUILD_VERSION=1.2.3" > build.env
artifacts:
reports:
dotenv: build.env
environment:
name: Example
url: https://example.com
deploying:
tags:
- docker
image: bash
stage: deploy
rules:
- if: $CI_COMMIT_BRANCH == "staging"
when: always
- when: never
dependencies:
- building
script:
echo $BUILD_VERSION
reports: dotenv:
и сделайте вместо этогоpaths:
. Затем сохранитеdependencies:
точно так же, как у вас, чтобы восстановить build.env в конвейере развертывания. - person Peter   schedule 30.06.2021yml
из своего ответа и изменил толькоartifacts.reports
изbuilding
наartifacts.paths: -build.env
- person miile7   schedule 30.06.2021building
в некоторых сборках и пытались передать данные между несвязанными конвейерами. Смотри мой ответ - person Peter   schedule 30.06.2021