Доступные билтины
Билтины — это внутренние 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_ensureservice_configs_renderservice_configs_render_checkservice_generated_harvestservice_configs_copyservice_configs_checkmessageconfirmdocker_remove_project_volumesdocker_wait_healthycontainers_runninghttp_checkremove_pathssource_clone- Внутренние билтины движка (не вызываются из пользовательского YAML)
- Соглашение об именовании
Каталог
Заголовок раздела «Каталог»| Билтин | Назначение |
|---|---|
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-репозиторий в каталог относительно корня проекта, однократно (идемпотентно) |
service_dirs_ensure
Заголовок раздела «service_dirs_ensure»Создаёт директории хаба сервиса.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
service | string | обязательно | Имя папки сервиса из workspace/services/<name>/ |
mode | string | skip | skip, 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.
service_configs_render
Заголовок раздела «service_configs_render»Рендерит конфиг-файлы сервиса из шаблон-пака конфигов (workspace/templates/config/<pack>/) в директорию хаба сервиса (svc.Dir), воспроизводя любые собранные значения ${generated.<name>} из хранилища сгенерированных значений (.dwe/generated.yml). Это рендер-основанный преемник устаревшего service_configs_copy.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
service | string | обязательно | Ключ сервиса |
mode | string | replace | Поддерживается только 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: mainservice_configs_render_check
Заголовок раздела «service_configs_render_check»Проверяет, что каждая цель рендера пака конфигов для сервиса существует на диске. Его основное назначение структурное: добавление как check: шага service_configs_render заставляет этот шаг перезапускаться при каждом деплое (рычаг hasCheck → Run в journal/decision.go обходит пропуск по action-hash), так что правки шаблонов и очистки хранилища всегда вступают в силу — в точности зеркалируя service_configs_copy + service_configs_check.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
service | string | обязательно | Ключ сервиса |
Сервису без разрешимого пака конфигов нечего проверять, и он no-op. Возвращает ошибку с перечислением отсутствующих отрендеренных файлов, что приводит к падению проверки.
service_generated_harvest
Заголовок раздела «service_generated_harvest»Читает каждое из объявленных полей generated: сервиса из его файла на диске, извлекает значение по регекспу поля (группа захвата 1) и записью-если-отсутствует сохраняет его в хранилище сгенерированных значений (.dwe/generated.yml). Хранилище сохраняется атомарно при записи нового значения.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
service | string | обязательно | Ключ сервиса |
«Собрать, а не сгенерировать»: собственный генератор сервиса (например, php artisan key:generate) пишет секрет; DWE только считывает его обратно и воспроизводит при последующих рендерах. Запись-если-отсутствует означает, что значение, уже находящееся в хранилище, сохраняется, поэтому повторный деплой — это no-op. Сервис без полей generated: — это no-op. Отсутствующий файл, паттерн, не совпавший ни с одной строкой, паттерн без группы захвата или захваченное пустое значение выдаются как ошибки — никогда не пропускаются молча. См. блок generated и render config.
service_configs_copy
Заголовок раздела «service_configs_copy»⚠️ Устарело. Заменено на
service_configs_render+service_generated_harvest. Продолжает работать, ноdwe validateвыдаёт предупреждение, и при каждом шаге копирования срабатывает однократное runtime-уведомление об устаревании. См. render config для замены.
Копирует шаблонные конфиг-файлы из configs/services/<service>/ в services/<service>/configs/. Создаёт директорию назначения configs/, если её нет — это канонический путь создания configs/ (билтин service_dirs_ensure её не создаёт).
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
service | string | обязательно | Ключ сервиса |
mode | string | replace | default, update или replace |
Поведение режимов:
| Режим | Назначения нет | Назначение существует |
|---|---|---|
default | записать | no-op |
replace | записать | безусловно перезаписать |
update | записать | смерджить новые строки KEY=VALUE без изменения существующих ключей (с учётом env-файлов) |
Когда у соответствующей записи configs[] есть mountpoint, билтин также создаёт пустой файл в <service-dir>/<mountpoint>, чтобы Docker Desktop virtiofs мог наложить поверх него вложенный файловый bind mount.
service_configs_check
Заголовок раздела «service_configs_check»⚠️ Устарело. Компаньон-
check:устаревшегоservice_configs_copy. Для рендер-основанных конфигов используйтеservice_configs_render_check.
Проверяет, что все шаблонные конфиг-файлы, декларированные в service.yml сервиса, существуют в его хабе после шага service_configs_copy. Используйте как действие check:, чтобы убедиться, что конфиги успешно развёрнуты.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
service | string | обязательно | Ключ сервиса |
Возвращает ошибку с перечислением отсутствующих файлов, что приводит к падению проверки. Обычно используется как 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: mainmessage
Заголовок раздела «message»Печатает сообщение в вывод деплоя.
| Параметр | Тип | Описание |
|---|---|---|
level | string | info, success, warning или error (обязательно) |
text | string | Текст сообщения (обязательно); поддерживает Go template-выражения на DweConfig |
- name: done type: builtin cmd: message with: level: success text: "Deploy of {{ .Project.Name }} completed"confirm
Заголовок раздела «confirm»Запрашивает у пользователя подтверждение перед продолжением. Пропускается при заданном флаге --yes или когда шаг подтверждается через ExecContext.SkipConfirm. В TTY использует huh.Confirm; в piped/CI stdin откатывается к простому Y/n.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
message | string | Are you sure? | Текст промпта |
ok_msg | string | Continuing | Сообщение об успехе после подтверждения |
stop_msg | string | Aborted | Сообщение об ошибке после отказа / Esc |
docker_remove_project_volumes
Заголовок раздела «docker_remove_project_volumes»Удаляет все Docker-тома, имя которых начинается с <project_name>_ (разрешается из docker.yml по объединённому конфигу). Параметров нет. Прерывается, если разрешённое имя проекта пусто.
docker_wait_healthy
Заголовок раздела «docker_wait_healthy»Ожидает, пока Docker-контейнеры достигнут healthy-состояния. Поллит активный стек Docker Compose, пока все указанные контейнеры не станут healthy или не истечёт таймаут.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
timeout | string duration | 60s | Максимальное время ожидания; должно быть положительным (например, 120s, 2m) |
interval | string duration | 2s | Интервал опроса; должен быть положительным |
services | list 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().
containers_running
Заголовок раздела «containers_running»Быстрая проверка «запущен» для compose-сервисов. В отличие от docker_wait_healthy он не поллит готовность, не учитывает таймаут и не требует, чтобы у сервисов был объявлен healthcheck — вызов docker compose ps --status=running --services возвращает набор сейчас запущенных сервисов, и билтин делает diff с запрошенным списком.
Транзиентный сбой проверки — когда сам вызов docker compose ps завершается с ошибкой (любой ненулевой сбой выполнения, например ненулевой код выхода прямо на границе docker up --wait, пока compose CLI / демон на мгновение заняты, хотя все контейнеры уже подняты) — повторяется ограниченное число раз с короткой паузой перед тем, как шаг упадёт; единственное исключение — отменённый контекст, он немедленно прерывает оставшиеся повторы. Это не поллинг готовности: если проверка отработала успешно, но сообщает, что сервис не запущен, шаг падает с первой попытки. Когда все повторы неудачны, stderr от docker compose ps попадает в текст ошибки, чтобы сбой можно было диагностировать.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
services | list 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>.
http_check
Заголовок раздела «http_check»Билтин-предикат (KindPredicate), выполняющий HTTP GET и утверждающий ответ. Возвращает успех, когда эндпоинт отдаёт ожидаемый код статуса и — когда задан contains: — тело, содержащее указанную подстроку. При сбое повторяет попытку до retries раз, ожидая interval между попытками; каждая отдельная попытка ограничена timeout.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
url | string | обязательно | Целевой URL. Должен парситься как абсолютный http/https URL с хостом. |
status | int | 200 | Ожидаемый код статуса HTTP. |
contains | string | — | Опциональная подстрока, которая должна присутствовать в теле ответа. Когда пусто, тело не читается. |
retries | int | 0 | Дополнительные попытки после первой при несовпадении/ошибке. Всего попыток = retries + 1. Должно быть >= 0. |
interval | string duration | 1s | Ожидание между попытками. Должно быть >= 0. Отменяется через контекст. |
timeout | string duration | 5s | Таймаут на попытку (не общий). Должно быть > 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, до запуска пайплайна.
remove_paths
Заголовок раздела «remove_paths»Удаляет пути из файловой системы.
| Параметр | Тип | Описание |
|---|---|---|
paths | list of strings | Пути относительно проекта для удаления. Каждый должен быть относительным и не выходить за корень проекта; абсолютные пути и ..-обходы отклоняются на этапе валидации. |
source_clone
Заголовок раздела «source_clone»Клонирует git-репозиторий в каталог относительно корня проекта. Гейт идемпотентности встроен, поэтому шагу не нужна собственная пара when:/check:.
| Параметр | Тип | Описание |
|---|---|---|
repo | string | обязательно. Всё, что принимает git clone (SSH-remote, HTTPS-URL, локальный путь). |
dir | string | обязательно. Назначение относительно корня проекта. Абсолютные пути, . и ..-обходы отклоняются на этапе валидации; символическая ссылка в компоненте пути отклоняется во время выполнения. |
branch | string | опционально. Передаётся как 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_* / без префикса.