Учебное руководство
Главы руководства
На этой странице

Полные стенды SourceCraft

Оглавление · SourceCraft CI и доставка

Интеграция влита в SourceCraft main через PR !11. Control workflow проверен в CI; контроллер и холодный runtime установлены на VPS из main 43d552c. Полный цикл test и PR проверяется отдельным приёмочным PR; описание кода не означает, что все этапы живой проверки уже завершены.

Main разворачивается на web.test.gheilt.mxsource.xyz, собственный PR — на web.pr-N.gheilt.mxsource.xyz. У каждого также cms, media, storybook, docs. Свои PostgreSQL, Garage, Strapi, доступы и volumes. Production сохраняет прежние адреса и существующий pipeline до отдельного переключения.

Первый запуск копирует только опубликованные документы и используемые media текущей production CMS. Черновики, пользователи, токены и webhook не копируются. Исходный внешний сайт не используется. Медиа читаются напрямую из текущего Garage через внутреннюю сеть и фиксированный Host штатным http.request: Node.js fetch этот заголовок не передаёт; исходные публичные URL сохраняются как ключи снимка, затем импорт меняет их на адреса стенда. Повторный push сохраняет контент и редакторские изменения стенда.

Экспорт: pnpm cms:snapshot --destination var/content-import/published. Проверка снимка: pnpm cms:snapshot --dry-run --destination var/content-import/published. Старая внешняя команда переименована в cms:snapshot:external и не входит в pipeline стендов. Импорт published snapshot требует выделенное окружение, поддерживает dry-run и отказывается перезаписывать существующие редакторские записи.

Авторитет состояния и доставка

SourceCraft CI публикует готовые digest-манифесты и отдельный снимок веток/PR в существующий release repository YC. VPS использует свою pull-only учётку и outgoing HTTPS; персональный PAT SourceCraft на VPS не хранится. Control workflow срабатывает при main push и по расписанию каждые 10 минут. Приёмник проверяет полное чтение страниц API, собственный repository, source/target PR, SHA и свежесть control не более 20 минут. Неизвестное или устаревшее состояние не разрешает обновление/удаление стенда.

PR CI должен проверить точный head и актуальный main base; чужие/fork PR выполняют обычные проверки без privileged publication. Проверки готовности включают публичные HTTP endpoints стенда. Перед merge агент сверяет head/base, CI, живой стенд и обсуждения; branch protection тарифом не заменяем. Агент работает в собственном worktree и ветке от свежего SourceCraft main.

TTL и холодный режим

PR удаляется после закрытия/merge или 12 часов без нового head. Повтор CI и HTTP обращения lease не продлевают. Контроллер обрабатывает свежие сведения о закрытии; при расписании отсутствие события закрытия обнаруживается в следующем 10-минутном цикле плюс опрос VPS. После TTL удаляются контейнеры, сети, volumes, снимок, локальные доступы и маршруты данного PR. Новый commit открытого PR создаёт новый стенд с текущим опубликованным контентом.

PR/test/staging охлаждаются через 30 минут без HTTP к любому из пяти доменов. Холодный режим сохраняет данные и digest. HTTP отвечает 503/Retry-After на время запуска и будит сохранённый релиз без сборки или импорта. POST и загрузки не повторяются автоматически. Production всегда включён. Одновременно работают не более четырёх nonproduction стендов; LRU охлаждает наименее недавно посещённый допустимый стенд. Все изменения state/power, start/stop и deployment используют общие locks и повторную проверку поколения/lease.

Основной state: /opt/gheilt/preview-state/<id>.json; provider отделяет SourceCraft от legacy GitHub. Power state: /opt/gheilt/preview-runtime/<id>.json. Чужой provider не получает право заменить существующий id. Runtime: user-unit atmanki-preview-runtime.service; Caddy получает только Unix socket, Docker socket ему не передаётся.

Релизные ветки, staging и blue-green production — следующий этап интеграции, их завершение этой главой не утверждается.

Проверка версии и отзыв сертификатов

/api/health сохраняет JSON { status: "ok" } и возвращает X-App-Release с SHA сборки. CI ждёт именно свой SHA, а не просто HTTP 200 предыдущего стенда. PR-образы собираются с временной CMS-фикстурой без production-секретов; после импорта на VPS webhook инвалидирует страницы, и сайт начинает читать собственную CMS и media. Privileged publisher загружается из текущего main, а не из файлов PR.

После удаления маршрутов всех пяти адресов PR сертификаты попадают в долговечную очередь. ACME использует ключ конкретного сертификата и проверяет, что все SAN относятся к этому PR. Недоступность Let’s Encrypt оставляет задание для повторного опроса. После подтверждённого отзыва удаляются только соответствующие leaf-файлы. Caddy перезапускается для очистки кеша сертификатов; это кратковременно прерывает проксирование, контейнеры production-приложений и их данные продолжают работать. Охлаждение не удаляет и не отзывает сертификаты.

Если CA не достигает HTTP/TLS порта VPS, применяется DNS-01 через ограниченный YC-провайдер Caddy. Образ proxy собирается в CI; отдельный ключ DNS доступен только Caddy. Изменение способа проверки домена не отменяет отзыв сертификатов закрытых PR.

Установка контроллера

Оператор доставляет проверенные tools из main в /opt/gheilt/preview-tools/<SHA>; PR-файлы на VPS не исполняются. Под deploy-пользователем запускается scripts/deploy/preview-runtime-install.sh; административно — scripts/deploy/sourcecraft-environments-install.sh /opt/gheilt/preview-tools/<SHA>. Он заменяет команду существующего sourcecraft-receive.service, сохраняя таймер опроса раз в две минуты. Authorized key остаётся в /opt/gheilt/sourcecraft/pull-key.json, control и готовность — в приватном /opt/gheilt/sourcecraft/state. После обновления tools оператор повторяет установку: автоматическое обновление исполняемых скриптов с веток PR запрещено.

Ошибка развёртывания одного стенда оставляет его для повторного опроса и не блокирует закрытие других PR. Обновление получает только четыре application images из YC Registry; установленные PostgreSQL и Garage не обновляются попутно и не требуют повторного доступа к Docker Hub. Если их ещё нет на хосте, первоначальная подготовка VPS должна установить эти образы. Контроллер сохраняет отдельную запись активности каждого PR ещё до появления образов. При первом наблюдении используется дата commit из API SourceCraft; повторная сборка не меняет её. При следующем изменении head записывается новое наблюдение, включая возврат A → B → A. Новый head продлевает lease один раз, даже если его проверки ещё не прошли; до успешной сборки продолжает обслуживаться предыдущая проверенная версия. Повторное наблюдение того же head, повтор CI и обращения по HTTP срок не меняют.

PR-проверки и публикация выполняются в разных tasks: SourceCraft запускает их на разных workers, публикация зависит от успешной check-task. От проверок не передаются workspace или environment. В чистой privileged task checkout удаляет Git credentials; скрипты PR на хосте не запускаются, Docker получает только фиктивный read-token. Доверенные publisher-файлы читаются из текущего main в свежем полном clone; если main успел измениться и его object ещё отсутствует, сборка завершается и требует свежего запуска. Автоматический PR использует конфигурацию из main. Manual --cfg-commit с feature допустим только для workflow checks, без выдачи IAM.

Контракты платформы: tasks и отдельные workers, триггеры из main.

В живой приёмке обнаружено: переменная, записанная в SOURCECRAFT_ENV, не сработала как динамическое условие if. Gate теперь пишет eligible в SOURCECRAFT_OUTPUT; публикация проверяет статус gate-кубика. Чужой/stale PR получает checks-only, собственный PR обязан пройти финальную проверку полного capsule и публичной готовности. Отсутствующий gate output (например, ошибка API) или пропущенная публикация завершают CI ошибкой.

Живая приёмка полного цикла

Для проверки создаётся отдельный собственный PR от текущего main. Его автоматический CI должен собрать четыре образа, опубликовать capsule и дождаться публичного /api/health с X-App-Release, равным head этого PR. Успешных проверок исходников недостаточно. Затем проверяются пять HTTPS-адресов, отдельные тома CMS и медиа, сохранение редакторской правки при следующем commit, охлаждение и пробуждение по HTTP. Закрытие PR должно удалить его ресурсы и обработать отзыв сертификатов всех пяти доменов.

На 6 октября 2026 года импорт test проверен на VPS: 200 опубликованных документов и 897 медиафайлов; шесть контейнеров прошли healthcheck. Публичная готовность пока не подтверждена: входящие ACME-проверки Let’s Encrypt нового IP заканчиваются таймаутом. Полный цикл PR и фактический отзыв сертификатов остаются предметом живой приёмки.