Если нативный кубик в процессе выполнения изменит окружение воркера, например, установит пакет, создаст или удалит файл и т. д., это окружение останется для всех последующих кубиков, которые выполняются в рамках одного задания.
Docker-кубик — выполняется внутри Docker-контейнера, который запускается на воркере. Внутри контейнера запускается пользовательский скрипт или скрипт контейнера, если для контейнера предусмотрена точка входа (entrypoint).
Если Docker-кубик в процессе выполнения изменит окружение, оно будет доступно последующим кубикам задания, только если изменения производятся внутри директории /sourcecraft. Все остальные изменения удаляются вместе с Docker-контейнером.
При работе из контейнера директории монтируются следующим образом:
директория, в которой находятся связанные с выполняемым заданием файлы, монтируется по пути /sourcecraft;
директория, в которую клонируется репозиторий, и которая по умолчанию назначается рабочей (workdir), монтируется по пути /sourcecraft/workspace.
Пути указанных директорий можно получить из предопределенных переменных окружения$SOURCECRAFT_ROOT_DIRECTORY и $SOURCECRAFT_WORKSPACE соответственно.
Docker-кубик задается с помощью параметра image, в котором указывается название Docker-образа, а также опционально логин, пароль, точка входа и аргументы.
В кубиках вы можете использовать переменные окружения, а также секреты. Для передачи переменных окружения от одного кубика к последующим в виде пар KEY=VALUE предусмотрена предопределенная переменная$SOURCECRAFT_ENV.
Кубики внутри одного задания по умолчанию запускаются последовательно. Кубики могут быть связаны между собой через параметр needs. В параметре указывается список кубиков, которые должны быть выполнены до запуска текущего. Если параметр не указан, кубик будет зависеть от кубика, который определен непосредственно перед ним.
Артефакты, которые могут быть созданы в результате работы кубика, сохраняются для дальнейшего использования. Их можно скачать из конкретного кубика в секции CI/CD репозитория в течение 14 дней.
allow_failure — флаг, позволяющий управлять поведением CI/CD-процесса при возникновении ошибок в отдельных кубиках. При значении true выполнение задания продолжится даже в случае ошибки в кубике, как если бы он завершился успешно. Значение по умолчанию — false. Подробнее см. Пример конфигурации, при которой задание продолжится даже после завершения кубика ошибкой.
artifacts — список путей к файлам, которые будут созданы в результате работы кубика и сохранены для дальнейшего использования. Артефакты можно будет скачать из конкретного кубика в секции CI/CD репозитория в течение 14 дней. Подробнее см. Пример конфигурации кубиков с использованием артефактов.
if — условие, при котором кубик будет выполнен. Если условие не выполнено, кубик пропускается, а задание продолжает выполняться. Поддерживаются следующие операторы:
always() — выполнить кубик вне зависимости от того, успешно ли выполнились предыдущие кубики или нет. Например, если нужно очистить окружение.
contains() — проверка наличия в строке какого-либо содержимого, например contains(env.SOURCECRAFT_COMMIT_REF_NAME, "release") или env.SOURCECRAFT_COMMIT_REF_NAME.contains("release").
cubes.<имя_кубика>.status — проверка статуса любого предыдущего кубика.
failure() и success() — проверка сводного статуса по всем кубикам, завершившим работу до текущего.
== — сравнение, например env.SOURCECRAFT_COMMIT_REF_NAME == "main".
!= — отрицание, например env.SOURCECRAFT_COMMIT_REF_NAME != "main".
script — команда, которая будет выполнена в кубике.
uses — параметр, с помощью которого в текущем кубике можно переиспользовать параметры из другого кубика. В зависимости от того, где определен переиспользуемый кубик, применяется следующий синтаксис:
Чтобы переиспользовать кубик из другого репозитория, у этого кубика обязательно должен быть задан флаг exported: true. Если флаг не задан, то попытка переиспользовать кубик в другом репозитории завершится ошибкой.
with — параметры GitHub Action. Используется только совместно с action.
Важно
Запуск GitHub Actions и пайплайнов GitLab в CI/CD SourceCraft поддерживается только на облачных воркерах.
Пример конфигурации кубиков с использованием переменных, в том числе предопределенных
# Здесь определяются переменные с глобальной областью видимости,# они будут переданы во все кубики всех заданий во всех рабочих процессахenv:GLOBAL_VAR:global_varGLOBAL_SECRET:${{secrets.<название_секрета>}}workflows:my-workflow:# Здесь определяются переменные, которые будут доступны во всех кубиках # всех заданий рабочего процесса my-workflowenv:WORKFLOW_VAR:workflow-vartasks:-name:my-task# Здесь определяются переменные, которые будут доступны во всех кубиках # внутри задания my-taskenv:TASK_ENV_VAR:Thisvariableisavailableinallcubesofthistask.# Многострочная переменнаяMULTILINE_VAR:|
multi-var
multi-var
this is my multi-var
cubes:-name:my-cube-1# Здесь определяются переменные, которые будут доступны только внутри# кубика my-cube-1env:CUBE_ENV_VAR:Thisvariableisavailableonlyincubemy-cube-1.# Переменная, значение которой задается из секретаSECRET_VAR:${{secrets.<название_секрета>}}# Переиспользование переменных из глобальной области видимости, # например GLOBAL_VAR и GLOBAL_SECRETLOCAL_VAR:${{env.<глобальная_переменная_1>}}LOCAL_SECRET:${{env.<глобальная_переменная_2>}}# Переиспользование переменных из области видимости рабочего# процесса, например WORKFLOW_VARLOCAL_VAR2:${{env.<переменная_рабочего_процесса>}}script:-echo"$TASK_ENV_VAR"-echo"$MULTILINE_VAR"-echo"$CUBE_ENV_VAR"-echo"$SECRET_VAR"-echo"$WORKFLOW_VAR"-echo"$LOCAL_VAR"-echo"$LOCAL_VAR2"-echo"$LOCAL_SECRET"-name:my-cube-2# Здесь определяются переменные, которые будут доступны только внутри # кубика my-cube-2env:CUBE_ENV_VAR:Thisvariableisavailableonlyincubemy-cube-2.script:-echo"$TASK_ENV_VAR"-echo"$CUBE_ENV_VAR"# Использование предопределенной переменной-echo"$SOURCECRAFT_TASK"-echo"$WORKFLOW_VAR"-echo"$GLOBAL_VAR"-name:my-task-2cubes:-name:my-cube-3script:-echo"$WORKFLOW_VAR"-echo"$GLOBAL_VAR"
Пример переиспользования параметров кубика из произвольного YAML-файла другого репозитория
Файл с переиспользуемым кубиком .ci-files/cubes/bash-lib.yaml в другом репозитории myrepo организации myorg:
cubes:-name:external-cube-1env:CUBE_VAR:helloscript:-echo$CUBE_VAR# Флаг, разрешающий использовать кубик в других репозиторияхexported:true-name:external-cube-2script:-echo"world"exported:true
Файл .sourcecraft/ci.yaml репозитория, в котором настраивается CI:
Пример конфигурации с условным исполнением кубиков
workflows:workflow-name:tasks:-name:task-namecubes:# Кубик выполнится, только если рабочий процесс запущен в ветке, имя которой # содержит текст «release», и целевая ветка в предложении изменений — «main»-name:condition-cube-1if:contains(env.SOURCECRAFT_COMMIT_REF_NAME,"release")&&env.SOURCECRAFT_BASE_REF=="main"script:-echo'The source branch name contains text "release" and the target branch is "main".'# Кубик выполнится, только если рабочий процесс запущен в ветке, имя которой# содержит текст «feature», или целевая ветка в предложении изменений — не «main»-name:condition-cube-2if:env.SOURCECRAFT_COMMIT_REF_NAME.contains("feature")||env.SOURCECRAFT_BASE_REF!="main"script:-echo'The source branch name contains text "feature" or the target branch is not "main".'# Кубик выполнится вне зависимости от того, успешно ли выполнились предыдущие # кубики или нет-name:condition-cube-3if:always()script:-env-ibash
Docker-образы (image)
Блок image содержит параметры Docker-образа, который будет использоваться для выполнения кубика.
Вы можете указать стандартное имя Docker-образа или путь в конкретном реестре.
Если блок image не указан, команды будут выполняться в окружении Linux.
Поддерживаются следующие опциональные параметры:
args — аргументы, которые будут переданы на вход контейнеру при запуске. Нельзя использовать в кубике, в котором задан параметр script.
entrypoint — переопределение точки входа (entrypoint) контейнера. Аналог флага --entrypoint для команды docker run.
Пример конфигурации Docker-образа с аутентификацией
Если для доступа к реестру нужна аутентификация, то можно использовать в задании команду docker login или задать настройки аутентификации в блоке image и задействовать секрет, например:
Чтобы выполнить набор команд в контексте контейнера, укажите путь к Docker-образу в реестре в параметрах image или image:name, а набор команд — в script, например:
Если в контейнере переопределена точка входа, то, чтобы выполнить в нем команды из script, сбросьте точку входа. Это можно сделать, указав в параметре entrypoint значение "". Например, вы можете использовать контейнер, у которого по умолчанию задана точка входа ENTRYPOINT ["/usr/bin/docker"]:
Передать аргументы командной строки в Docker-контейнер
Чтобы передать в контейнер с переопределенной точкой входа аргументы, которые нужны для его выполнения, используйте параметр args. Например, это может быть контейнер, который используется для создания нового Docker-образа:
Параметр script: [commands] является альтернативой установки entrypoint: "default shell" и args: ["-c", 'command_1 && … && command_N'].
Важно
В одном кубике нельзя одновременно задать image:args и script.
Автоматический перезапуск кубика
Чтобы разрешить автоматический перезапуск кубика, установите для него параметр retry. Укажите в параметре максимальное количество повторных попыток и условия перезапуска.
При каждом перезапуске:
Очищаются переменные окружения (env), добавленные в ходе предыдущей попытки.
Очищаются данные, записанные в блок outputs в ходе предыдущей попытки.
Артефакты, созданные в процессе выполнения кубика, сохраняются только для последней попытки, вне зависимости от ее успешности.
Данные на файловой системе не очищаются. Необходимо самостоятельно убедиться, что данные, которые могли быть изменены, не повлияют на результаты перезапуска.
При отмене задачи (cancel) механизм перезапуска блокируется, кубик не перезапускается.
Если для кубика одновременно установлены параметры retry и allow_failure, то количество перезапусков определяется параметром retry.
Перезапуск по умолчанию
cubes:-name:cube1...retry:3
В этом примере:
retry — максимальное количество повторных попыток. После первого запуска кубик будет перезапущен максимум три раза.
Условия перезапуска не указаны, поэтому перезапуск может произойти как при ошибке исполнения, так и при превышении таймаута.
max — максимальное количество повторных попыток. После первого запуска кубик будет перезапущен максимум три раза.
on_error_types — условия перезапуска:
timeout — перезапуск при превышении таймаута.
Проверка статусов предыдущих кубиков
Возможные статусы:
success — успешное выполнение.
failure — неуспешное выполнение: ошибка.
ignored_failure — условно успешное выполнение: игнорируемая ошибка трансформируется из failure при включенном allow_failure=true.
timeout — неуспешное выполнение: выполнение прервано по таймауту.
ignored_timeout — условно успешное выполнение: игнорируемый таймаут трансформируется из timeout при включенном allow_failure=true.
skipped — кубик пропущен: не выполнялся из-за условия if, вернувшего значение false.
cancelled — кубик отменен: выполнение всего workflow было отменено пользователем.
Проверка статуса любого предыдущего кубика
Чтобы проверить статус любого предыдущего кубика, используйте в условии if выражение вида cubes.<имя_кубика>.status == <статус>.
Пример
cubes:# Кубик 1: Успешный кубик-name:success-cubescript:-echo"This cube must succeed"# Кубик 2: Проверка success статуса предыдущего кубика-name:if-success-cubeif:cubes.success-cube.status=="success"needs:-success-cubescript:-echo"success-cube succeeded (expected)!"
Проверка сводного статуса всех предыдущих кубиков
Чтобы проверить сводный статус всех кубиков, завершивших свою работу до текущего, используйте в условии if функции:
success() — возвращает true, если все предыдущие кубики завершились успешно или почти успешно.
Статусы, подходящие под условие:
success
skipped
ignored_failure
ignored_timeout
failure() — возвращает true, если хотя бы один из предыдущих кубиков завершился с ошибкой.
Статусы, подходящие под условие:
failure
timeout
cancelled
Пример
cubes:# Кубик 1: Успешный кубик-name:success-cubescript:-echo"This cube must succeed"# Кубик 2a: Проверка success статуса предыдущего кубика-name:if-success-cube# if-условие проверки статуса любого предыдущего кубикаif:cubes.success-cube.status=="success"needs:-success-cubescript:-echo"success-cube succeeded (expected)!"# Кубик 2б: Проверка failure статуса предыдущего кубика-name:if-failure-cube# if-условие проверки сводного статуса по всем кубикам, завершивших свою работу до этого кубикаif:failure()||!success()needs:-success-cubescript:-echo"success-cube failed (not expected)!"-exit1# Кубик 3: Кубик с ошибкой-name:failed-cubeallow_failure:trueneeds:-if-success-cube-if-failure-cubescript:-echo"This cube must fail"-exit1# Кубик 4а: Проверка failure статуса предыдущего кубика-name:if-success-cube-2if:cubes.failed-cube.status=="success"needs:-failed-cubescript:-echo"failed-cube succeeded (not expected)!"-exit1# Кубик 4б: Проверка статуса failure предыдущего кубика-name:if-failure-cube-2if:cubes.failed-cube.status=="ignored_failure"needs:-failed-cubescript:-echo"failed-cube failed (expected)!"
Статус выполнения предыдущих кубиков также можно проверить в скриптах посредством использования синтаксиса для outputs: ${{ cubes.<cube-name>.status }}.
Пример
if [ "${{ cubes.retrycube.status }}" == "success" ]; then
echo "Retry cube succeeded!"
else
echo "Retry cube failed!"
fi