nodbox
Разделы документации

Автодеплой по push

Новая версия на каждый push в выбранную ветку: как включить и выключить автодеплой, вебхук, фильтр путей и пометки, пропускающие деплой.

Автодеплой заводит новую версию приложения на каждый push в ветку, которая записана в приложении. Работает он у приложений из репозитория: у приложений из архива и из готового образа push нет, версию для них заказывают вручную.

Пока автодеплой выключен, push ничего не делает, а версию можно заказать из панели или по API. Версия, которую завёл push, ничем не отличается от заказанной вручную: те же сборка, статусы и откат, подробности - в разделе Версии и откат.

Как включить и выключить

Автодеплой включается переключателем у приложения. В панели он называется «Деплоить каждый пуш» и стоит в двух местах:

  • при создании приложения, под выбором ветки, сразу включённым
  • в приложении, на вкладке «Настройки», в карточке «Деплой по пушу»

Выключить автодеплой можно там же. Правка настроек ничего не деплоит: новое значение действует на следующий push.

По API то же делают поле auto_deploy и фильтр watch_paths в запросах POST /api/v1/applications и PATCH /api/v1/applications/{id}. Если при создании поле не прислать, автодеплой выключен. У приложения из архива или образа оба поля API отклоняет с ошибкой 422.

Автодеплой привязан к ветке приложения. Push в другую ветку, пуш тега и удаление ветки версию не заводят.

Как push доходит до платформы

Push сообщает платформе вебхук - запрос, который git-сервис отправляет на адрес платформы после каждого push. Кто заводит этот вебхук, зависит от сервиса:

Сервис Вебхук Что делать
GitHub платформенный, один на всех ничего: события приходят сами
GitLab твой, на каждый репозиторий завести вебхук и вписать адрес и секрет из панели
Bitbucket твой, на каждый репозиторий завести вебхук и вписать адрес и секрет из панели

У GitLab и Bitbucket платформа получает доступ только на чтение, поэтому вебхук за тебя создать не может.

У GitLab и Bitbucket платформа принимает доставку, только если она подписана секретом подключения. GitLab присылает сам секрет в заголовке X-Gitlab-Token. Bitbucket считает от тела запроса подпись SHA-256 на секрете (HMAC) и присылает её в заголовке X-Hub-Signature. Доставка без секрета или с неверным секретом получает ответ 403, версию такая доставка не заводит.

GitHub

Для приложений из GitHub настраивать нечего. Вебхук уже есть у GitHub App, которое ты установил при подключении, и push приходит на платформу сам. Нужно, чтобы приложение nodbox было установлено на репозиторий: если при установке ты выбрал отдельные репозитории, нужного может не оказаться в списке. Как подключить аккаунт и добавить репозиторий, описано в разделе Подключение GitHub, GitLab и Bitbucket.

GitLab

Вебхук заводится на каждый репозиторий, который ты деплоишь:

  1. В панели открой «Источники кода», найди подключение GitLab и нажми «Настроить автодеплой». В окне будут адрес и секрет.
  2. В GitLab открой проект, раздел Settings → Webhooks, и добавь вебхук.
  3. В поле URL вставь адрес из панели, в поле Secret token - секрет.
  4. Из событий оставь Push events. Остальные платформа не читает: она отвечает на них кодом 200 и ничего не делает.
  5. Сохрани вебхук.

Адрес и секрет один на подключение: во всех репозиториях этого подключения вписывай одни и те же значения.

Bitbucket

Здесь то же, что в GitLab:

  1. В панели открой «Источники кода», найди подключение Bitbucket и нажми «Настроить автодеплой». В окне будут адрес и секрет.
  2. В Bitbucket открой репозиторий, в его настройках раздел Webhooks, и добавь вебхук.
  3. В поле URL вставь адрес из панели, в поле Secret - секрет.
  4. В триггерах выбери событие Repository push. Платформа читает только его, то есть repo:push, остальные события она пропускает.
  5. Сохрани вебхук.

Один push может обновить несколько веток сразу, и Bitbucket присылает их одной доставкой. Платформа проверяет каждую ветку отдельно.

Секрет вебхука

Секрет принадлежит подключению: он общий для всех его репозиториев. В панели его можно открыть снова в любой момент, окно «Автодеплой по push» показывает его каждый раз. Отдельно сменить секрет нельзя: он выводится из самого подключения.

Какой push заводит версию

Платформа заказывает версию приложения, когда выполнены все условия:

  • у приложения включён автодеплой, а источник - репозиторий этого подключения
  • push пришёл в ветку приложения, именно в неё, без шаблонов
  • в сообщении последнего коммита push нет пометки, пропускающей деплой
  • пути изменённых файлов проходят фильтр, если он задан
  • доступ к git-сервису действует, а проект не удаляется и не заблокирован за долг
  • приложение не останавливается и не удаляется
  • на балансе хватает денег на запас, если деплой увеличивает мощность приложения, как и при ручном деплое

Если репозиторий подключён к нескольким приложениям, push заказывает версии всем, кому он подходит по ветке и фильтру.

Фильтр путей для монорепозитория

В монорепозитории из одного репозитория запускают несколько приложений, и push в apps/api не должен пересобирать apps/web. Фильтр путей говорит, какие изменения считать своими. В панели он называется «Что считать изменением» и показывается под переключателем автодеплоя, в API это watch_paths.

Фильтр - список путей от корня репозитория. Push заводит версию, если хотя бы один его файл, добавленный, изменённый или удалённый, лежит под одним из путей:

  • путь к каталогу накрывает всё внутри: apps/web совпадает с apps/web/src/index.ts
  • путь к файлу совпадает с этим файлом: package.json следит за одним файлом
  • совпадение идёт по целым сегментам: apps/web не накрывает apps/website
  • пустой список означает любое изменение, это умолчание

Правила записи путей:

  • без ведущего слэша, слэш в конце убирается сам
  • без сегментов . и ..
  • без шаблонов: звёздочки не раскрываются, а читаются как обычные символы
  • регистр различается
  • до 20 путей в списке, каждый до 255 символов

Список в панели и по API заменяется целиком: то, что ты прислал, и есть новый фильтр.

Три оговорки:

  • GitHub кладёт в событие не больше 20 коммитов. Если в push их 20 или больше, список файлов неполон, фильтр не судит, и версия заказывается: лишний деплой дешевле пропущенного. Так же платформа поступает, когда GitLab сообщает, что прислал не все коммиты.
  • Bitbucket не присылает список изменённых файлов вовсе, поэтому для него фильтр не работает: версию заводит любой push в ветку приложения.
  • Фильтр отвечает только на вопрос «заказывать ли версию». Из какой папки собирается приложение, задаёт корневая директория в настройках сборки.

Пометки, пропускающие деплой

Если в сообщении коммита стоит одна из четырёх пометок, push не заводит версию:

  • [skip deploy]
  • [deploy skip]
  • [skip ci]
  • [ci skip]

Правила поиска:

  • квадратные скобки обязательны: слова «skip ci» без них ничего не значат
  • регистр не важен: [Skip CI] работает так же
  • пометка может стоять в любой части сообщения, в заголовке или в тексте
  • смотрится только сообщение последнего коммита push, тот, на котором встала ветка: пометка в предыдущих коммитах не учитывается

Пометка действует только на автодеплой. Версию, пропущенную так, можно заказать вручную из панели или по API, пометки там не проверяются.

Серия push подряд

Каждый push, прошедший условия, заводит свою версию со своим номером. Версии не стоят в очереди: новая версия отменяет идущий деплой предыдущей, на каком бы этапе он ни был, будь то загрузка кода, сборка или выкат. Отменённая версия остаётся в истории как отменённая, письма об отмене не приходит.

Платформа клонирует ветку на момент загрузки кода, поэтому в новой версии уже есть изменения прерванной. Пока новая версия собирается, продолжает отвечать работающая прежняя, а сборка отменённой версии ничего не стоит: плата начинается с подтверждённого выката.

Если вебхук прислал одну и ту же доставку дважды, например при повторной отправке из журнала GitLab или Bitbucket, вторая версия не появится. Чтобы собрать тот же коммит ещё раз, закажи деплой вручную.

Что видно после срабатывания

Версия заводится, как только платформа получает доставку, отдельного подтверждения нет. Увидеть её можно в приложении:

  • на вкладке «События» появляется запись «Заказан деплой версии v7», затем «Версия v7 выкачена и получила весь трафик», а отменённая предшественница получает запись «Деплой версии v6 отменён»
  • на вкладке «Версии» у каждой версии есть коммит: первые семь знаков хеша, сообщение и автор
  • на вкладке «Сборка» идёт лог сборки

Панель не помечает, что версия заведена push, а не вручную. Об этом говорит коммит версии. Если деплой версии не удался, платформа отправляет письмо, когда этот повод включён в уведомлениях.

Пропущенный push следа в панели не оставляет. Лента событий рассказывает, что было с приложением, и запись о каждом отфильтрованном push забила бы её: в монорепозитории большинство push не касается приложения.

Почему версия не появилась

Сначала проверь причины, которые видны в приложении:

  • автодеплой включён, а в карточке «Деплой по пушу» стоит нужная ветка
  • push был в эту ветку, а не в соседнюю
  • сообщение последнего коммита не содержит пометки
  • пути изменённых файлов проходят фильтр
  • подключение в «Источниках кода» действует, а не отозвано
  • баланс проекта не ниже порога и проект не заблокирован

Если всё сходится, смотри журнал доставок вебхука. В GitLab он в настройках вебхука, в Bitbucket - там же, в просмотре запросов. У GitHub вебхук принадлежит приложению nodbox, поэтому в настройках репозитория журнала нет.

Если доставок в журнале нет вовсе, вебхук не заведён на этот репозиторий или в нём не выбрано событие push. У каждой доставки виден код ответа платформы:

Ответ Что значит Что делать
403 секрет не совпал или не указан вставь секрет из окна «Автодеплой по push» заново, без пробелов по краям
200 доставка принята смотри тело ответа

Тело ответа - JSON с тремя полями. Поле status принимает значения:

  • accepted - доставка разобрана, в deployments число заказанных версий
  • ignored - событие не про push в ветку: тег, удаление ветки или другое событие, а также подключение, которого платформа не знает
  • duplicate - эта доставка уже разобрана

Поле skipped называет приложения, которым версию не заказали, и причину:

Причина Что значит
branch_mismatch push пришёл не в ветку приложения
path_filter ни один изменённый файл не лежит под путями фильтра
skip_directive в сообщении последнего коммита есть пометка, пропускающая деплой
connection_inactive доступ к git-сервису отозван или подключение удалено, подключи аккаунт заново
project_unavailable проект удаляется или недоступен
project_suspended проект заблокирован за долг
insufficient_funds на балансе не хватает денег на запас для прироста мощности
application_busy приложение останавливается или удаляется

Что дальше


Страница в markdown, так её читает агент: /docs/deploy/auto-deploy.md