Files
progcode/editorial/agent-rewrites/126.json
T
huncode 2d914b543f
Build and deploy / deploy (push) Failing after 15s
Publish rewritten technical article archive
2026-08-02 22:19:34 +03:00

8 lines
15 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"index": 126,
"slug": "editorial-2024-07-practice-release-engineering",
"title": "Релиз без догадок: как проверить связь между commit, artifact и rollback",
"excerpt": "Одинаковый tag не доказывает, что команда собирается доставить нужный код. Разбираем проверяемую цепочку от commit до rollout, отрицательный путь и границу rollback для данных.",
"contentHtml": "<p>После выкладки сервис отвечает кодом старой версии, хотя в заявке указан новый релиз. В карточке сборки, образе и rollout стоит один tag. Команда повторяет запуск, но не может быстро ответить на три вопроса: из какого commit собран artifact, какой digest отправили и совместима ли migration с данными. Цена ошибки растёт с каждой попыткой: увеличивается окно сбоя, меняется состояние базы, а точку возврата приходится восстанавливать по разным журналам.</p>\n<p>Одинаковая версия не связывает объекты сама по себе. Релиз готов к следующему действию только тогда, когда можно сравнить exact commit id, immutable digest, migration target и return point. Если одна связь неизвестна или ложна, проверка должна остановить выпуск. Новый retry не исправляет расхождение записей.</p>\n<h2>Механизм цепочки</h2>\n<p>У релиза есть несколько разных объектов. <code>commit</code> фиксирует исходный revision. <code>artifact</code> содержит собранное содержимое и digest. <code>migration</code> меняет схему или данные и должна назвать целевую версию и совместимость. <code>rollout</code> описывает намерение отправить конкретный digest. <code>return point</code> указывает версию и digest, к которым можно вернуться.</p>\n<p>Эти записи не заменяют друг друга. Artifact должен ссылаться на exact commit, а не только на имя ветки. Rollout должен содержать digest artifact, а не mutable tag. Migration должна отвечать на вопрос о совместимости. Return point должен быть известен до разрешения операции. Такая цепочка не доказывает, что deploy уже состоялся. Она делает расхождение видимым до действия.</p>\n<figure><img src=\"/assets/editorial/2024/release-engineering-2024-delivery-chain.svg\" alt=\"Схема сверки commit, artifact, migration, rollout и точки возврата перед релизом\" loading=\"lazy\" /><figcaption>Учебная схема показывает связи между записями релиза. Она не является журналом CI, registry, кластером или результатом production-выкладки.</figcaption></figure>\n<h2>Минимальный пример</h2>\n<p>Ниже приведён учебный пример с вымышленными значениями. Код не обращается к Git, registry, CI, Kubernetes API или базе данных. Он только сравнивает записи. Положительный результат означает согласованность этих записей, а не готовность реальной среды.</p>\n<pre><code>const release = { version: '2024.07.0' };\nconst commit = { id: 'commit-7f4a0c1' };\nconst artifact = {\n digest: 'sha256:release-070-a1',\n sourceCommitId: 'commit-7f4a0c1',\n};\nconst migration = {\n targetReleaseVersion: '2024.07.0',\n compatibleWith: '2024.06.3',\n};\nconst rollout = {\n requestedArtifactDigest: 'sha256:release-070-a1',\n migrationVersion: '2024.07.0',\n};\n\nconst checks = {\n source: artifact.sourceCommitId === commit.id,\n migration: migration.targetReleaseVersion === release.version,\n artifact: rollout.requestedArtifactDigest === artifact.digest,\n rollout: rollout.migrationVersion === migration.targetReleaseVersion,\n};\n\nconst readyForReview = Object.values(checks).every(Boolean);\nif (!readyForReview) throw new Error('stop: reconcile release records');</code></pre>\n<p>Каждая проверка отвечает только на один вопрос. Если заменить <code>sourceCommitId</code> на другой id, результат станет отрицательным. Если изменить digest в rollout, tag всё ещё будет выглядеть правильно, но содержимое уже не совпадёт. Отрицательный путь важнее зелёной строки: система не выбирает за инженера «примерно подходящую» запись.</p>\n<p>Название <code>readyForReview</code> намеренно не означает <code>readyForDeploy</code>. Код не проверяет подпись, права, конфигурацию среды, состояние базы, доступность сервиса или факт доставки. Он лишь открывает следующий этап проверки, если четыре связи согласованы.</p>\n<h2>Симптом → причина → проверка → действие</h2>\n<div class=\"table-scroll\"><table><caption>Диагностика расхождений до запуска</caption><thead><tr><th scope=\"col\">Симптом</th><th scope=\"col\">Причина</th><th scope=\"col\">Проверка</th><th scope=\"col\">Действие</th></tr></thead><tbody><tr><td>Tag совпадает, но artifact ссылается на другой commit.</td><td>Tag используют вместо точной связи с исходным revision.</td><td>Сравнить <code>artifact.sourceCommitId</code> и commit id.</td><td>Остановить выпуск. Исправить запись или пересобрать artifact после решения владельца.</td></tr><tr><td>Старый код не читает новую схему.</td><td>Rollback образа ошибочно считают rollback данных.</td><td>Проверить target migration, совместимость и обратную процедуру.</td><td>Вернуть только разрешённый artifact. Изменение данных рассмотреть отдельно.</td></tr><tr><td>Rollout прошёл с тем же tag, но другим digest.</td><td>Намерение ссылается на изменяемую метку.</td><td>Сравнить requested digest с digest artifact.</td><td>Не запускать rollout. Пересоздать запись после сверки.</td></tr><tr><td>После остановки предлагают повторить deploy.</td><td>Retry используют вместо объяснения mismatch.</td><td>Найти первую ложную связь и её источник.</td><td>Сначала исправить записи, затем повторить только проверки.</td></tr><tr><td>Точку возврата называют «предыдущим релизом».</td><td>У return point нет конкретного содержимого.</td><td>Проверить version и immutable digest.</td><td>Не обещать возврат, пока обе величины не записаны.</td></tr></tbody></table></div>\n<p>Таблица разделяет разные классы риска. Ошибка commit относится к происхождению artifact. Ошибка digest относится к содержимому, выбранному для rollout. Ошибка migration относится к совместимости данных и кода. Неопределённый return point относится к возможности безопасно назвать действие после сбоя. Одно поле <code>release=green</code> не заменяет эти проверки.</p>\n<h2>Порядок действий перед выпуском</h2>\n<ol><li><strong>Назовите границу проверки.</strong> Зафиксируйте release version, owner и источник каждой записи. Укажите, что сейчас выполняется сверка, а не deploy.</li><li><strong>Свяжите artifact с commit.</strong> Проверьте exact source commit и digest. Имя ветки, последний merge и короткий tag не заменяют идентификатор.</li><li><strong>Опишите migration отдельно.</strong> Назовите target version, совместимость с текущим contract и действие по данным. Не прячьте migration в комментарии к образу.</li><li><strong>Сверьте rollout.</strong> Он должен содержать immutable digest artifact и migration version. Любое расхождение переводит процесс в stop.</li><li><strong>Назовите return point.</strong> Запишите предыдущую версию и digest. Отдельно укажите, что произойдёт с данными и кто проверит этот путь.</li><li><strong>Повторите проверки после исправления.</strong> Передайте дальше только записи без ложных связей. Положительный результат открывает авторизованную проверку, но не выдаёт разрешение на deploy.</li></ol>\n<h2>Почему rollback не возвращает данные</h2>\n<p>Rollback Deployment возвращает прежнюю ревизию Pod template. Это помогает вернуть код и настройки, которые входят в этот template. Но такой rollback не отменяет произвольный SQL, удалённую запись, заполненное поле или изменение внешнего contract. Если migration уже изменила данные, старый artifact может не уметь с ними работать.</p>\n<p>Поэтому return point должен содержать две границы. Первая говорит, какой artifact можно запустить. Вторая говорит, что разрешено делать с данными. Возможны обратная migration, совместимый промежуточный код, восстановление из резервной копии или запрет автоматического возврата. Пока выбранный путь не проверен, честная формулировка звучит так: «возврат artifact определён; откат данных не доказан».</p>\n<p>Та же граница действует для provenance и attestation. Provenance описывает происхождение сборки. Attestation может подтверждать утверждение об этом происхождении. Ни одно из них само по себе не доказывает совместимость migration, approval rollout или здоровье сервиса. Эти вопросы требуют собственных источников и проверок.</p>\n<h2>Ограничения и отрицательный путь</h2>\n<p>Схема ловит расхождения между названными записями. Она не доказывает правдивость каждого значения. Она не проверяет историю Git, содержимое образа, подпись, policy CI, права на кластер, runtime configuration, состояние базы, трафик, метрики или факт доставки.</p>\n<p>Если commit неизвестен, digest отсутствует, migration не содержит compatibility statement или return point не назван, результат должен быть отрицательным. Не подставляйте «последний main». Не ищите образ по tag. Не объявляйте rollback данных по факту возврата Pod template. Остановитесь на первой неизвестной границе и назначьте источник, который может её подтвердить.</p>\n<h2>Проверяемый критерий готовности</h2>\n<p>Запись готова к передаче на авторизованную проверку, если второй инженер без устных пояснений может показать exact commit id, artifact digest, связь artifact с commit, migration target и compatibility, rollout digest, migration version и return point. Для каждой строки есть источник, владелец и действие при mismatch. Проверка даёт либо все утверждения <code>true</code>, либо конкретный stop с названием ложной связи.</p>\n<p>В учебном примере все значения вымышлены и не описывают production-результат. В реальном выпуске критерий нужно применять к доступным и разрешённым записям. Если одна строка не имеет источника или действия, выпуск не готов: сначала уточните contract, затем повторите сверку.</p>\n<h2>Проверяемые источники</h2>\n<ul><li><a href=\"https://slsa.dev/spec/v1.0/terminology\" target=\"_blank\" rel=\"noopener noreferrer\">SLSA v1.0: Terminology</a> — официально описывает provenance и два способа её проверки.</li><li><a href=\"https://docs.github.com/en/actions/how-tos/secure-your-work/use-artifact-attestations/use-artifact-attestations\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub Docs: Using artifact attestations to establish provenance for builds</a> — описывает создание и проверку attestation для binary и container image.</li><li><a href=\"https://kubernetes.io/docs/concepts/workloads/controllers/deployment/\" target=\"_blank\" rel=\"noopener noreferrer\">Kubernetes Docs: Deployments</a> — описывает ревизии Deployment, rollout history и rollback Pod template.</li></ul>"
}