release: glchat 0.1.1
Версия — в одном месте: файл VERSION в корне, из него её берут Makefile, deploy/install.sh (IMAGE_TAG) и desktop-обёртка (tauri.conf.json, Cargo.toml). Публикация обновлений (scripts/desktop-release.sh): - манифесты прошлых релизов удаляются: оставшийся <старая версия>.json перекрывал новый релиз — обёртка спрашивает манифест своей версии и видела «обновлений нет»; - mktemp-каталог раскладки получает 755, каталоги на инстансе нормализуются: rsync -a переносил режим 0700 на корень каталога обновлений, и приложение не могло читать манифесты (404 при живых файлах); - --remote работает без TTY и без sudo, если каталог обновлений записываем; опции ssh — в GLCHAT_SSH_OPTS; - предупреждение при публикации версии старше уже опубликованной. Сервер: HEAD /updates/... (chi не выводит его из GET) — размер и тип артефакта без скачивания; тест TestUpdatesAnswersHead. Приёмка на живом канале: 0.1.0 → 0.1.1 на стенде (скачивание, проверка подписи, установка, перезапуск), /Applications/glchat.app = 0.1.1.
This commit is contained in:
+83
-13
@@ -134,25 +134,68 @@ Caddy не нужна: и встроенный Caddy профиля, и внеш
|
||||
└── darwin/aarch64/
|
||||
├── glchat.app.tar.gz # артефакт релиза (создаёт tauri build)
|
||||
├── glchat.app.tar.gz.sig # подпись ed25519 (формат minisign)
|
||||
├── 0.1.0.json # манифест версии
|
||||
├── 0.1.1.json # манифест текущего релиза
|
||||
└── latest.json # манифест последнего релиза — его и отдаёт инстанс
|
||||
```
|
||||
|
||||
Публикация релиза:
|
||||
Манифестов прошлых релизов в каталоге быть не должно: обёртка спрашивает
|
||||
`/updates/{target}/{arch}/{своя версия}`, и оставшийся `<старая версия>.json`
|
||||
перекрыл бы новый релиз — клиент со старой версией получил бы «обновлений нет».
|
||||
Публикующий скрипт сам убирает такие файлы (см. ниже).
|
||||
|
||||
```bash
|
||||
make desktop-build # собрать бандл (.app/.dmg) и артефакты обновления
|
||||
sudo make desktop-release # разложить в /opt/glchat/updates + создать манифест
|
||||
make desktop-release-upload HOST=user@server # то же, но по SSH (sudo спросит пароль в терминале)
|
||||
make desktop-release ARGS='--dry-run' # посмотреть план, ничего не записывая
|
||||
```
|
||||
## Выпуск релиза
|
||||
|
||||
Версия живёт в одном месте — файл `VERSION` в корне репозитория; из него её
|
||||
берут `Makefile` (версия сервера и образов), `deploy/install.sh` (`IMAGE_TAG`)
|
||||
и desktop-обёртка (`desktop/src-tauri/tauri.conf.json` + `Cargo.toml` — их
|
||||
значения должны совпадать с `VERSION`).
|
||||
|
||||
1. Поднять версию:
|
||||
|
||||
```bash
|
||||
echo 0.1.2 > VERSION # версия сервера и обёртки
|
||||
# те же значения — в desktop/src-tauri/tauri.conf.json, Cargo.toml, Cargo.lock
|
||||
make web-build && make build # сервер собирается с новой версией
|
||||
```
|
||||
|
||||
2. Проверки и сборка бандла:
|
||||
|
||||
```bash
|
||||
make go-lint && go test -tags sqlite_fts5 -race -count=1 ./internal/...
|
||||
cd web && npm run check && npm run lint && npm test && cd ..
|
||||
make desktop-check # fmt, clippy, cargo test
|
||||
make desktop-build # .app + .dmg + артефакты обновления
|
||||
```
|
||||
|
||||
3. Зафиксировать и пометить релиз:
|
||||
|
||||
```bash
|
||||
git add VERSION Makefile deploy/install.sh desktop/src-tauri scripts/desktop-release.sh
|
||||
git commit -m "release: 0.1.2"
|
||||
git tag -a v0.1.2 -m "glchat 0.1.2" && git push origin main --tags
|
||||
```
|
||||
|
||||
4. Опубликовать обновление на инстансе:
|
||||
|
||||
```bash
|
||||
sudo make desktop-release # локальный инстанс
|
||||
make desktop-release-upload HOST=user@server # по SSH (sudo спросит пароль)
|
||||
make desktop-release-upload HOST=user@server \
|
||||
GLCHAT_SSH_OPTS="-i ~/.ssh/key -o IdentitiesOnly=yes" # свой ключ, без TTY (CI)
|
||||
make desktop-release ARGS='--dry-run' # посмотреть план
|
||||
```
|
||||
|
||||
5. Проверить канал и живьём обновиться со старой версии — см. следующий раздел.
|
||||
|
||||
Скрипт `scripts/desktop-release.sh` берёт версию из `tauri.conf.json`, сам
|
||||
определяет target/arch по имени артефакта, копирует артефакт и `.sig`, собирает
|
||||
манифест (`version`, `notes`, `pub_date`, `platforms.<target>-<arch>.signature/url`)
|
||||
и кладёт его и как `<version>.json`, и как `latest.json`. Несколько платформ
|
||||
одной версии (macOS + Windows + Linux) складываются в один манифест: запускайте
|
||||
скрипт по разу на артефакт.
|
||||
манифест (`version`, `notes`, `pub_date`, `platforms.<target>-<arch>.signature/url`),
|
||||
кладёт его и как `<version>.json`, и как `latest.json`, а манифесты прошлых
|
||||
релизов убирает. Несколько платформ одной версии (macOS + Windows + Linux)
|
||||
складываются в один манифест: запускайте скрипт по разу на артефакт. Каталог
|
||||
обновлений на инстансе обычно принадлежит root — тогда rsync идёт через sudo;
|
||||
если каталог записываем (стенд), sudo не нужен и загрузка работает без
|
||||
терминала.
|
||||
|
||||
`latest.json` нужен потому, что обёртка приходит со **своей установленной**
|
||||
версией: «новее ли релиз» решает клиент сравнением semver
|
||||
@@ -169,7 +212,8 @@ catch-all `handle` и доходит до приложения (так же, к
|
||||
Проверка (стенд):
|
||||
|
||||
```bash
|
||||
curl -s https://gl.mhspx.su/updates/darwin/aarch64/0.1.0 | jq .
|
||||
curl -s https://gl.mhspx.su/updates/darwin/aarch64/0.1.0 | jq . # манифест для старой версии
|
||||
curl -sI https://gl.mhspx.su/updates/darwin/aarch64/glchat.app.tar.gz | head -3 # 200 + размер
|
||||
# в логе обёртки (~/Library/Logs/su.mhspx.glchat/glchat.log) —
|
||||
# «обновлений нет» (манифест разобран) вместо
|
||||
# «проверка обновлений не удалась: … 404»
|
||||
@@ -179,6 +223,32 @@ curl -s https://gl.mhspx.su/updates/darwin/aarch64/0.1.0 | jq .
|
||||
подтверждение в диалоге (во время звонка перезапуск без согласия не делается) →
|
||||
подпись проверяется до установки, downgrade отклоняется.
|
||||
|
||||
### Приёмка релиза на живом инстансе (26.09.2026, 0.1.0 → 0.1.1)
|
||||
|
||||
Проверено на боевом канале стенда, без локальных заглушек:
|
||||
|
||||
- манифест опубликован `scripts/desktop-release.sh --remote`, артефакт
|
||||
`glchat.app.tar.gz` (3 204 953 Б) и подпись лежат в
|
||||
`/opt/glchat/updates/darwin/aarch64/`;
|
||||
- обёртка 0.1.0, запущенная с `--update-now`, в журнале (UTC) показала:
|
||||
`доступно обновление 0.1.1` → `тихое обновление по флагу: 0.1.0 → 0.1.1` →
|
||||
`обновление 0.1.1 установлено, перезапуск` → `обёртка запущена: версия=0.1.1` →
|
||||
`обновлений нет` (17:08:23–17:08:25Z);
|
||||
- запрос старой версии `GET /updates/darwin/aarch64/0.1.0` отдаёт манифест
|
||||
**0.1.1** — это и есть та точка, где раньше мешал оставшийся `0.1.0.json`;
|
||||
- `/Applications/glchat.app` после установки — 0.1.1, ярлык на рабочем столе
|
||||
(`~/Desktop/glchat.app`) указывает на него.
|
||||
|
||||
**Важно про место установки.** `tauri-plugin-updater` распаковывает обновление
|
||||
во временный каталог и переносит бандл `rename(2)`. Если приложение лежит на
|
||||
другом томе, чем временный каталог (например, на внешнем диске
|
||||
`/Volumes/…`, а `TMPDIR` — на загрузочном), установка падает с
|
||||
`установка обновления не удалась: Cross-device link (os error 18)`, хотя
|
||||
скачивание и проверка подписи проходят. Поэтому приложение для автообновления
|
||||
надо держать на загрузочном томе — так делает `.dmg` (ставит в `/Applications`);
|
||||
ярлык на рабочем столе лучше вести на `/Applications/glchat.app`, а не на
|
||||
сборку в репозитории.
|
||||
|
||||
### Локальная проверка «поверх старой версии» (без стенда)
|
||||
|
||||
Установка обновления проверена локально на настоящем сервере инстанса: сборка
|
||||
|
||||
Generated
+1
-1
@@ -1474,7 +1474,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "glchat-desktop"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "glchat-desktop"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
description = "glchat — desktop-обёртка вокруг веб-клиента (Tauri 2)"
|
||||
authors = ["glchat"]
|
||||
license = "AGPL-3.0-or-later"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "glchat",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"identifier": "su.mhspx.glchat",
|
||||
"build": {
|
||||
"frontendDist": "./ui"
|
||||
|
||||
Reference in New Issue
Block a user