Перейти к содержимому

Доступные билтины

Билтины — это внутренние Go-функции движка, вызываемые из шага через type: builtin. Они работают in-process с доступом к объединённому конфигу и тому же реестру, что и декларативные команды type: builtin.

Билтины-предикаты как тело шага (семантика утверждения)

Заголовок раздела «Билтины-предикаты как тело шага (семантика утверждения)»

Предикат — билтин, отвечающий на вопрос «да/нет» о состоянии мира (file_exists, executable_in_path, tcp_reachable, http_check, containers_running, env_keys_present, config_keys_present и билтин shell) — может использоваться прямо как тело шага, а не только внутри блока check:/when:. Как тело шага предикат становится утверждением:

  • Результат true (проверка проходит) делает шаг успешным.
  • Результат false (проверка не проходит) проваливает шаг с собственным сообщением предиката, останавливая пайплайн, как любой другой сбой шага. Новый тип ошибки не вводится — объяснение предиката становится ошибкой шага.

Шаги-предикаты всегда перезапускаются: гейт деплоя «уже актуально» и per-step пропуск по action-hash никогда не пропускают шаг, тело которого — предикат (та же обработка always-run, что и у шагов check:). У утверждения нет осмысленного кешированного результата, поэтому оно переоценивается при каждом деплое.

Гейт when: по-прежнему применяется, как обычно — шаг-предикат с when:, вычисляющимся в false, пропускается без утверждения (условное утверждение остаётся условным).

- name: assert-app-reachable
type: builtin
cmd: http_check
with:
url: http://localhost:8080/health
status: 200
contains: '"ok"'
retries: 10
interval: 2s

Эта возможность чисто разрешающая: предикаты, ранее легальные только внутри check:/when:, теперь легальны и как тела шагов, в любом пайплайне (deploy.yml, reset.yml, lifecycle.yml и тест-сценарии) и как пользовательские команды type: builtin. Существующие конфиги не затрагиваются.

Билтины-действия в check: — разрешены, но это плохая идея

Заголовок раздела «Билтины-действия в check: — разрешены, но это плохая идея»

Схема допускает и обратное: билтин-действие (source_clone, remove_paths, service_configs_render, …) принимается в позиции check:, потому что часть действий доступны только на чтение (service_configs_check), и отвержение всего вида сломало бы их. Это разрешение не является рекомендацией: check: отвечает на вопрос «не сделано ли уже?» и перевычисляется движком тогда, когда тело шага — нет, поэтому изменяющий билтин в этой позиции заставляет ответ менять тот мир, о котором его спрашивают. Держите в check: только предикаты и действия, доступные на чтение. workspace/validate.yml обеспечивает это на своей поверхности фиксированным allow-list’ом (shell, file_exists, executable_in_path, env_keys_present, tcp_reachable, http_check, config_keys_present) — см. validate.md.

БилтинНазначение
service_dirs_ensureСоздаёт директории хаба сервиса
service_configs_renderРендерит конфиг-файлы из шаблон-пака в хаб сервиса (воспроизводит сгенерированные значения)
service_configs_render_checkПроверяет, что отрендеренные цели конфигов существуют; добавление как check: перезапускает рендер при каждом деплое
service_generated_harvestСобирает поля generated: сервиса в хранилище сгенерированных значений (запись-если-отсутствует)
service_configs_copy⚠️ Устарело — копирует шаблонные конфиг-файлы в хаб сервиса
service_configs_check⚠️ Устарело — проверяет, что скопированные конфиг-файлы существуют в хабе сервиса
messageПечатает стилизованное сообщение уровня info/success/warning/error
confirmИнтерактивный Y/n промпт (пропускается при --yes)
docker_remove_project_volumesУдаляет все тома, имя которых начинается с имени compose-проекта
docker_wait_healthyОжидает, пока Docker-контейнеры достигнут healthy-состояния
containers_runningБыстрая проверка «запущен» (без поллинга, таймаута и обязательного healthcheck)
http_checkУтверждает, что HTTP-эндпоинт возвращает ожидаемый статус (и опциональную подстроку тела), с ретраями
remove_pathsУдаляет пути относительно корня проекта из файловой системы
source_cloneКлонирует git-репозиторий в каталог относительно корня проекта, однократно (идемпотентно)

Создаёт директории хаба сервиса.

ПараметрТипПо умолчаниюОписание
servicestringобязательноИмя папки сервиса из workspace/services/<name>/
modestringskipskip, error или recreate

Разрешённый список директорий: [src] + ServiceConfig.Dirs (из service.yml сервиса). Каждый элемент должен быть непустым относительным путём, не выходящим за пределы dir сервиса.

Директории configs/ нет в этом списке — service_configs_copy создаёт её лениво, когда у сервиса декларирован блок configs:. Если нужно создавать её жадно (или вытирать при recreate), добавьте configs в dirs: явно.

Поведение режимов:

РежимДиректории нетДиректория существуетНе-директория по пути
skipсоздатьno-opошибка
errorсоздатьошибкаошибка
recreateсоздатьудалить + создатьошибка

Безопасность: src всегда использует семантику skip в режиме recreate (исходный код никогда не удаляется). Все остальные директории — включая configs, если она перечислена в dirs: — вычищаются при recreate.

Рендерит конфиг-файлы сервиса из шаблон-пака конфигов (workspace/templates/config/<pack>/) в директорию хаба сервиса (svc.Dir), воспроизводя любые собранные значения ${generated.<name>} из хранилища сгенерированных значений (.dwe/generated.yml). Это рендер-основанный преемник устаревшего service_configs_copy.

ПараметрТипПо умолчаниюОписание
servicestringобязательноКлюч сервиса
modestringreplaceПоддерживается только replace (перезапись)

Рендеринг конфигов opt-in: сервис без разрешимого пака конфигов — это no-op. Сочетайте этот шаг с check: service_configs_render_check, чтобы он перезапускался при каждом деплое. См. render config для субстрата, разрешения пака и полного потока деплоя.

- name: render-configs
type: builtin
cmd: service_configs_render
with:
service: main
check:
type: builtin
cmd: service_configs_render_check
with:
service: main

Проверяет, что каждая цель рендера пака конфигов для сервиса существует на диске. Его основное назначение структурное: добавление как check: шага service_configs_render заставляет этот шаг перезапускаться при каждом деплое (рычаг hasCheck → Run в journal/decision.go обходит пропуск по action-hash), так что правки шаблонов и очистки хранилища всегда вступают в силу — в точности зеркалируя service_configs_copy + service_configs_check.

ПараметрТипПо умолчаниюОписание
servicestringобязательноКлюч сервиса

Сервису без разрешимого пака конфигов нечего проверять, и он no-op. Возвращает ошибку с перечислением отсутствующих отрендеренных файлов, что приводит к падению проверки.

Читает каждое из объявленных полей generated: сервиса из его файла на диске, извлекает значение по регекспу поля (группа захвата 1) и записью-если-отсутствует сохраняет его в хранилище сгенерированных значений (.dwe/generated.yml). Хранилище сохраняется атомарно при записи нового значения.

ПараметрТипПо умолчаниюОписание
servicestringобязательноКлюч сервиса

«Собрать, а не сгенерировать»: собственный генератор сервиса (например, php artisan key:generate) пишет секрет; DWE только считывает его обратно и воспроизводит при последующих рендерах. Запись-если-отсутствует означает, что значение, уже находящееся в хранилище, сохраняется, поэтому повторный деплой — это no-op. Сервис без полей generated: — это no-op. Отсутствующий файл, паттерн, не совпавший ни с одной строкой, паттерн без группы захвата или захваченное пустое значение выдаются как ошибки — никогда не пропускаются молча. См. блок generated и render config.

⚠️ Устарело. Заменено на service_configs_render + service_generated_harvest. Продолжает работать, но dwe validate выдаёт предупреждение, и при каждом шаге копирования срабатывает однократное runtime-уведомление об устаревании. См. render config для замены.

Копирует шаблонные конфиг-файлы из configs/services/<service>/ в services/<service>/configs/. Создаёт директорию назначения configs/, если её нет — это канонический путь создания configs/ (билтин service_dirs_ensure её не создаёт).

ПараметрТипПо умолчаниюОписание
servicestringобязательноКлюч сервиса
modestringreplacedefault, update или replace

Поведение режимов:

РежимНазначения нетНазначение существует
defaultзаписатьno-op
replaceзаписатьбезусловно перезаписать
updateзаписатьсмерджить новые строки KEY=VALUE без изменения существующих ключей (с учётом env-файлов)

Когда у соответствующей записи configs[] есть mountpoint, билтин также создаёт пустой файл в <service-dir>/<mountpoint>, чтобы Docker Desktop virtiofs мог наложить поверх него вложенный файловый bind mount.

⚠️ Устарело. Компаньон-check: устаревшего service_configs_copy. Для рендер-основанных конфигов используйте service_configs_render_check.

Проверяет, что все шаблонные конфиг-файлы, декларированные в service.yml сервиса, существуют в его хабе после шага service_configs_copy. Используйте как действие check:, чтобы убедиться, что конфиги успешно развёрнуты.

ПараметрТипПо умолчаниюОписание
servicestringобязательноКлюч сервиса

Возвращает ошибку с перечислением отсутствующих файлов, что приводит к падению проверки. Обычно используется как post-check шага service_configs_copy:

- name: copy-configs
type: builtin
cmd: service_configs_copy
with:
service: main
mode: replace
check:
type: builtin
cmd: service_configs_check
with:
service: main

Печатает сообщение в вывод деплоя.

ПараметрТипОписание
levelstringinfo, success, warning или error (обязательно)
textstringТекст сообщения (обязательно); поддерживает Go template-выражения на DweConfig
- name: done
type: builtin
cmd: message
with:
level: success
text: "Deploy of {{ .Project.Name }} completed"

Запрашивает у пользователя подтверждение перед продолжением. Пропускается при заданном флаге --yes или когда шаг подтверждается через ExecContext.SkipConfirm. В TTY использует huh.Confirm; в piped/CI stdin откатывается к простому Y/n.

ПараметрТипПо умолчаниюОписание
messagestringAre you sure?Текст промпта
ok_msgstringContinuingСообщение об успехе после подтверждения
stop_msgstringAbortedСообщение об ошибке после отказа / Esc

Удаляет все Docker-тома, имя которых начинается с <project_name>_ (разрешается из docker.yml по объединённому конфигу). Параметров нет. Прерывается, если разрешённое имя проекта пусто.

Ожидает, пока Docker-контейнеры достигнут healthy-состояния. Поллит активный стек Docker Compose, пока все указанные контейнеры не станут healthy или не истечёт таймаут.

ПараметрТипПо умолчаниюОписание
timeoutstring duration60sМаксимальное время ожидания; должно быть положительным (например, 120s, 2m)
intervalstring duration2sИнтервал опроса; должен быть положительным
serviceslist of stringsвсеОграничение конкретными именами compose-сервисов; по умолчанию = все контейнеры активного стека

Пример: ожидание всех контейнеров

- name: wait
type: builtin
cmd: docker_wait_healthy
with:
timeout: 120s
interval: 2s

Пример: ожидание конкретных сервисов

- name: wait-app
type: builtin
cmd: docker_wait_healthy
with:
timeout: 60s
interval: 1s
services:
- app-main
- db

Поведение:

  • Если в активном стеке нет контейнеров (или совпадающих с фильтром сервисов), логирует предупреждение и возвращает успех. Идемпотентно для пайплайнов, выполняемых до up.
  • Если контейнер unhealthy или истёк таймаут до того, как все контейнеры стали healthy, возвращает ошибку и останавливает пайплайн.
  • Контейнеры без healthcheck (статус none) считаются всегда healthy и пропускаются.
  • Активный стек определяется текущим набором оверлеев (по умолчанию, включённые сервисы, включённые tools). Этот билтин уважает ComposeFiles(), а не ComposeFilesAll().

Быстрая проверка «запущен» для compose-сервисов. В отличие от docker_wait_healthy он не поллит готовность, не учитывает таймаут и не требует, чтобы у сервисов был объявлен healthcheck — вызов docker compose ps --status=running --services возвращает набор сейчас запущенных сервисов, и билтин делает diff с запрошенным списком.

Транзиентный сбой проверки — когда сам вызов docker compose ps завершается с ошибкой (любой ненулевой сбой выполнения, например ненулевой код выхода прямо на границе docker up --wait, пока compose CLI / демон на мгновение заняты, хотя все контейнеры уже подняты) — повторяется ограниченное число раз с короткой паузой перед тем, как шаг упадёт; единственное исключение — отменённый контекст, он немедленно прерывает оставшиеся повторы. Это не поллинг готовности: если проверка отработала успешно, но сообщает, что сервис не запущен, шаг падает с первой попытки. Когда все повторы неудачны, stderr от docker compose ps попадает в текст ошибки, чтобы сбой можно было диагностировать.

ПараметрТипПо умолчаниюОписание
serviceslist of stringsобязательноИмена compose-сервисов, которые должны быть в данный момент запущены. Пустой список отклоняется.

Пример: гейт шага пайплайна по запущенному сервису

- name: stack-up
type: dwe
cmd: "docker up"
check:
type: builtin
cmd: containers_running
with:
services: [app-main, db]

Когда выбирать его вместо docker_wait_healthy:

  • У сервиса нет healthcheck — docker_wait_healthy либо пропустит его (считая healthy), либо зависнет в ожидании статуса, которого никогда не будет.
  • Нужен пред-условный шаг для последующего (например, service_exec), и хочется явную ошибку «контейнер X не запущен» вместо stderr-трейса compose.
  • Пайплайн выполняется сразу после docker up и нужно лишь убедиться, что стек поднялся, без затрат на round-trip поллинга.

Если сервисы отсутствуют, билтин падает с services not running: <comma-separated list>.

Билтин-предикат (KindPredicate), выполняющий HTTP GET и утверждающий ответ. Возвращает успех, когда эндпоинт отдаёт ожидаемый код статуса и — когда задан contains: — тело, содержащее указанную подстроку. При сбое повторяет попытку до retries раз, ожидая interval между попытками; каждая отдельная попытка ограничена timeout.

ПараметрТипПо умолчаниюОписание
urlstringобязательноЦелевой URL. Должен парситься как абсолютный http/https URL с хостом.
statusint200Ожидаемый код статуса HTTP.
containsstringОпциональная подстрока, которая должна присутствовать в теле ответа. Когда пусто, тело не читается.
retriesint0Дополнительные попытки после первой при несовпадении/ошибке. Всего попыток = retries + 1. Должно быть >= 0.
intervalstring duration1sОжидание между попытками. Должно быть >= 0. Отменяется через контекст.
timeoutstring duration5sТаймаут на попытку (не общий). Должно быть > 0.

Как тело шага это утверждение: успешная проверка делает шаг успешным, неуспешная проваливает пайплайн с сообщением вида http_check http://localhost:8080/health: expected status 200, got 503 (after 31 attempts). Его равнозначно можно использовать внутри блока check:/when: или как запись проверки в validate.yml.

Пример: ожидание health-эндпоинта после up

- name: wait-app-http
type: builtin
cmd: http_check
with:
url: http://localhost:8080/health
status: 200
contains: '"status":"ok"'
retries: 30
interval: 2s
timeout: 3s

Поведение:

  • Попытки выполняются последовательно: попытка → при несовпадении/ошибке ожидание interval → следующая попытка, до retries + 1 попыток всего.
  • Ответ не с кодом status, тело без подстроки contains, отказ в соединении или таймаут попытки — всё считается неуспешной попыткой.
  • Ожидания interval и per-attempt запросы уважают отмену контекста, поэтому прерванный пайплайн останавливается быстро.
  • Некорректные параметры (отсутствующий/битый url, отрицательные retries/interval, неположительный timeout) отклоняются на этапе плана методом Validate, до запуска пайплайна.

Удаляет пути из файловой системы.

ПараметрТипОписание
pathslist of stringsПути относительно проекта для удаления. Каждый должен быть относительным и не выходить за корень проекта; абсолютные пути и ..-обходы отклоняются на этапе валидации.

Клонирует git-репозиторий в каталог относительно корня проекта. Гейт идемпотентности встроен, поэтому шагу не нужна собственная пара when:/check:.

ПараметрТипОписание
repostringобязательно. Всё, что принимает git clone (SSH-remote, HTTPS-URL, локальный путь).
dirstringобязательно. Назначение относительно корня проекта. Абсолютные пути, . и ..-обходы отклоняются на этапе валидации; символическая ссылка в компоненте пути отклоняется во время выполнения.
branchstringопционально. Передаётся как git clone --branch <branch>.

Поведение по состоянию назначения:

НазначениеРезультат
содержит запись .gitпропуск с сообщением, успех — независимо от того, на какой ветке этот checkout
отсутствует или пустой каталогклонировать
непустой и не git-checkoutошибка с указанием пути
существует, но не каталогошибка с указанием пути

Пропуск намеренно слеп к ветке: source_clone материализует исходники один раз и никогда не перенаправляет и не обновляет существующее рабочее дерево. Переключение веток и подтягивание изменений — задача разработчика (или отдельного шага).

Git запускается с отключёнными промптами — GIT_TERMINAL_PROMPT=0, обнулённые GIT_ASKPASS/SSH_ASKPASS и GIT_SSH_COMMAND=ssh -o BatchMode=yes, когда окружение ещё не задало в нём реальную команду — поэтому отсутствующие учётные данные проваливают шаг вместо того, чтобы подвесить деплой на неотвечаемом промпте. Явно заданный GIT_SSH_COMMAND (кастомный файл ключа, порт) уважается как есть; пустое значение не содержит команды, которую git мог бы запустить, поэтому считается незаданным и заменяется значением по умолчанию. Команда не читает stdin.

- name: clone-backend
type: builtin
cmd: source_clone
with:
repo: "${vars.source.backend.repo}"
dir: services/backend/src
branch: "${vars.source.backend.branch}"

Внутренние билтины движка (не вызываются из пользовательского YAML)

Заголовок раздела «Внутренние билтины движка (не вызываются из пользовательского YAML)»

Следующие билтины зарезервированы за движком. Они не могут появляться в пользовательских deploy.yml, reset.yml или lifecycle.yml — попытка использования вызывает ошибку на этапе загрузки.

БилтинОписание
docker_daemon_startЗапускает именованный daemon-контейнер через docker compose run -d. Вызывается виртуальной командой .start, генерируемой из команд type: daemon.
docker_daemon_logsТейлит логи daemon-контейнера на переднем плане. Вызывается виртуальной командой .logs, генерируемой из команд type: daemon.
docker_daemon_stopОстанавливает именованный daemon-контейнер (идемпотентно). Вызывается виртуальной командой .stop, генерируемой из команд type: daemon.
docker_stop_remove_containerОстанавливает и удаляет именованный контейнер (docker stop + docker rm -f, оба идемпотентны при отсутствии контейнера). Вызывается синтетической фазой container, которую dwe reset run --service <name> подставляет в начало каждого per-service пайплайна сброса. Параметры: container_template (string, обязателен; шаблон имени, разрешается через префикс проекта), stop_timeout (duration string, опционально, по умолчанию 10s). При сбое остановки пробрасывает ошибку и НЕ пытается удалить.
daemons_reapОстанавливает все daemon-контейнеры проекта. Автоматически подставляется движком как фаза _auto_reap_daemons в начало каждого пайплайна stop lifecycle.

Билтины docker_* — Docker-специфичные; билтины service_* оперируют папками отдельных сервисов; имена без префикса — общие. Внутренние билтины следуют той же модели docker_* / без префикса.