15 KiB
План первого релиза в GitHub
Цель: в GitHub Releases появляется тег с прикреплёнными бинарниками —
firmware_test(HAB-образ) иservice-tui(standalone-бандлы под macOS и Windows). Этот документ — практический чек-лист «как довести до кнопки Publish», а не повторение инженерных фазRELEASE_ROADMAP.md.
Как связаны два артефакта
firmware_test (C, i.MX RT1052, версия 0.1.2 из
firmware/test/CMakeLists.txt) и service-tui (Python/Textual, версия
0.2.0 из tools/production/pyproject.toml) — независимо версионируемые
проекты, но релиз одного без другого бесполезен сервисному инженеру:
service-tui — это инструмент, которым он прошивает плату диагностической
прошивкой, и HAB-образ firmware_test кладётся внутрь бандла TUI как
firmware/<Type>/firmware_test_hab.bin (см. just host::package-tui,
tools/production/docs/DEV_ARCH.md §14). Поэтому релиз собирается как один
комплект, даже если версии независимые.
Известное ограничение (задокументировано в README.md/DEV_ARCH.md):
Release-сборка firmware_test нестабильна (проблема с FCB/clock), поэтому
в бандл TUI кладётся Debug-образ (FIRMWARE_BUILD_TYPE=Debug). В релиз
GitHub имеет смысл положить оба HAB-образа отдельными assets (Debug — как
основной для TUI, Release — с пометкой «experimental», для тех, кто прошивает
через tools/host/flash_usb.py вручную), либо только Debug — см. открытый
вопрос в шаге 1.5.
Текущее состояние (снимок на момент написания плана)
| Область | Состояние |
|---|---|
firmware_test |
Собирается, HAB-образ генерируется (just build::hab-firmware-test-{debug,release}), Release нестабилен |
service-tui |
v0.2.0, PyInstaller onedir, alpha-бандлы уже вручную собраны и прогнаны на живом железе macOS+Windows (коммиты c694258/bfe4dd6) |
service_tui.spec |
Устарел относительно того, чем реально собраны протестированные alpha-бандлы — не содержит datas для spsdk, dcd/*.bin, pyproject.toml (задокументировано в DEV_ARCH.md §14 и CHANGELOG.md「Известные ограничения」) |
tools/production/dist/service-tui-v0.2.0-{macos,windows}/ |
Закоммичены в git (906 файлов, ~96 МБ суммарно) и устарели относительно HEAD — собраны до коммитов 2dbe3e6/22c4077/31e3237 (фиксы моков тестов, рефакторинг докстрингов) |
CI (.github/workflows/ci.yml) |
Только build+test в devcontainer на ubuntu-latest; не собирает service-tui, нет macOS/Windows раннеров, нет release-пайплайна, нет тегов в репозитории |
just/ci.just |
Есть рецепт release (→ just build::hab-all-release) — только firmware, ничего про упаковку TUI или публикацию на GitHub |
| Ветки | feature-tui-monolith на 15 коммитов впереди dev, ещё не смёржена; в репозитории также есть main — политика, какая ветка режет релизы, явно не зафиксирована |
Шаг 1 — Закрыть блокирующие долги перед тегом
Без этого CI-сборка (шаг 3) не будет соответствовать тому, что уже провалидировано на железе, — а «релиз, который не воспроизводим из исходников» хуже отсутствия релиза.
- Актуализировать
tools/production/service_tui.spec— добавитьcollect_data_files("spsdk")(+SPSDK_DATA_FOLDERесли понадобится),collect_dynamic_libs("libusbsio"),datasдляtools/host/dcd/{dcd.bin,w25q128_fdcb.bin,w25q512_fdcb.bin,ivt_flashloader.bin}иpyproject.toml. Ориентир — реальное содержимое уже собранных alpha-бандлов вdist/(их можно инспектировать перед удалением из git, см. следующий пункт). - Убрать
tools/production/dist/из git:git rm -r --cached tools/production/dist+ добавитьtools/production/dist/в.gitignore. Собранные бандлы — это build-артефакты, их место в GitHub Release assets или CI-артефактах, не в истории репозитория. - (Дёшево, но не блокирует) Убрать мёртвую зависимость
pyusbизtools/production/pyproject.toml— детект давно переведён наspsdk/serial.tools.list_ports(Р7), ни один модульapp/её не импортирует. - Пересобрать бандлы локально с исправленным spec из актуального HEAD
(
just host::package-tuiна macOS и на Windows) и повторить хотя бы дымовой прогон чек-листа Гейта 5 изRELEASE_ROADMAP.md(детект SDP → прошивкаfirmware_test→ диагностика → выход). Полный деструктивный чек-лист (обрыв USB и т.п.) уже пройден на предыдущей сборке — здесь цель убедиться, что исправленный spec не сломал состав бандла, а не повторять всё с нуля. - Открытый вопрос: класть ли в релиз Release-сборку
firmware_testвообще (сейчас нестабильна) — по умолчанию план предполагает только Debug-образ как основной asset, Release не публикуется до починки FCB/clock-проблемы. Требует подтверждения.
Шаг 2 — Версия и тег
- Схема тега —
firmware_test(0.1.2) иservice-tui(0.2.0) версионируются независимо. Предлагается: тег видаvX.Y.Z= версияservice-tui(это главный продукт релиза для сервисного инженера), версияfirmware_testуказывается в описании релиза отдельной строкой. Альтернатива — раздельные теги (tui-v0.2.0+firmware-v0.1.2), если в будущем оба проекта должны релизиться независимо друг от друга. Требует подтверждения, план ниже считает первый вариант. - Ветка релиза — в репозитории есть и
dev, иmain, при этомmainвgit logне встречается в историиfeature-tui-monolith/dev(нужно свериться отдельно, еслиmainуже используется под что-то другое). Рекомендация: смёржитьfeature-tui-monolith → dev, затемdev → main, тег ставить наmain— такmainостаётся точкой, соответствующей опубликованным релизам, аdev— интеграционной веткой. Требует подтверждения, если у проекта другая договорённость проmain. CHANGELOG.md— закрыть секцию[Не выпущено] — service-tui: ...→[YYYY-MM-DD] — v0.2.0, вычеркнуть из «Известные ограничения» то, что закрывается шагом 1 (spec-расхождение,pyusb).
Шаг 3 — CI: собрать релизные бинарники автоматически
Текущий .github/workflows/ci.yml собирает только firmware_test на
ubuntu-latest внутри devcontainer — этого недостаточно для
кросс-платформенной упаковки service-tui. Нужен отдельный workflow,
не смешанный с обычным PR-циклом (см. just/ci_workflow.md, «Шаг 3 —
выделить release workflow»).
Новый .github/workflows/release.yml, триггер — тег v* (плюс
workflow_dispatch для тестового прогона без публикации):
| Job | Раннер | Что делает |
|---|---|---|
firmware |
ubuntu-latest (тот же devcontainer-подход, что в ci.yml) |
just ci::release → hab-all-release (по факту нужен только firmware_test, Debug+Release); выгрузить firmware_test_hab.bin (оба типа) как артефакт |
service-tui-macos |
macos-latest |
скачать firmware-артефакт из job firmware; uv sync в tools/production; just host::package-tui; заархивировать dist/service-tui-vX.Y.Z-macos/ |
service-tui-windows |
windows-latest |
то же самое, PowerShell-совместимые команды (just/uv доступны на Windows) |
publish-release |
ubuntu-latest, needs: [firmware, service-tui-macos, service-tui-windows] |
скачать все артефакты, создать GitHub Release через gh release create / softprops/action-gh-release@v2, прикрепить firmware_test_hab.bin (Debug, + Release с пометкой experimental, если решение по шагу 1.5 — «класть оба»), service-tui-vX.Y.Z-macos.zip, service-tui-vX.Y.Z-windows.zip |
Важные нюансы:
- Firmware для бандла TUI собирается один раз в job
firmwareи передаётся в macOS/Windows job'ы артефактом — пересобирать ARM-прошивку на каждом раннере отдельно избыточно (и на macOS/Windows раннерах нет подготовленного devcontainer/toolchain). - Аппаратные гейты (детект SDP на живой плате, деструктивные сценарии
обрыва USB) CI выполнить не может — GitHub-hosted раннеры не видят
реальное USB-устройство. Это ручной шаг, который уже пройден один раз
вручную (коммиты «MacOS tested»/«Windows tested») и должен повторяться
вручную перед каждым релизом, пока не поднят self-hosted HIL-раннер
(см.
just/ci_workflow.md, «Шаг 5»). План релиза это не блокирует, но release notes должны явно фиксировать, что сборка прошла ручную проверку на железе, а не только CI.
Шаг 4 — Ручные шаги перед Publish
- Скачать
service-tui-vX.Y.Z-{macos,windows}.zip, собранные именно CI (не локальную сборку из шага 1.4) — прогнать сокращённый чек-лист Гейта 5: детект SDP → прошивкаfirmware_test→ диагностика на обеих ОС. Цель — убедиться, что CI-сборка не разошлась с уже провалидированной локальной. - Обновить
tools/production/README.md/корневойREADME.md— ссылка на релиз/инструкция «откуда скачать сервисному инженеру».
Шаг 5 — Публикация
git tag vX.Y.Z
git push origin vX.Y.Z
— триггерит release.yml. Проверить, что все 3 asset'а прикрепились и
release notes корректны (описание можно сгенерировать из секции
CHANGELOG.md за этот релиз + gh release create --generate-notes как
дополнение). Если Гейт 6 (RELEASE_ROADMAP.md) закрыт не полностью
(например, POST-1 сознательно отложен — это нормально, он и заявлен как
пост-релизный) — релиз всё равно можно публиковать как обычный, а не
pre-release, POST-1 не блокирует v1 по замыслу roadmap.
Шаг 6 — Развитие CI после первого релиза (не блокирует, но логично заложить сразу)
Эти пункты уже зафиксированы в just/ci_workflow.md («Рекомендуемые
следующие шаги»), возвращаемся сюда после первого релиза:
lintjob (just ci::lintсейчас заглушка) —clang-format --dry-run --Werror+clang-tidy.- Coverage (
just ci::_coverageуже есть, но не подключён в workflow). - Публикация devcontainer image в GHCR — сократит время
firmwarejob вrelease.ymlи обычномci.yml(сейчас образ пересобирается в каждой job, даже с layer-кэшем). - Self-hosted HIL lane — единственный способ когда-нибудь автоматизировать то, что сейчас в шаге 4 делается руками.
Сводная последовательность
Шаг 1 (spec + dist из git + пересборка)
│
Шаг 2 (тег/ветка/CHANGELOG — решения по открытым вопросам)
│
Шаг 3 (release.yml: firmware → macOS/Windows package → publish)
│
Шаг 4 (ручная проверка CI-бинарников на железе)
│
Шаг 5 (git tag → publish)
│
Шаг 6 (lint/coverage/GHCR/HIL — после релиза, не блокирует)
Открытые вопросы, требующие решения пользователя
| # | Вопрос | Где всплывает |
|---|---|---|
| 1 | Класть ли Release-сборку firmware_test в релиз (сейчас нестабильна) |
Шаг 1.5 |
| 2 | Схема тега — один vX.Y.Z (=версия TUI) или раздельные теги firmware/TUI |
Шаг 2.1 |
| 3 | Тег ставится на main (после dev → main) или сразу на dev/на самой feature-ветке |
Шаг 2.2 |