Темы



Представляем Worker Previews: изолированные среды предварительного просмотра для каждого изменения, внесенного вашим агентом

Коротко сгенерировано ИИ по тексту статьи
  • Cloudflare запустила Worker Previews для автоматического создания изолированных сред предпросмотра под каждую Git-ветку с отдельным URL и конфигурацией.
  • Каждое превью автоматически изолирует пространства имен Durable Objects и контейнеры, защищая продакшен-данные от некорректных миграций и изменений схем.
  • Инструмент поддерживает работу на кастомных доменах, авторизацию через Cloudflare Access и полный мониторинг запросов через Workers Observability.

Почему это важно: Среды позволяют разработчикам и ИИ-агентам проверять атомарные изменения в реальных условиях и устранять ошибки до слияния кода с продакшеном.

Нет ничего хуже, чем тестировать изменения, которые отлично работают в тестовой среде (staging), а затем видеть, как они ведут себя совершенно иначе в продакшене. Именно поэтому мы хотели предоставить вам среду, максимально приближенную к продакшену, — чтобы вы могли протестировать свои изменения в «боевых» условиях и убедиться, что они работают ровно так, как вы ожидали.

Агенты помогают нам писать больше строк кода, чем когда-либо прежде, а более масштабные изменения требуют более тщательного тестирования перед релизом. В идеале такое тестирование должно быть организовано так, чтобы не замедлять работу агентов, но при этом давать им инструменты для участия в больших этапах жизненного цикла разработки.

Именно поэтому сегодня мы запускаем Worker Previews. Каждая ветка Git получает похожую на продакшен среду для запуска со собственным кодом, конфигурацией, URL-адресом, средствами мониторинга и состоянием.

Теперь для каждого изменения в вашей кодовой базе вы можете:

  • Развернуть изолированный предварительный просмотр (Preview) с помощью npx wrangler preview, используя собственные переменные, секреты и привязки (bindings), отдельно от продакшен-конфигурации и трафика.
  • Поделиться стабильным URL-адресом предварительного просмотра для ветки, чтобы каждый пуск (push) обновлял один и тот же запущенный Preview, где можно отправлять запросы, кликать по интерфейсу и тестировать ответы во время выполнения.
  • Изолировать Durable Objects и Container-приложения для каждой ветки, сохраняя изменения состояния, сессии, память, миграции и параллельные тесты в рамках конкретного Preview.
  • Анализировать логи, ошибки, метрики и трассировки для этого Preview, чтобы убедиться в работоспособности изменений, отловить сбои, отправить исправление и проверить его до того, как изменения увидят пользователи в продакшене.
  • Начинать работу с заранее заданной конфигурации Preview: каждый Preview стартует с копии определенных вами переменных, секретов, привязок и настроек — точно так же, как ветка кода начинается с main. Мы называем это базовой конфигурацией.
  • Переопределять конфигурацию Preview при необходимости (например, направляя ее на собственную базу данных или тестовый ключ API для миграций) — без изменения продакшена, базовой конфигурации или настроек других Preview.
  • Обслуживать URL-адреса Preview на собственном домене, чтобы провайдеры авторизации, файлы cookie, совместное использование ресурсов между разными источниками (CORS) и перенаправления OAuth работали точно так же, как в продакшене.

Результатом является цикл обратной связи на этапе перед продакшеном для каждой ветки. Отправьте изменения в ветку, протестируйте поведение, оцените производительность — еще до слияния (merge) с продакшеном.

Это делает возможным внедрение жизненного цикла разработки с участием агентов (Agent Development Lifecycle — ADLC), при котором каждое изменение является атомарным, независимо развертываемым, наблюдаемым и проверяемым. Кроме того, это дает агентам и людям необходимые данные для самосовершенствования: обнаружить ошибку, отправить исправление и проверить следующее развертывание до того, как оно попадет в продакшен.

Каждая ветка Git получает собственную среду

Когда вы начинаете работу над новой функцией, первое, что вы делаете — создаете ветку на основе main. Вы получаете собственную копию кода и вносите изменения, не затрагивая ничего в продакшене.

Worker Previews распространяют эту модель и за пределы кода. Каждая ветка получает свою собственную изолированную среду и URL-адрес. Вы можете запускать сотни Preview одновременно — каждый из них работает независимо, не влияя на другие Preview или продакшен.

ch1.png

Продакшен и каждый Preview имеют собственную конфигурацию, доступную по своему URL-адресу.

Когда вы запускаете npx wrangler preview, ветка получает собственную копию определенной вами конфигурации Preview, работающую по собственному URL — и всё это в рамках одного Worker.

В панели управления это работает как переключение веток. Нажмите на навигационную цепочку (breadcrumb) рядом с именем вашего Worker (по умолчанию это Production), чтобы просмотреть все ваши Preview:

Панель управления объединяет все среды в едином интерфейсе. Продакшен соседствует с любым необходимым количеством Preview, поэтому разработчики могут работать над отдельными изменениями, не конфликтуя из-за общей тестовой среды. В отличие от сред Wrangler, где для каждой среды требуется развертывать и администрировать отдельный Worker, Preview сохраняют изоляцию в рамках единого представления панели управления.

Каждый Preview работает как реальная версия вашего Worker. Некоторые изменения можно проверить только во время выполнения: конечная точка API должна обработать реальный запрос и вернуть правильный ответ. Более субъективные изменения, такие как обновление пользовательского интерфейса, новый шаг онбординга или другое состояние ошибки, должны быть оценены в контексте до того, как они попадут в продакшен.

Каждый Preview имеет собственное изолированное и персистентное состояние благодаря Durable Objects и Containers

Чтобы изоляция распространялась на всё приложение, ресурсы с сохранением состояния (stateful) требуют особого подхода. Причина в том, что Durable Objects работают по модели синглтона. За конкретный идентификатор объекта отвечает единственный экземпляр, которому принадлежит его хранилище.

Если бы Preview разделял то же пространство имен DO (DO namespace) с продакшеном, вы бы не просто читали устаревшие данные — вы могли бы в реальном времени изменять тот же экземпляр, который обслуживает живой трафик (страшно!).

Именно поэтому каждый раз, когда вы запускаете npx wrangler preview, Cloudflare автоматически создает новое пространство имен Durable Object и Container-приложение для этого Preview, благодаря чему неудачная миграция или некорректное изменение схемы остаются локализованными исключительно в пределах этой ветки.

Все, что вам нужно сделать, это экспортировать класс, добавить его миграцию и получить к нему доступ через ctx.exports:

export class Counter extends DurableObject {}

export default {
  async fetch(request, env, ctx) {
    const id = ctx.exports.Counter.idFromName("demo");
    const counter = ctx.exports.Counter.get(id);
    return counter.fetch(request);
  },
};

В продакшене ctx.exports.Counter разрешается в продакшен-пространство имен, в то время как в Preview — в пространство имен этого Preview.

Теперь в вашем распоряжении целый полигон для экспериментов. Возьмем, к примеру, песочницы (Sandboxes), где миллисекунды улучшения времени запуска могут иметь решающее значение для пользовательского опыта. Если вы пытаетесь улучшить производительность при «холодном старте», вы можете одновременно запускать разные конфигурации в разных ветках, сравнивать их производительность в холодном и разогретом состояниях бок о бок и быстрее находить оптимальную настройку.

Тестируйте, наблюдайте и дорабатывайте каждый Preview (или поручите это своему агенту)

Теперь, когда каждая ветка работает по собственному URL-адресу в изолированной среде со своим собственным состоянием, вы можете задействовать цикл обратной связи и начать тестирование каждого изменения в реальных условиях до того, как оно попадет в продакшен.

Вы можете отправлять трафик на URL-адрес Preview привычным вам способом — из терминала, выполняя проверки из CI, с помощью агента или кликая по интерфейсу самостоятельно. Как только трафик начинает поступать, все привычные вам инструменты Workers Observability становятся доступны и привязаны к каждому отдельному Preview.

По мере того как каждый запрос поступает в Preview, инструменты Workers Observability отслеживают весь его жизненный цикл в виде «водопада» (waterfall), включая вызовы fetch, операции привязок и вызовы обработчиков. Поэтому, когда что-то идет не так, вы можете проследить точную последовательность событий, не разбираясь в продакшен-трафике или сигналах от других изменений.

Мониторинг для Preview выглядит точно так же, как вы привыкли видеть для продакшен-воркеров. Выберите свой Preview в навигационной цепочке и откройте вкладку Observability, чтобы просмотреть его события, ошибки и трассировки:

Чтобы предоставить вашим агентам еще больше контроля, вы можете заставить их открывать URL-адрес Preview в headless-браузере, пошагово проходить процедуру входа в систему и делать скриншоты или записывать всю сессию в виде воспроизводимых DOM-событий с помощью Browser Run.

Ниже приведен пример, в котором агент открывает Preview, фиксирует отрисованное содержимое и сопоставляет неудачный запрос с событиями Workers Observability из того же запуска.

Проверяющий может наблюдать за сеансом в реальном времени с помощью функции Live View или вмешаться с помощью функции Human in the Loop («человек в контуре»), когда автоматике требуется экспертная оценка.

Если что-то идет не так, вы видите проблему с двух сторон: что было отрендерено на экране и что произошло на уровне выполнения.

Это дает агенту достаточно данных для автономного продолжения предпродакшен-цикла: развернуть, открыть URL с помощью Playwright MCP, пройти по шагам интерфейса, запросить трассировки через MCP-сервер Workers Observability, внести патч, выполнить повторное развертывание и проверить результат. Каждая итерация остается в рамках конкретной ветки.

Настройте базовую конфигурацию для Preview один раз, а затем переопределяйте ее по мере необходимости

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

Вы задаете базовую конфигурацию для Preview один раз в блоке previews в своем конфигурационном файле Wrangler.

{
  "vars": {
    "ENVIRONMENT": "production"
  },
  "r2_buckets": [
    {
      "binding": "UPLOADS",
      "bucket_name": "prod-uploads"
    }
  ],
  "previews": {
    "vars": {
      "ENVIRONMENT": "preview"
    },
    "r2_buckets": [
      {
        "binding": "UPLOADS",
        "bucket_name": "r2-staging"
      }
    ]
  }
}

В панели управления в разделе Worker → Settings это отображается в виде Production и Previews Base. После того как база задана, выполните npx wrangler preview из любой ветки для создания Preview. Если ваш Worker связан с Git через Workers Builds, это происходит автоматически при пуше.

Вы можете переопределить любую настройку только для одного конкретного Preview — без ущерба для продакшена, базовой конфигурации или других Preview.

URL-адреса предварительного просмотра на вашем собственном домене, защищенные с помощью Cloudflare Access

Чтобы сделать всю систему еще ближе к продакшену, ваши URL-адреса предварительного просмотра могут обслуживаться с вашего собственного кастомного домена. Если ваше приложение работает на example.com, то Preview для ветки входа в систему может быть доступен по адресу feature-login.previews.example.com.

Если вы хотите сохранить конфиденциальность этих URL-адресов, вы можете защитить свои Preview с помощью Cloudflare Access, потребовав от посетителей предварительной авторизации.

Тестирование всей системы перед продакшеном

Мы уже используем Worker Previews внутри Cloudflare в рамках концепции dogfooding, в частности для сборки и тестирования CloudflareOS — нашей платформы с открытым исходным кодом для безопасного подключения агентов к корпоративным системам.

CloudflareOS позволяет агентам работать с такими сервисами, как Google, GitHub и Slack, с помощью Gatekeepers (шлюзов), которые контролируют доступ агентов к различным ресурсам и их возможности по внесению изменений. Из-за этого изменения в Gatekeeper особенно чувствительны к ошибкам, так как баг может непреднамеренно раскрыть данные или разрешить действие, которое ни в коем случае не должно было допускаться.

Некоторые из таких ошибок проявляются только тогда, когда OAuth-колбэки, разрешения, процессы согласования и состояние приложения выполняются одновременно. Поскольку тестирование каждого компонента по отдельности не может показать нам, как поведет себя вся система в сборе, мы развертываем изолированный Preview CloudflareOS и ее Gatekeepers для каждого рассматриваемого изменения. Затем мы запускаем полный рабочий процесс, исправляем то, что сломалось, и тестируем снова перед слиянием.

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

«Previews дает нам возможность проводить итерации на границе сети (edge) гораздо раньше. Для IKEA.com поддержка кастомных доменов помогает избегать проблем с политикой безопасности контента (CSP) и файлами cookie. Мы особенно рады поддержке Service Binding, которая обеспечит связь между Preview и станет настоящим прорывом для сквозного (end-to-end) тестирования по всей цепочке наших Worker». — Сантош Кумар Двиведи (Santosh Kumar Dwivedi), старший инженер-программист, IKEA

«В Supermemory мы активно используем Cloudflare, и Worker Previews — это именно то улучшение пользовательского опыта разработчиков, которое мы хотели увидеть. Для HTTP-потоков мы можем просматривать изменения Worker до того, как они попадут в продакшен, включая маршруты на базе Durable Objects, и выявлять проблемы на более ранних этапах без замедления процесса доставки релизов». — Дхравья Шах (Dhravya Shah), основатель Supermemory

«Previews потрясающе удобен для Inspect [кодинг-агент Ramp]. Я использовал его для ревью и тестирования PR для Inspect прямо с телефона, что делает ревью и тестирование PR с Inspect на мобильных устройствах отзывчивыми… вместе с Inspect». — Дилан Гарсия (Dylan Garcia), ведущий штатный инженер, Ramp

Что дальше?

Вы можете подумать: Разве у Workers не было URL-адресов для превью раньше? Это правда, были. Теперь мы называем их Version URLs, поскольку они указывают на конкретные загруженные версии Worker. В отличие от Worker Previews, они не создают изолированную среду для каждой ветки и могли ссылаться только на продакшен-ресурсы. Чтобы узнать больше и сравнить различные рабочие процессы, ознакомьтесь с нашей документацией.

Worker Previews — это большой шаг вперед по сравнению с тем, что мы предлагали ранее, но впереди еще много интересного. Вот над чем мы работаем прямо сейчас:

  • Предварительный просмотр многоворкерных (multi-Worker) приложений. На данный момент сервисная привязка из Preview по-прежнему вызывает продакшен-деплой связанного Worker. Мы работаем над тем, чтобы весь путь запроса целиком оставался внутри соответствующих Preview.
  • Запуск потребителей Queue и Workflows внутри каждого Preview. На сегодняшний день Preview могут отправлять сообщения в очереди (Queues), но не могут их потреблять, в то время как изоляция выполнения Workflow требует отдельной конфигурации. Мы хотим, чтобы весь асинхронный поток автоматически ограничивался рамками ветки.
  • Поддержка долгоживущих Preview для staging и QA. От команд, участвовавших в закрытом бета-тестировании, мы услышали, что не каждая ветка живет недолго — некоторые поддерживают среды staging, QA или индивидуальные среды для разработчиков, которые сохраняются между спринтами. Мы хотим обеспечить полноценную поддержку таких сценариев и будем рады услышать, как именно вы их используете, чтобы сделать всё максимально правильно.

Worker Previews уже доступны. Начните работу с документацией, а если у вас есть запрос на функцию или вы столкнулись с проблемой, откройте тикет на GitHub или присоединяйтесь к сообществу разработчиков Cloudflare в Discord.

Благодарности: Этот проект стал возможным благодаря усилиям по проектированию и реализации Грега Бримбла (Greg Brimble), Патрика О'Доннелла (Patrick O«Donnell), Мэтта Прайса (Matt Price), Коринн Алперс (Korinne Alpers), Макса Петерсона (Max Peterson), Сины Саффари (Cina Saffary), Джоша Уилера (Josh Wheeler), Томаса Анккорна (Thomas Ankcorn), Мэтта Ротенберга (Matt Rothenberg) и Брэндона Сриттматтера (Brandon Strittmatter) под руководством Брендана Ирвайна-Брока (Brendan Irvine-Broque) и Дэна Картера (Dan Carter).

© Cloudflare Blog