chore(release): prepare 2.0.0-beta.15 with verified draft publication

This commit is contained in:
babin
2026-09-19 16:04:27 +03:00
parent 9dc2db1d89
commit 88b6870e91
8 changed files with 83 additions and 54 deletions
+4 -1
View File
@@ -111,7 +111,8 @@ jobs:
- **Сервер, контейнер, машина без монитора** — `tglock-cli-*`: то же самое, но без графического интерфейса
Если Windows ругается на файл — [почему так и что с этим делать](https://github.com/by-sonic/tglock#-антивирус-ругается-smartscreen-предупреждает-virustotal-показывает-детекты).
releaseDraft: false
# Publish only after every platform, CLI and exact-commit APK is verified.
releaseDraft: true
prerelease: false
args: ${{ matrix.args }}
@@ -162,6 +163,7 @@ jobs:
- uses: softprops/action-gh-release@v2
with:
tag_name: ${{ github.ref_name }}
draft: true
files: arm64-cli/*
cli:
@@ -229,5 +231,6 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref_name }}
draft: true
prerelease: false
files: ${{ matrix.asset }}
Generated
+1 -1
View File
@@ -3822,7 +3822,7 @@ dependencies = [
[[package]]
name = "tglock"
version = "2.0.0-beta.14"
version = "2.0.0-beta.15"
dependencies = [
"aes",
"cipher",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "tglock"
version = "2.0.0-beta.14"
version = "2.0.0-beta.15"
edition = "2021"
rust-version = "1.88"
description = "Telegram unblock via local WebSocket tunnel"
+72 -46
View File
@@ -1,38 +1,64 @@
# Как выпускать релиз
## Порядок важен
## Подготовка через PR
Токен GitHub Actions создаёт релиз **только на HEAD ветки по умолчанию**. Если тег
отстанет от `main` хотя бы на один коммит, публикация упадёт с ошибкой
`Resource not accessible by integration` — сообщение про права, хотя права в
порядке и дело в положении тега.
1. Поднять версию согласованно в шести файлах:
- `Cargo.toml` — версия пакета `tglock`;
- `Cargo.lock` — версия только пакета `tglock`, без обновления зависимостей;
- `tauri.conf.json` — версия приложения и имён установщиков;
- `package.json` — версия frontend-пакета;
- `package-lock.json` — верхняя версия и `packages[""].version`;
- `ui/main.ts` — версия копируемого диагностического отчёта.
2. Подготовить описание изменений и проверок, отдельно указав экспериментальные
платформы и непроверенные сценарии. Android получает `versionName`/`versionCode`
из конфигурации Tauri при сборке; сгенерированный `tauri.properties` не коммитится.
3. Проверить финальные изменения PR и слить его в `main` с соблюдением обязательных
проверок ветки. Дождаться зелёных проверок и Android workflow на итоговом HEAD
`main` до создания тега. APK предыдущего PR-коммита не заменяет артефакт этого
коммита: `headSha` Android run должен совпадать с коммитом будущего тега.
Отсюда единственное жёсткое правило: **тег ставится последним, и пока идёт
релиз, в `main` не пушим.**
## Тег и сборка
## Шаги
Release workflow этого репозитория допускает тег только на текущем HEAD ветки
по умолчанию. Guard сохраняет прежнюю защиту от выпуска другого коммита:
ранее расхождение тега и `main` сопровождалось ошибкой публикации
`Resource not accessible by integration`.
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. Поставить аннотированный тег на этот же коммит и запушить его:
1. Сверить `git ls-remote origin refs/heads/main` и локальный
`git rev-parse HEAD` после перехода на финальный коммит `main`.
2. Убедиться, что выбранная версия и тег ещё не существуют, затем поставить
аннотированный тег на этот коммит:
```bash
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,
документации, чего угодно — после публикации релиза.
3. Пока релиз собирается, не добавлять коммиты в `main`. Guard проверяет HEAD
в начале работы и не устраняет гонку после проверки.
4. Дождаться **всех** jobs Release. Workflow создаёт **draft** и сохраняет его
черновиком при загрузке GUI, CLI и ARM64. Частично загруженный выпуск не должен
становиться общедоступным до проверок.
## Проверить, что выпустили
Ручной `workflow_dispatch` запускайте на релизном теге, а не на ветке: часть
загрузчиков использует `github.ref_name` как имя релиза.
Зелёный workflow — это ещё не доказательство. В бетах 2 и 3 сборка была зелёной,
а в приложение попадал headless-бинарь вместо графического. Поэтому проверяем
содержимое, а не имя файла:
## Проверка артефактов и публикация
Зелёный workflow сам по себе недостаточен. В бетах 2 и 3 в GUI-бандл попадал
headless-бинарь, поэтому проверяются содержимое и происхождение:
- Windows: GUI `.exe` и `tglock-cli-x86_64-pc-windows-msvc.exe`.
- macOS: универсальные `.dmg`, `.app.tar.gz` и CLI.
- Linux x64: `.AppImage`, `.deb` и CLI.
- ARM64 Linux: `tglock-cli-aarch64-unknown-linux-musl` и его `.sha256`;
workflow проверяет ELF без динамических зависимостей и запуск бинаря.
- Android: скачать ARM64 debug APK из успешного Android run с `headSha`,
совпадающим с коммитом тега. Сохранить имя с версией и явной пометкой
`android-arm64-debug`, прикрепить APK к тому же draft. Указать экспериментальный
статус и ограничения debug-подписи из [ANDROID.md](ANDROID.md).
Пример проверки скачанного macOS-бандла:
```bash
gh release download vX.Y.Z --repo by-sonic/tglock -p 'TGLock_universal.app.tar.gz' -D /tmp/check
@@ -40,35 +66,35 @@ 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`) и ругается, если в бандле оказался не тот.
Проверьте версию скачанного CLI и хотя бы один реальный протокольный обмен
через него по [LIVE_PROBE.md](LIVE_PROBE.md). Зафиксируйте, какие платформы
исполнены локально, а какие проверены CI. Секрет локального прокси в заметки и
публичные артефакты не включается.
## Если публикация всё-таки упала с `Resource not accessible by integration`
Когда набор файлов полон, подписи/контрольные суммы и версии сверены, а release
notes готовы, опубликуйте draft. Например:
Значит, тег разошёлся с `main`. Сверьте:
```bash
gh release edit vX.Y.Z --repo by-sonic/tglock --draft=false --notes-file release-notes.md
```
Исторически `v2.0.0-beta.*` в этом репозитории публикуются с `prerelease=false`;
workflow сохраняет эту настройку. После публикации проверьте публичную страницу
релиза, ссылки скачивания и список файлов. Краткий пост об обновлении должен
ссылаться на опубликованный релиз и отделять проверенные исправления от
экспериментальных платформ.
## Если сборка или публикация упала
Сначала прочитайте ошибку и сверяйте коммит тега, `main`, workflow run и версии.
Не делайте вывод о причине только из текста `Resource not accessible by
integration`: он может относиться и к правам токена.
```bash
git ls-remote origin refs/heads/main 'refs/tags/vX.Y.Z^{}'
```
Если SHA разные — переставьте тег на HEAD и запушьте заново:
```bash
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.
От этого защищает только правило из первого раздела.
Если это ошибка инфраструктуры, повторите упавшие jobs на том же коммите.
Если нужна правка исходников, внесите её через PR и выберите новую версию для
нового тега. Опубликованные теги и бинарные артефакты не заменяйте: пользователи
должны иметь возможность воспроизвести уже выпущенную версию.
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "tglock-ui",
"version": "2.0.0-beta.14",
"version": "2.0.0-beta.15",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "tglock-ui",
"version": "2.0.0-beta.14",
"version": "2.0.0-beta.15",
"dependencies": {
"@tauri-apps/api": "^2.8.0"
},
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "tglock-ui",
"private": true,
"version": "2.0.0-beta.14",
"version": "2.0.0-beta.15",
"type": "module",
"scripts": {
"test:worker": "node --experimental-vm-modules --test worker/tglock-worker.test.js",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "TGLock",
"version": "2.0.0-beta.14",
"version": "2.0.0-beta.15",
"identifier": "com.bysonic.tglock",
"mainBinaryName": "tglock",
"build": {
+1 -1
View File
@@ -451,7 +451,7 @@ async function copyDiagnostics(): Promise<void> {
// Public reports exclude proxy links, worker domains and free-form logs.
const report = {
application: "TGLock",
version: "2.0.0-beta.14",
version: "2.0.0-beta.15",
running: status.running,
activeConnections: status.activeConnections,
tunnels: status.tunnels,