DarkRiDDeR10 мин

Инженерия релиза: цепочка доказательств между commit и deploy

РелизыDevOps

В заявке на выпуск написано 2024.07.0. Рядом лежат четыре похожих подписи: commit synthetic-commit-7f4a0c1, artifact с digest sha256:synthetic-2024-07-0-a1, migration plan 2024.07.0 и rollout card с тем же номером. Это конкретная учебная ситуация, а не журнал поставки: все записи заранее вшиты в fixture. Цена понятна и без реальной среды: если хотя бы одна подпись относится к другой версии, команда может обсуждать ошибку не того кода, ожидать не ту схему и готовить возврат к несуществующей точке.

Чаще всего симптом выглядит безобидно: на каждой стадии есть знакомый tag, но нельзя показать одну непрерывную связь от commit до запрошенного artifact. Причина — версия используется как украшение, а не как ключ сравнения; migration и rollout появляются отдельными карточками. Проверка короткая: сравнить parent-ссылку artifact на commit, target migration, digest в rollout и return point. Действие ещё короче: при первом несовпадении остановить review и исправить запись до любого реального deploy. Так рассуждают о контракте релиза, не о любимой CI-системе.

Что именно должно совпасть

Минимальная цепочка не требует огромной платформы. Достаточно назвать четыре объекта и запретить им молча расходиться. Commit фиксирует исходный revision. Artifact хранит собственную версию, digest и declared source commit. Migration plan хранит target release и отдельный compatibility statement. Rollout card повторяет версию, digest и migration version, но остаётся намерением: она ещё не доказывает, что кто-либо получил доступ к среде или что операция была выполнена. Отдельно хранится rollback candidate с прошлой версией и digest, но без обещания вернуть данные назад.

Слово «доказательство» здесь практическое. Оно не означает криптографическое свойство любого поля и не подменяет attestation. Оно означает, что следующий человек может сравнить одну пару значений с другой и получить конкретное «совпало» либо «стоп». GitHub в июне 2024 уже описывал artifact attestations как отдельный объект, который создаётся для build artifact и проверяется позже. Это полезное разделение ролей: label artifact, statement о происхождении и approval на deploy не должны сливаться в одну строку release=green.

Четыре versioned synthetic объекта: commit, artifact, migration plan и rollout card. Стрелки требуют точного совпадения commit id, версии, digest и migration version; отдельная нижняя карточка показывает rollback draft без реального deploy и без обещания отменить данные.
Цепочка показывает только учебный contract fixed records в памяти. Это не pipeline, artifact registry, трасса CI, облачный экран или результат rollout.

Рабочая таблица связей

Какая связь нужна до human review
ПереходНужное равенствоЧто проверитьЧто делать при расхождении
commit → artifactartifact.sourceCommitId = commit.idНе только tag, но exact declared commit id.Остановить: artifact нельзя связать с исходным revision.
artifact → migrationmigration.targetReleaseVersion = releaseVersionВерсия и declared compatibility относятся к одному release.Остановить: не угадывать, для какого кода написана migration.
artifact → rollout cardrequestedArtifactDigest = artifact.digestCard называет именно записанный immutable digest.Остановить: версия может совпасть, а содержимое — нет.
release → rollback draftreturn version + return digest известныЕсть ли точка возврата и граница для migration.Не обещать data undo; вынести его в отдельный review.

Таблица полезна тем, что не требует доверять одному центральному полю. Например, tag 2024.07.0 может стоять и у source, и у artifact, но source commit всё равно обязан совпасть. Аналогично, rollout card не становится надёжной от того, что её version выглядит красиво: digest должен быть тем же digest, который зафиксирован рядом с artifact. Каждая строка даёт проверяемый ответ и отдельный stop condition. Такой stop condition дешевле позднего расследования, потому что меняет только запись, а не среду.

Минимальная fixture вместо ложной автоматизации

Ниже — исполнимая fixture sidecar-пакета. В ней четыре versioned synthetic JS objects заранее записаны в модуле. Функция не принимает URL, имя registry, путь к manifest, credentials, журнал CI или target deploy. Она возвращает teaching report: aligned case ведёт лишь к human deploy review, а mismatch case — к stop. Команда --verify-fixture проверяет invariants этих объектов, но не создаёт artifact, не вызывает runner и не читает ни одного внешнего состояния.

import { createFixedSyntheticReleaseInput, inspectSyntheticReleaseEvidence } from './upgrade-2024-07.mjs';

const report = inspectSyntheticReleaseEvidence(createFixedSyntheticReleaseInput('fixed-aligned-release'));

if (report.decision !== 'continue-to-human-deploy-review') {
  throw new Error('fixed synthetic chain is not aligned');
}

console.log(report.record.commit.id);
console.log(report.record.artifact.digest);
console.log(report.record.rollout.state); // proposed-not-executed

// The fixture reads only embedded objects. It is not CI, a registry, or a rollout.

node web/scripts/upgrade-2024-07.mjs --verify-fixture

Именно ограничение input делает пример проверяемым. Если передать похожее поле ciLog или deployTarget, fixture отвергнет input как extra field. Это не защита настоящей системы и не проверка CI. Это защита смысла статьи: учебный объект не должен незаметно начать потреблять реальное evidence, а затем выдавать его за подтверждённый rollout. Даже положительный результат fixture означает лишь равенство fixed records, которые автор уже поместил в память.

Маршрут перед настоящим выпуском

  1. Назовите release version и owner проверки. Version без ответственного за сравнение остаётся label. Owner не обязан делать deploy, но обязан знать, какая запись считается исходной.
  2. Свяжите artifact с commit exact идентификатором. Не заменяйте id названием ветки, последним merge или человеческим описанием. Сначала проверьте declared link, затем решайте, достаточно ли он надёжен для вашей среды.
  3. Опишите migration отдельно. Укажите target version, compatibility с предыдущей версией и то, что data effect требует отдельного review. Не прячьте это в комментарии к artifact.
  4. Соберите rollout intent без действия. Card должна повторить release, digest и migration version. Её задача — сделать будущую проверку однозначной, не запустить операцию.
  5. Сравните четыре перехода и остановитесь на первом mismatch. Не лечите расхождение новой попыткой. Исправьте record, повторите сравнение и только затем передавайте вопрос авторизованному reviewer.
  6. Запишите return point до approval. Версия и digest для возврата нужны до реального deploy; для migration отдельно зафиксируйте, что code rollback не означает data rollback.

Почему migration нельзя приклеить в самом конце

Migration обычно ломает простую картину «вернули прошлый artifact — всё вернулось». В Kubernetes Deployment revision связана с Pod template: rollback возвращает прежний template, а не отменяет любые изменения за его пределами. Это не недостаток Kubernetes; это важная граница, которую стоит назвать в любом delivery design. Если migration уже изменила данные или contract, прежний code может потребовать compatibility window, отдельную reverse procedure либо сознательный отказ от автоматического возврата. Поэтому migration version и её declared compatibility — часть evidence chain, а не последний пункт runbook.

Практика не требует однажды выбрать универсальный способ миграций. Она требует отделить два вопроса. Первый: какая версия artifact допустима для target data contract? Второй: какое действие по данным разрешено и как проверяется его обратимость? Пока второй вопрос не описан, rollback draft должен говорить ровно правду: «return artifact указан; data undo не обещан». Такая формулировка неприятнее зелёной галочки, зато она не заставляет инженера угадывать после первого симптома.

Ограничения и следующий проверяемый шаг

Эта схема не проверяет реальный Git history, build provenance, signature, runtime configuration, secret, доступ к cluster, состояние database, качество monitoring или факт доставки. SLSA v1.0 даёт vocabulary для provenance и verification, но не отменяет local policy и не превращает произвольный JSON в доказательство. GitHub Artifact Attestations и Kubernetes Deployment documentation описывают конкретные возможности своих систем; из них нельзя вывести, что каждая организация должна применять идентичные поля или один и тот же rollback.

Следующий проверяемый шаг — взять один разрешённый к анализу release record и, не выполняя deploy, заполнить ту же таблицу четырьмя значениями: exact commit id, artifact digest, migration target/compatibility и return version/digest. Затем второй reviewer должен найти либо подтвердить одно равенство в каждой строке. Если у строки нет owner-а, источника или stop action, не расширяйте pipeline: сначала исправьте contract. Это маленький тест, который оставляет понятный результат независимо от выбранного CI/CD инструмента.

Историческая граница июля 2024

Материал использует только первичные официальные источники, реально доступные к июлю 2024: SLSA v1.0 был объявлен stable в апреле 2023, GitHub объявил Artifact Attestations generally available 25 июня 2024, а Kubernetes release-1.30 documentation уже содержала versioned Deployment guidance. Технические факты в тексте намеренно узкие: provenance нужно проверять относительно ожиданий, attestation не равна approval, а Deployment rollback не равен откату данных. Все ids, digest, versions и outcomes выше — fixed synthetic teaching records, не наблюдения о чьей-либо доставке.

Проверяемые источники

  • GitHub Changelog: Artifact Attestations is generally available, 25 июня 2024 — Первичный датированный источник GitHub: в GitHub Actions можно создать attestation для собранного artifact и затем проверить его. Здесь это основание различать artifact и проверяемое утверждение о нём; источник не является policy, журналом или доказательством чужого выпуска.
  • SLSA: SLSA v1.0 is now final!, 19 апреля 2023 — Первичная публикация о первом stable SLSA v1.0. Из неё взята узкая идея versioned provenance и проверки ожиданий, а не claim, что любой набор полей делает конкретную сборку безопасной или готовой к deploy.
  • Kubernetes documentation: Deployments, snapshot 14.03.2024 — Первичный неизменяемый снимок ветки release-1.30, доступный до июля 2024: revision Deployment связана с Pod template, а rollback возвращает прежнюю revision шаблона. Это не отменяет data migration и не переносится автоматически на другой deploy-инструмент.