Команда открывает pull request. CI собирает приложение, разворачивает отдельное окружение и добавляет ссылку на preview. Можно проверить интерфейс, пройти регистрацию и показать изменения коллегам.
Затем QA запускает сценарий с внешней интеграцией. Тестовый платёж проходит, но заказ остаётся неоплаченным: webhook URL у провайдера всё ещё ведёт в общий staging. Или адрес правильный, но событие приходит во время следующего деплоя, когда обработчик ещё не готов.
У временных окружений есть собственный жизненный цикл. Они появляются для конкретной задачи, пересоздаются после изменений и удаляются после проверки. Внешняя система о pull request ничего не знает: она отправляет событие на зарегистрированный URL по своим правилам и в своё время.
Чтобы проверять такие интеграции до слияния ветки, приём вебхуков нужно включить в устройство preview-окружения. В Adal Cloud публичный вход и конечный обработчик можно разделить: внешний сервис отправляет запрос на URL Сервера Adal Cloud, а Destination определяет, в какое приложение его доставить.
Почему preview приложения ещё не означает preview интеграции
Под ephemeral environments обычно понимают временные окружения, созданные для ветки, pull request или отдельного запуска проверки. Branch preview позволяет посмотреть конкретное изменение, временный деплой — воспроизвести проблему, QA-окружение — проверить релиз на изолированных данных.
Для вебхуков этого недостаточно. Нужна связь между внешним событием и именно той копией приложения, которую проверяет команда.
Представим две параллельные ветки. В первой меняется обработка подписок, во второй — возврат платежа. Если обе используют один тестовый аккаунт провайдера и один webhook URL, события могут попадать в общий staging или одновременно в оба preview. Тогда результат зависит от чужих действий: один тест создаёт данные, другой получает неожиданное событие.
Проверка становится полезной, когда команда может связать четыре вещи: ветку, тестовые данные, источник события и обработчик. Сам адрес preview решает только последнюю часть.
Для таких проверок используйте тестовые ключи и изолированные данные. Preview с экспериментальным обработчиком не должен получать production-события или выполнять реальные платежи и уведомления клиентам.
Стабильный вход перед временным приложением
URL Сервера Adal Cloud действует, пока существует сам Сервер. Его можно зарегистрировать у провайдера и сохранить при пересоздании приложения. Меняется адрес доставки в Destination, а публичная точка приёма остаётся прежней.
Для одного тестового потока маршрут выглядит так:
Тестовая среда внешнего сервиса
→ постоянный HTTPS URL Сервера Adal Cloud
→ Request
→ Destination текущего preview
→ обработчик из проверяемой ветки
Например, preview для PR-184 получил новый адрес после повторного развёртывания. Если команда сохраняет Сервер Adal Cloud для этого PR, внешний webhook URL менять не требуется. Нужно обновить адрес получателя и проверить доставку в новую копию приложения.
Это разделяет два жизненных цикла: приложение можно пересоздавать чаще, чем точку приёма внешних событий. При включённом постоянном хранении запросы и их история доступны в пределах retention, даже если временное приложение уже остановлено.
Публичный preview и окружение в закрытой сети
Если обработчик preview доступен из интернета, используйте Destination типа Direct HTTP. Adal Cloud отправит принятый запрос на публичный адрес приложения.
Если окружение работает в частной сети, для доставки можно запустить Adal CLI рядом с приложением:
Внешний сервис
→ Сервер Adal Cloud
→ Adal CLI в сети preview-окружения
→ внутренний webhook-обработчик
Adal CLI устанавливает исходящее защищённое соединение. Внутреннему обработчику не нужны публичный IP и открытый входящий порт. URL Destination должен быть доступен с машины или контейнера, где работает CLI: localhost внутри отдельного контейнера не обозначает соседний контейнер с приложением.
CLI должен работать столько, сколько команда использует preview. Если запустить его только внутри короткой CI-задачи, соединение завершится вместе с ней, хотя само окружение ещё будет нужно QA. Процесс доставки следует включить в жизненный цикл деплоя.
Сам обработчик по-прежнему должен проверять подпись провайдера и содержимое запроса перед выполнением действий.
Выбор маршрута также зависит от защиты preview. Публичная страница за формой входа не обязательно принимает серверные HTTP-запросы. Direct HTTP требует доступного обработчика; способ доступа нужно проверить отдельно. Настройка обоих вариантов описана в документации по Destinations.
Как разделить параллельные ветки
Постоянный входящий URL удобен, но он сам по себе не определяет, какому PR принадлежит событие. Схему стоит выбирать по тому, какие проверки команда запускает одновременно.
| Сценарий | Организация потока | Что учесть |
|---|---|---|
| Один QA-стенд для последовательных проверок | Постоянный Сервер Adal Cloud, Destination ведёт в текущий деплой | Перед переключением завершить проверку и разобраться с ожидающими событиями |
| Несколько независимых branch previews | Отдельный Сервер и тестовый поток для каждого preview | Провайдер должен позволять разделить события между endpoint или тестовыми аккаунтами |
| Сравнение двух версий обработчика | Один Сервер, две Destinations, одинаковый запрос в обе версии | Это намеренная доставка в обе цели; данные и побочные действия должны быть изолированы |
Для независимых PR отдельные Серверы Adal Cloud делают маршруты явными. URL каждого Сервера регистрируется для соответствующего тестового потока и остаётся прежним при повторных деплоях этого preview. Создание нового PR при такой схеме всё же требует настройки его входящего адреса у провайдера.
Разделение на стороне Adal Cloud должно соответствовать разделению у отправителя. Если провайдер отправляет все события одного аккаунта на каждый зарегистрированный endpoint, добавление нескольких URL не изолирует тесты. Понадобятся отдельные тестовые аккаунты, sandbox-проекты или другие предусмотренные провайдером средства разделения.
Несколько Destinations одного Сервера получают один входящий Request. Это удобно для сравнения версий, но не означает автоматический выбор ветки. Имя Destination вроде PR-184 помогает ориентироваться в панели и не становится правилом маршрутизации. Разные пути одного Сервера также не создают отдельные изолированные потоки с собственными Destinations.
Что включить в жизненный цикл CI/CD
Маршрут вебхука стоит описывать вместе с деплоем. Для команды важна понятная последовательность действий:
Назначить тестовый поток. Связать preview с PR, тестовым аккаунтом провайдера и Сервером Adal Cloud. При повторном деплое использовать прежнюю связь, если назначение окружения сохранилось.
Настроить получателя. Указать адрес нового приложения в Destination и выбрать Direct HTTP или Adal CLI.
Подготовить приложение. Выполнить миграции, загрузить тестовые данные и убедиться, что webhook-обработчик готов. Для закрытого окружения подключить CLI после готовности приложения.
Проверить весь маршрут. Создать тестовое событие, найти Request, проверить Delivery и ожидаемое изменение данных в приложении.
Сохранить связь с проверкой. Зафиксировать PR, commit, адрес окружения и ID события в отчёте QA или CI. Это позволит понять, какой код обрабатывал запрос.
Завершить поток перед удалением. Отключить отправку новых событий для preview, проверить ожидающие доставки и сохранить нужные результаты диагностики.
Удалить временные ресурсы. Остановить CLI, убрать ненужный Destination и решить, нужен ли ещё Сервер с сохранёнными Requests в пределах retention.
Это схема организации процесса. Конкретные шаги автоматизации зависят от CI/CD-платформы и доступных интерфейсов провайдера. Сначала полезно проверить маршрут на одном preview, затем закрепить его в процедуре развёртывания.
Секреты тестовой интеграции и токен CLI должны поступать из хранилища секретов. Для CI с кодом из внешних pull requests отдельно определите, какие проверки могут получать эти секреты и в какой доверенной среде они выполняются.
Событие пришло во время деплоя
Представим, что QA уже создал тестовый платёж, а приложение в этот момент пересоздаётся. Публичный Сервер Adal Cloud может принять событие независимо от готовности preview. Дальнейшее поведение зависит от маршрута и настроек.
Если Direct HTTP обращается к ещё не готовому приложению и получает ошибку или тайм-аут, результат фиксируется в истории доставки. Следующие попытки выполняются по настроенной retry-политике.
Для CLI важно различать отсутствие соединения и ошибку приложения. Пока CLI отключён, попытка обращения к внутреннему обработчику не начинается. Если CLI подключён, но приложение недоступно, это уже неуспешная попытка.
За доставку ожидающих Requests после подключения отвечает Deliver pending requests on connect. Для этого сценария настройка должна быть включена, запрос — оставаться сохранённым в пределах retention, Destination — существовать, а CLI — подключиться к нужному Серверу. Готовность обработчика тоже обязательна.
Так можно пережить промежуток между двумя деплоями одного preview. Но накопленное событие всё ещё должно относиться к текущим тестовым данным. После полной очистки базы старый вебхук может ссылаться на заказ, которого в новом окружении уже нет.
Replay для QA и проверки исправления
Некоторые интеграционные ошибки трудно повторить. Вебхук возникает после нескольких действий в CRM, завершения внешней задачи или определённого изменения подписки. Воспроизводить всю цепочку после каждого изменения обработчика дорого по времени.
При постоянном хранении Request можно изучить, исправить код и выполнить Replay. Adal Cloud создаёт новый Request из сохранённого запроса и доставляет его в текущие Destinations Сервера. Ручной retry повторяет конкретную существующую доставку. Различие описано в документации по Requests.
Например, QA обнаружил, что обработчик неверно разбирает необязательное поле. Разработчик исправляет код и обновляет preview. Команда повторяет запрос, проверяет результат Delivery и затем смотрит, правильно ли изменились данные приложения.
Для осмысленной проверки нужно подготовить связанные сущности и состояние базы. Идемпотентный обработчик может пропустить уже обработанный event ID — это правильная защита от дубликатов, но для проверки новой логики потребуется контролируемое исходное состояние теста.
Нужно учитывать и правила подписи провайдера. Сохранённый запрос может не пройти проверку допустимого возраста подписи; например, такую защиту описывает Stripe. Adal Cloud не создаёт новую подпись провайдера. Для проверки полного пути с актуальной подписью используйте новое тестовое событие или предусмотренную провайдером повторную отправку.
Поздние вебхуки после удаления preview
Закрытый PR не означает, что внешний сервис уже перестал отправлять события. Асинхронная операция может завершиться позже, а у провайдера могут оставаться запланированные повторы.
Поэтому cleanup должен учитывать и источник событий, и получателя. Нельзя просто перенаправить канал PR-184 в PR-185: поздний вебхук первой проверки может изменить данные второй. Сохранение URL полезно при обновлении одного окружения, но повторное использование канала для другой задачи требует явного решения о старых событиях.
Если нужно разобрать результат после остановки preview, Сервер Adal Cloud можно оставить с постоянным хранением до конца необходимого окна диагностики. При этом удаление Destination удаляет связанные с ним данные доставки, включая историю попыток. Нужные сведения следует сохранить заранее; удаление самого Сервера также удаляет его сохранённые Requests. Retention и условия удаления описаны в документации по хранению данных.
Срок хранения выбирается под длительность проверки. Короткоживущий деплой не означает, что результаты его проверки должны исчезнуть в ту же минуту.
Что это даёт команде
Для B2B-приложения проверка интерфейса часто покрывает только часть сценария. Заказ, статус документа или состояние подписки могут зависеть от события из платёжной системы, CRM или сервиса обработки данных. Ошибка в этом участке становится заметна клиенту уже после внешнего действия.
Когда вебхуки доходят до нужного preview, команда может проверить интеграцию до слияния ветки. QA получает событие в своей копии приложения, разработчик видит исходный Request и историю доставки, а исправление можно проверить на сохранённом примере.
В Adal Cloud мы разделяем стабильный публичный приём и доставку в меняющееся окружение. Для временных деплоев это даёт постоянную точку входа, для параллельных веток — явно разделённые потоки, для QA — данные, по которым можно разобрать результат проверки.
Начните с одного тестового потока: создайте Сервер Adal Cloud, настройте Destination своего preview и проверьте реальное событие. Быстрый старт поможет настроить маршрут. Затем включите его создание, обновление и завершение в жизненный цикл окружения.