chore(release): одна платформа — один ассет - #155
Merged
Merged
Conversation
Каждый выпуск выкладывал одну и ту же сборку дважды: архивом и голым бинарником под другим именем. `v8-runner-darwin-arm64` — байт в байт тот же файл, что `v8-runner-macos-aarch64/v8-runner` внутри архива; скрипт это равенство сам же и проверял. Два имени на одну платформу, три из четырёх платформ с прямым бинарником и четвёртая без — и на вопрос «что из этого что» приходилось отвечать словами. Остаются архивы, по одному на платформу. Полезная нагрузка релиза падает с десяти ассетов до семи. Нативный аудит не потерян, а переделан. Он запускал именно прямой бинарник, доказывая, что опубликованное стартует; теперь бинарник достаётся из архива тем же кодом, который архив проверяет, — значит запускается ровно тот файл, чью сумму несёт манифест. Отдельной сверки сумм между формами больше не нужно: форма одна. Заодно аудит вырос с трёх платформ до четырёх — Intel-мак нативно не проверялся вовсе. Имена удалённых бинарников названы в теле описания релиза: тот, кто пойдёт их искать, должен узнать, что их нет и почему. Защита от повторения: `test_a_platform_is_published_in_one_form_only` падает и когда имя возвращается в workflow, и когда таблица возвращается в скрипт, и когда платформа появляется в аудите дважды. Обе стороны проверены пробой.
Удаляя шаг выгрузки прямого ассета, я срезал текст до следующего `- name:` — а он оказался уже внутри следующей работы. Вместе с шагом ушёл заголовок `publish`, её пять шагов оказались внутри матричной сборки, а `audit-native` и `audit-draft` стали ссылаться на работу, которой нет. GitHub такой файл не запускает вовсе: релиз было не выпустить. Оба набора тестов при этом оставались зелёными: они проверяли подстроки, а строка `needs: [publish, audit-native]` никуда не делась — делась работа. Поэтому вместе с возвратом заголовка появляется примета `test_release_workflow_is_a_workflow_github_will_start`: она разбирает YAML, сверяет состав работ, проверяет, что каждая зависимость разрешается и у каждой работы есть шаги, и что публикует только `publish` — у матричной сборки прав на запись нет, и съехавший в неё шаг публикации выполнялся бы по разу на платформу. Проба: снятый заголовок роняет её. Заодно по замечаниям ревьюера: - имя извлечённого бинарника называет сам скрипт, а не матрица аудита: то же соответствие «цель — имя файла» больше не живёт в двух местах, и `.exe` на Windows берётся из описания архива; - тест на извлечение проверяет не только байты, но и право на запуск — прежнюю проверку `chmod` унесло вместе с шагом, а без неё три из четырёх платформ ломались бы молча; - состав архива описан точно: внутри ещё README и `examples/`, а на Windows бинарник называется иначе; - в README убрана фраза про неизменные имена бинарников — рядом с абзацем о том, что бинарников больше нет, она противоречила сама себе.
`import yaml` уронил обе работы Happy Path: PyYAML на раннерах нет, а `pip install` в CI нет ни одного — питон в этом репозитории намеренно живёт на стандартной библиотеке, и реестр разбирает своё front matter сам по той же причине. Структура рабочего процесса теперь читается по отступам: имена работ, их зависимости и наличие шагов. Разбор сверен с PyYAML — состав работ и зависимости совпадают. Проба прежняя: снятый заголовок `publish` роняет примету.
После вливания гейта рабочих процессов разрешимость `needs` проверяется по всем файлам сразу. Здесь остаётся то, чего та проверка не видит: шаги публикации живут в своей работе, у матричной сборки прав на запись нет, и ни один из них туда не съехал — иначе они выполнялись бы по разу на платформу, затирая друг другу `dist`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Почему
Каждый выпуск выкладывал одну и ту же сборку дважды:
v8-runner-macos-aarch64.tar.gzv8-runner-darwin-arm64Скрипт это равенство сам же и проверял (
binary != (dist / direct_name).read_bytes()→ ошибка). То есть два имени на одну платформу, в двух разных традициях именования:macos/aarch64по триплету Rust иdarwin/arm64в стиле Go. Плюс прямые бинарники были у трёх платформ из четырёх, а у Intel-мака — нет, и со стороны это неотличимо от забытой сборки.Ровно этот вопрос и возник на v0.11.0: «а что из этого что?».
Что меняется
Остаются архивы, по одному на платформу. Релиз ужимается с 10 ассетов до 7, полезная нагрузка — с ~41 МБ до ~13. Аттестуемых артефактов становится 5 вместо 8.
Удалено:
unica_asset_nameиз матрицы, три шага workflow (Prepare/Attest/Upload direct Unica asset), таблицаDIRECT_ASSETS, подкомандаprepare-direct, перекрёстная сверка сумм между формами и рольdirect-binaryв манифесте.Что пришлось переделать, а не удалить
audit-nativeскачивал черновик релиза и запускал именно прямой бинарник на каждой ОС — это доказательство, что опубликованный файл действительно стартует. Просто выкинуть его значило бы потерять проверку.Вместо этого добавлена подкоманда
extract-binary: она достаёт бинарник из архива тем же кодом, который архив проверяет (_archive_binaryс канонизацией имён и сверкой вложенных LICENSE/FORK_NOTICE). Аудит запускает ровно тот файл, чью сумму несёт манифест, — и одинаково на всех трёх системах, безtarна одной и7zна другой.Побочный выигрыш: матрица аудита выросла с трёх платформ до четырёх. Intel-мак нативно не проверялся вообще — теперь проверяется.
Отдельная сверка сумм между формами больше не нужна по построению: форма одна.
Описание релиза
Тело релиза генерируется на каждый выпуск из литерала в
release.yml. Туда добавлена таблица «архив → система → процессор» и подсказка проuname -m, потому чтоaarch64противx86_64— ровно то место, где спотыкаются. Там же названы удалённые имена: тот, кто пойдёт искатьv8-runner-darwin-arm64, должен узнать, что его нет и почему, а не решить, что сборка сломалась.Защита от повторения
test_a_platform_is_published_in_one_form_onlyпадает, если имя возвращается в workflow, если таблица возвращается в скрипт или если платформа появляется в аудите дважды. Проверено пробой в обе стороны. Упоминание удалённых имён в теле описания примета разрешает намеренно.test_extract_binary_yields_exactly_the_archived_binaryзакрепляет то, что заменило перекрёстную сверку: извлечённый файл равен архивному для каждой из четырёх целей, а незнакомая цель — названный отказ.Проверки
python3 tests/release_governance.py— 18 passedpython3 tests/release_assets.py— 11 passed (CI гоняет оба файла,ci.yml:174-175)Rust не затронут.
Что надо знать ревьюеру
Версия не поднята. v0.11.0 уже выпущена с обоими наборами, менять её задним числом нельзя — изменение вступит в силу с 0.12.0.
Потребителя проверяли. У Unica есть
unica-bootstrapс зашитымreleases/download/этого репозитория и контрактным тестом, сопоставляющим платформу с именем прямого бинарника. По словам владельца, ни одна публичная Unica ничего из форка не забирает, поэтому согласование не требуется. Стоит знать, что у Unica уже естьextract_verified_tar_gzиapplication/gzipв допустимых формах доставки, то есть переезд на архив для неё — правка манифеста, а не новая машинерия.