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

Исторический документ: результаты относятся к указанной в тексте дате.

История проекта

Приёмка релизных веток и blue-green

Оглавление · Релизный контракт

Состояние на 7 октября 2026 года: первый native stable Release применён на production через SourceCraft; GitHub выключен и архивирован.

Код и проверки

PR №16 содержит staging, нативную release authority, compatibility guard CMS, private backup с restore PostgreSQL/Garage/uploads, транзакцию blue-green четырёх приложений, ownership и охлаждение точной staging generation. Новый учебник из main сохранён.

На head 8661ebe6b144e9125b9ed98edb276951861de377:

  • CI №98 успешно выполнил проверки, опубликовал четыре образа PR и capsule, затем подтвердил публичный web health с точным SHA.
  • CI №99 успешно проверил тот же commit с конфигурацией из самого commit, workflow checks без IAM для публикации.
  • Независимое ревью выявило два Important: неучтённые startup helpers CMS и отсутствие восстановления local uploads. Оба исправлены с RED→GREEN. Исправлены также Labels: null и диапазон changelog для разошедшихся PR-веток.
  • Реальный changelog CLI сохраняет ручной текст description; native API авторизует текущего пользователя по ID автора PR, а UI-ссылки используют /pr/N.

TTL и повторное создание PR-стенда

После 12 часов без новых коммитов controller удалил PR №16, хотя PR оставался открытым. Очередь отзыва сертификатов при проверке пуста. Обновление этой главы даёт новый commit; его полный стенд проверяется отдельно перед merge.

Первый native релиз

release/0.1 и immutable release-base/0.1 созданы на 619aadd1c1314057c122c866541f3a1f5662e544. Main CI №181 и release CI №183 успешны; четыре staging images опубликованы в YC Registry. Полный staging содержит 200 опубликованных записей и 897 файлов из нашей production CMS/Garage. Web/content-health, CMS, Storybook, docs и публичный media smoke прошли; staging-ready.json связан с точными SHA/digest/generation.

Native stable v0.1.0 опубликован 2026-10-07T08:23:04Z, id 01a11575-7b65-70de-8c93-c812d364125a, hash совпадает со staging. Control plane №193 успешно включил событие выпуска. Production transaction завершилась: active color — blue, commit — 619aadd1c1314057c122c866541f3a1f5662e544. Все четыре digest совпадают со staging receipt; четыре новых контейнера healthy. Публичные web health/content-health, CMS, Storybook и docs отвечают 200/204, web X-App-Release совпадает с commit.

Private backup atmanki-restore-1ce1cf6740074f4385d371dda560fc8a имеет verified=true: восстановлены PostgreSQL, Garage и local uploads в собственные scratch resources. Исходные PostgreSQL/Garage container IDs сохранились; редакторские данные не заменены staging-данными. Прежние четыре приложения остановлены; совпавшая staging generation имеет power=cold. Незавершённых production/backup intent нет. Trusted controller установлен из main 10ccf924.

На VPS найдены и исправлены два интеграционных сбоя: exporter требовал http://s3:3902, а source helper передавал имя контейнера; HTTP gate принимал query string за часть environment id. Исправления в PR №17/18 влиты и установлены на VPS. Runtime tests — 25/25; source helper — 2/2; docs — 8/8. Первый draft с target_branch не смог публиковаться поверх заранее закреплённого тега. Пересоздан только собственный неопубликованный draft, tag не удалялся и не перемещался. Исправленный CLI создаёт draft для существующего immutable tag без target_branch; changelog tests — 11/11.

Границы живой проверки

Второй выпуск для смены blue→green и live fault injection не выполнялись по решению владельца. Локальные recovery/CMS-contract fixtures не заменяют эти наблюдения. На момент первого выпуска source links учебника ещё относились к историческому GitHub-зеркалу. Последующее исправление переводит их на штатный SourceCraft browse URL. Source maps/Umami build parameters прежнего CI в SourceCraft не перенесены; это явно отмечено в настройках.

Упрощение ввода по решению владельца

7 октября GitHub Actions отключены в настройках repository (enabled=false); активных и ожидающих jobs при отключении не было. GitHub workflow удалены из рабочего кода. Repository архивирован; старые три CI secrets и четыре variables удалены. В environments production, pr-1, pr-3 secrets/variables отсутствуют. Оба remote указывают на SourceCraft. Сборка Caddy отделена от обычного application CI: manual workflow запускается при изменении proxy. Сохраняем один CI проход и штатный backup внутри promotion; второй приёмочный patch и дополнительные crash rehearsals не являются условием ввода.

PR changelog учитывает точные native source/target SHA, даже если SourceCraft возвращает target ancestor вместо нынешнего main tip. Проверки owner/repository, source HEAD и гонки description сохраняются. Changelog собственного PR №18 после исправления записан с сохранением ручного текста.

Решения реализации

Ниже сохранён полный журнал решений этапа. Исторические решения про coexistence с GitHub и дополнительную приёмку заменены последним указанием владельца: GitHub отключён, выпуск выполняется без повторных репетиций. Отложенных Minor-находок ревью нет; все четыре находки исправлены.

Ruling: headings use Task N for ledger tools instead of Этап N — helper requires English headings — cost: cosmetic plan edit only.
Ruling: shared fixture builder accepts media_url explicitly — staging/PR media origins differ — cost if wrong: rebuild incorrect web origin.
Ruling: web addresses its CMS by unique gheilt-COLOR-cms, not shared prod-cms alias — both Compose projects attach backend and automatic service aliases collide — cost if wrong: web reads another color's CMS.
Ruling: production authority guard is implemented with transaction in Task 5 before controller wiring in Task 6 — cannot run candidate without fresh guard — cost: code ownership moved earlier only.
Ruling: after verified backup retarget only known internal Strapi webhook URLs to stable public production endpoint (dry-run first); preserve headers/events/manual external URLs — legacy web is stopped after promotion and bare web route would break ISR — cost if wrong: webhook delivery requires restoring configuration from backup; editorial data unchanged.
Ruling: live current GHCR CMS/web images lack OCI revision labels (read-only VPS inspection confirmed). Explicit legacy extraction accepts missing revision only for current GHCR previous side with no requested SHA, still verifies exact actual digest/runtime files; new candidates require exact SHA label — avoids denying bootstrap on historical metadata — cost if wrong: old build provenance remains limited to active digest/files, reported rather than invented.
Ruling: ownership gate covers GitHub Storybook/docs deployment too, not only deploy.yaml — all four apps participate in blue-green — cost: two additional workflow files. Live VPS_READY=false blocks historical YAML; PRODUCTION_OWNER new guard protects updated YAML. Checks retained.
Ruling: atomic release branch creation also records immutable release-base/X.Y tag — generate-notes previous_tag requires a tag, and first-release range must persist across worktrees — cost: one extra Git tag per release line.
Ruling: notes compare against previous stable release in the same X.Y line — unrelated release lines must not define patch range — cost: notes do not include other lines.
Ruling: register new flat documentation chapters in navigation; source link rewrite deferred until current textbook integration establishes native UI routes — cost: navigation adjustment only.
Ruling: SourceCraft main now contains merged textbook (!15); integrate its published layout, relocate own chapters into devops/history and retain existing navigation/link tests — cost: merge resolution and paths differ from original plan.
Ruling: conservative CMS guard hashes all source/compiled application files; only canonical strapi start with no npm startup hooks and fixed image launcher supported; relative runtime paths outside selected app directories rejected — stops transitive bootstrap execution from unguarded scripts — cost: backend code changes may require separate compatibility review. Maintenance CLI npm scripts remain outside startup contract; npm ci provenance+lock+installed version are not an arbitrary node_modules integrity proof.
Ruling: private backup uploads drill compares bytes, entry type, mode, uid/gid, links on own scratch volume with journal cleanup — hash of archive alone did not prove recovery — cost: third scratch volume during backup.
Ruling: user explicitly simplified rollout; retain data backup inside promotion, drop redundant rehearsal/second release/manual config checks — cost: less live fault-injection evidence, reported clearly.
Ruling: SourceCraft native Release with target_branch creates tag at publish and rejects existing tag; pin Git ref before draft POST without target_branch, require returned hash exact — confirmed by real draft recreation/publication, immutable tag preserved — cost: orphaned pinned tag after API failure needs explicit existing-tag draft recovery.
Ruling: changelog accepts own PR target SHA that is not current main tip; SourceCraft PR18 returned merge ancestor39c7 while main374 was a merge commit — author/repository/source HEAD and race checks retained, deployment authority unchanged — cost: notes use exact native source/target range rather than pretending target.sha always equals branch tip.
Ruling: GitHub repository archived after Actions disabled and all repository CI secrets/variables removed; environment secrets/variables empty — only historical source-link mirror retained — cost: subsequent code writes must use SourceCraft.

Сверка локального main

Старый origin/main оставлял локальный main «ahead 8». Семь коммитов уже входят в SourceCraft history; единственный отсутствовавший — merge 4208e199. merge-tree подтвердил, что объединение с ним даёт ровно существующий tree SourceCraft main. Интеграционный PR сохраняет этот merge в ancestry без повторного применения патчей и без изменения кода другого агента. Это позволяет затем обновить основной checkout fast-forward вместо reset или удаления истории.