From af3b14395ff021dbbda368a36a21325995f54970 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20Sonic?= Date: Thu, 30 Jul 2026 15:40:18 +0300 Subject: [PATCH] =?UTF-8?q?fix(bundle):=20=D0=B2=20v2.0.0-beta.2=20=D1=83?= =?UTF-8?q?=D0=BF=D0=B0=D0=BA=D0=BE=D0=B2=D1=8B=D0=B2=D0=B0=D0=BB=D1=81?= =?UTF-8?q?=D1=8F=20CLI=20=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=BE=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F=20(#31)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Симптом: на macOS приложение не запускается совсем — иконка подпрыгивает в доке и гаснет, хотя разрешение выдано. Причина. В #25 в крейте появился второй бинарь tglock-cli, а mainBinaryName в tauri.conf.json задан не был. Бандлер Tauri выбрал главным исполняемым файлом приложения headless CLI. Запуск .app стартовал консольный прокси, окна не создавалось. Проверено на опубликованных артефактах: CFBundleExecutable размер MacOS/* beta.1 tglock 18.6 МБ ← GUI, правильно beta.2 tglock-cli 4.5 МБ ← консольный прокси Задеты все платформы, не только macOS. В .deb лежит usr/bin/tglock-cli, а в TGLock.desktop прописан Exec=tglock-cli. Установщик Windows упал с 2.0 МБ до 0.6 МБ — тот же признак. То есть beta.2 не запускается нигде. Почему это уехало с зелёным CI: сборка релиза была успешной, потому что никто не проверял, что внутри бандла. Тесты гоняют ядро, а не собранное приложение. Исправление: mainBinaryName = "tglock" в tauri.conf.json. Проверено сборкой на этой же ветке — Tauri берёт tglock.exe, установщик вернулся к нормальному размеру. Чтобы это не повторилось, добавлены две проверки: - в CI, на каждый PR: mainBinaryName обязан совпадать с именем [[bin]], у которого required-features = ["gui"]. Проверено в обе стороны — на верном конфиге проходит, на подставленном tglock-cli падает; - в release.yml, после сборки: на macOS читается CFBundleExecutable из Info.plist, на Linux проверяется наличие /usr/bin/tglock в .deb. Смотрит внутрь настоящего артефакта, а не в конфиг. README: пример команды с хешем больше не прибит к конкретной версии, ссылка на запуск сборки заменена на общее указание, и добавлена строка для тех, кто уже скачал beta.2 и не смог её открыть. Co-authored-by: by-sonic <171230345+by-sonic@users.noreply.github.com> --- .github/workflows/ci.yml | 20 ++++++++++++++++++++ .github/workflows/release.yml | 23 +++++++++++++++++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 6 +++--- package.json | 2 +- tauri.conf.json | 3 ++- 7 files changed, 51 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 684bb85..42e5a6e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,26 @@ jobs: with: components: rustfmt, clippy + # Оба бинаря лежат в одном крейте, и бандлер Tauri без явного указания + # может взять headless CLI как главный исполняемый файл приложения. + # Именно это уехало в v2.0.0-beta.2: .app и .deb содержали tglock-cli, и + # приложение не открывалось ни на одной платформе. + - name: Main binary of the bundle must be the GUI one + run: | + node -e " + const fs = require('fs'); + const conf = JSON.parse(fs.readFileSync('tauri.conf.json', 'utf8')); + const toml = fs.readFileSync('Cargo.toml', 'utf8'); + const gui = toml.split('[[bin]]').slice(1) + .find(b => /required-features\s*=\s*\[\s*\"gui\"\s*\]/.test(b)); + if (!gui) throw new Error('не найден [[bin]] с required-features = [\"gui\"]'); + const name = (gui.match(/name\s*=\s*\"([^\"]+)\"/) || [])[1]; + if (conf.mainBinaryName !== name) { + throw new Error('mainBinaryName=' + conf.mainBinaryName + ', а GUI-бинарь называется ' + name); + } + console.log('mainBinaryName указывает на GUI-бинарь:', name); + " + - name: Check formatting run: cargo fmt --check diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7ba250f..cffb971 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -75,6 +75,29 @@ jobs: prerelease: false args: ${{ matrix.args }} + # Смотрит внутрь собранного бандла. v2.0.0-beta.2 опубликовался с зелёным + # CI, хотя .app и .deb содержали headless CLI вместо приложения: сборка + # была успешной, просто никто не проверял, что внутри. + - name: The bundle must contain the GUI binary + if: runner.os == 'macOS' + shell: bash + run: | + app=$(find target -maxdepth 6 -name 'TGLock.app' -type d | head -1) + test -n "$app" || { echo "TGLock.app не найден"; exit 1; } + exe=$(/usr/libexec/PlistBuddy -c 'Print :CFBundleExecutable' "$app/Contents/Info.plist") + echo "CFBundleExecutable = $exe" + test "$exe" = "tglock" || { echo "в бандле не GUI-бинарь"; exit 1; } + test -x "$app/Contents/MacOS/tglock" || { echo "исполняемый файл отсутствует"; exit 1; } + + - name: The bundle must contain the GUI binary + if: runner.os == 'Linux' + shell: bash + run: | + deb=$(find target -maxdepth 6 -name '*.deb' | head -1) + test -n "$deb" || { echo ".deb не найден"; exit 1; } + dpkg-deb -c "$deb" | grep -E ' \./usr/bin/tglock$' \ + || { echo "в .deb нет /usr/bin/tglock:"; dpkg-deb -c "$deb" | grep '/bin/'; exit 1; } + cli: name: Headless CLI ${{ matrix.platform }} needs: publish diff --git a/Cargo.lock b/Cargo.lock index 4d1f669..03bf46f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3553,7 +3553,7 @@ dependencies = [ [[package]] name = "tglock" -version = "2.0.0-beta.2" +version = "2.0.0-beta.3" dependencies = [ "aes", "cipher", diff --git a/Cargo.toml b/Cargo.toml index bc5edab..4e3c910 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tglock" -version = "2.0.0-beta.2" +version = "2.0.0-beta.3" edition = "2021" rust-version = "1.88" description = "Telegram unblock via local WebSocket tunnel" diff --git a/README.md b/README.md index 2afdd50..155c82a 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ TGLock — это **локальный прокси** на твоём компь Все сборки весят единицы мегабайт. Исключение — `.AppImage`: он несёт своё окружение и поэтому крупный. -> **🖥 `tglock-cli`** — тот же туннель без графического интерфейса, одним бинарём. Нужен там, где окно не создаётся: сервер, контейнер, виртуалка, машина без монитора. Доступен начиная с `v2.0.0-beta.2`. Подробности — [ниже](#-без-графического-интерфейса-tglock-cli). +> **🖥 `tglock-cli`** — тот же туннель без графического интерфейса, одним бинарём. Нужен там, где окно не создаётся: сервер, контейнер, виртуалка, машина без монитора. Доступен начиная с `v2.0.0-beta.2`. Если ты скачал beta.2 и приложение не открывалось — это была ошибка сборки, исправлено в beta.3. Подробности — [ниже](#-без-графического-интерфейса-tglock-cli). ### 🛡 Антивирус ругается, SmartScreen предупреждает, VirusTotal показывает детекты @@ -107,7 +107,7 @@ TGLock — это **локальный прокси** на твоём компь 1. **Сверить контрольную сумму.** GitHub публикует `sha256` каждого файла прямо на [странице релиза](https://github.com/by-sonic/tglock/releases/latest) — разверни `Assets` и увидишь digest рядом с именем. Сравни с тем, что скачалось: ```powershell - Get-FileHash .\TGLock_2.0.0-beta.2_x64-setup.exe -Algorithm SHA256 + Get-FileHash .\TGLock_<версия>_x64-setup.exe -Algorithm SHA256 ``` ```bash @@ -117,7 +117,7 @@ TGLock — это **локальный прокси** на твоём компь Это доказывает, что файл не подменили по пути к тебе. -2. **Посмотреть, как файл собирался.** Бинарники собирает GitHub Actions из публичного коммита, лог открыт и его никто не может отредактировать задним числом. Сборка релиза `v2.0.0-beta.2` — [run 30535555083](https://github.com/by-sonic/tglock/actions/runs/30535555083), коммит `b062724`. Видно, какой исходник взят и какими командами собран. +2. **Посмотреть, как файл собирался.** Бинарники собирает GitHub Actions из публичного коммита, лог открыт и его никто не может отредактировать задним числом. У каждого релиза на странице Actions есть свой запуск: видно, какой коммит взят и какими командами собран. Ссылка на него — в описании релиза. 3. **Собрать самому.** Для CLI это одна команда и никаких зависимостей кроме Rust: diff --git a/package.json b/package.json index dd341ef..90946ae 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "tglock-ui", "private": true, - "version": "2.0.0-beta.2", + "version": "2.0.0-beta.3", "type": "module", "scripts": { "dev": "vite --port 1420", diff --git a/tauri.conf.json b/tauri.conf.json index 8ba74b4..cb41fec 100644 --- a/tauri.conf.json +++ b/tauri.conf.json @@ -1,8 +1,9 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "TGLock", - "version": "2.0.0-beta.2", + "version": "2.0.0-beta.3", "identifier": "com.bysonic.tglock", + "mainBinaryName": "tglock", "build": { "beforeDevCommand": "npm run dev", "devUrl": "http://localhost:1420",