Files
Никита Sonic 60264ff177 ci: страж тега на HEAD и записанный порядок выпуска (#41)
Первый заход v2.0.0-beta.8 собрался на всех трёх платформах и упал на
публикации с «Resource not accessible by integration». Сообщение про права
уводит не туда: права были ровно те же, что у beta.7 (Contents: write),
tauri-action тот же коммит, правил на теги нет.

Настоящая причина — положение тега. Токен Actions создаёт релиз только на
HEAD ветки по умолчанию. Тег поставили на chore(release), следом дописали
коммит в main, и к моменту вызова API тег отстал на один коммит.

Задача guard сверяет тег с HEAD и валится за секунды до сборок, вместо
загадочного 403 через восемь минут. Она ловит тег на старом коммите, но не
ловит гонку «запушили в main во время сборки» — то есть ровно тот случай,
который и произошёл. Поэтому главная защита не в ней, а в порядке действий,
записанном в docs/RELEASING.md: тег ставится последним, во время релиза в
main не пушим.

Логика стража прогнана на обеих ветках на реальных SHA этого репозитория.

Co-authored-by: by-sonic <171230345+by-sonic@users.noreply.github.com>
2026-08-10 22:29:54 +03:00

3.9 KiB

Как выпускать релиз

Порядок важен

Токен GitHub Actions создаёт релиз только на HEAD ветки по умолчанию. Если тег отстанет от main хотя бы на один коммит, публикация упадёт с ошибкой Resource not accessible by integration — сообщение про права, хотя права в порядке и дело в положении тега.

Отсюда единственное жёсткое правило: тег ставится последним, и пока идёт релиз, в main не пушим.

Шаги

  1. Влить в main всё, что должно попасть в релиз, и дождаться зелёного CI.

  2. Поднять версию в двух местахCargo.toml и tauri.conf.json. Они должны совпадать: имена файлов бандла берутся из tauri.conf.json.

  3. Закоммитить подъём версии и запушить в main.

  4. Убедиться, что больше ничего не уедет: git ls-remote origin refs/heads/main должен совпасть с локальным git rev-parse HEAD.

  5. Поставить аннотированный тег на этот же коммит и запушить его:

    git tag -a v2.0.0-beta.N -m "TGLock 2.0.0-beta.N"
    git push origin v2.0.0-beta.N
    
  6. Ничего не пушить в main, пока сборка не закончится. Правки README, документации, чего угодно — после публикации релиза.

Проверить, что выпустили

Зелёный workflow — это ещё не доказательство. В бетах 2 и 3 сборка была зелёной, а в приложение попадал headless-бинарь вместо графического. Поэтому проверяем содержимое, а не имя файла:

gh release download vX.Y.Z --repo by-sonic/tglock -p 'TGLock_universal.app.tar.gz' -D /tmp/check
tar -xzf /tmp/check/TGLock_universal.app.tar.gz -C /tmp/check
python scripts/verify_bundle_binary.py /tmp/check/TGLock.app/Contents/MacOS/tglock

Скрипт ищет внутри бинаря маркеры GUI (ipc.localhost, wry) и маркеры CLI (allow-direct, secret-file) и ругается, если в бандле оказался не тот.

Если публикация всё-таки упала с Resource not accessible by integration

Значит, тег разошёлся с main. Сверьте:

git ls-remote origin refs/heads/main 'refs/tags/vX.Y.Z^{}'

Если SHA разные — переставьте тег на HEAD и запушьте заново:

git tag -d vX.Y.Z
git push origin :refs/tags/vX.Y.Z
git tag -a vX.Y.Z <sha ветки main> -m "TGLock X.Y.Z"
git push origin vX.Y.Z

Перезапускать упавший workflow бесполезно: он возьмёт тот же отставший тег и упадёт снова.

Что защищает автоматически

Первым шагом релиза идёт задача guard: она сверяет тег с HEAD ветки по умолчанию и валится за секунды, не запуская сборки. Она ловит тег, поставленный на старый коммит.

Она не ловит гонку: если запушить в main уже после её прохождения, но до конца сборки, публикация упадёт. Ровно так утонул первый заход v2.0.0-beta.8. От этого защищает только правило из первого раздела.