feat(server): инстанс отдаёт манифест автообновления desktop-обёртки
Обёртка с первого инкремента Фазы 6 запрашивает
`GET /updates/{target}/{arch}/{current_version}`, но на инстансе этого пути не
было: запрос попадал в SPA-заглушку, клиент получал HTML с кодом 200 и писал
в лог «error decoding response body».
Что сделано:
- `internal/server/updates.go` — статика автообновления: каталог `UPDATES_DIR`
(в контейнере `/app/updates:ro`), раскладка `<target>/<arch>/<version>.json` +
артефакт и `.sig`; версия без расширения отображается на `<version>.json`,
а если его нет — на `latest.json` (обёртка приходит со своей установленной
версией, «новее ли релиз» решает клиент сравнением semver). Для имён
с расширением артефакта запасного варианта нет: иначе вместо архива клиент
скачал бы манифест и подпись не сошлась бы. Сегменты пути проверяются по
символам, выход за каталог невозможен; `/updates/` добавлен в reservedPrefixes,
поэтому отсутствующий манифест — честный 404, а не HTML-шелл;
- `scripts/desktop-release.sh` и цели `make desktop-release` /
`make desktop-release-upload HOST=…`: берут собранный `glchat.app.tar.gz` + `.sig`,
определяют target/arch по имени артефакта, копируют их в каталог инстанса и
собирают манифест (версия из `tauri.conf.json`), объединяя платформы одной
версии; есть `--dry-run` и загрузка на инстанс по SSH;
- `deploy/install.sh` и шаблоны compose: каталог `${GLCHAT_UPDATES_DIR}`
(`/opt/glchat/updates`) создаётся установщиком и монтируется в контейнер
только для чтения; в `.env` добавлен `GLCHAT_UPDATES_DIR`.
Владельцу внешнего прокси добавлять ничего не нужно: `/updates/...` уходит в
catch-all `handle` и доходит до приложения, как статика клиента.
Проверено на стенде: `curl https://gl.mhspx.su/updates/darwin/aarch64/0.1.0`
→ 200 `application/json; charset=utf-8`, артефакт → 200 `application/gzip`,
отсутствующие платформа и версия → 404 (не HTML), `readyz` → 200, обёртка
в логе пишет «обновлений нет» вместо ошибки разбора. Тесты: 6 новых в
`internal/server/updates_test.go`, манифест разбирается типом самого плагина
обновлений (`updates::tests::манифест_разбирается_плагином_обновлений`).
This commit is contained in:
@@ -219,6 +219,22 @@ desktop-build: ## Собрать desktop-приложение (бандлы по
|
||||
desktop-run: ## Запустить собранное приложение (macOS); доп. аргументы — ARGS=…
|
||||
open -a "$(DESKTOP_TAURI_DIR)/target/release/bundle/macos/glchat.app" $(ARGS)
|
||||
|
||||
# Каталог обновлений инстанса и его публичный адрес (docs/client-tauri.md §4).
|
||||
# Раскладку делает scripts/desktop-release.sh: манифест версии + latest.json,
|
||||
# артефакт и подпись; приложение отдаёт их по /updates/{target}/{arch}/{version}.
|
||||
DESKTOP_UPDATES_DIR ?= /opt/glchat/updates
|
||||
DESKTOP_BASE_URL ?= https://gl.mhspx.su
|
||||
|
||||
.PHONY: desktop-release
|
||||
desktop-release: ## Разложить артефакты обновления в DESKTOP_UPDATES_DIR (нужен sudo)
|
||||
bash scripts/desktop-release.sh --dir "$(DESKTOP_UPDATES_DIR)" \
|
||||
--base-url "$(DESKTOP_BASE_URL)" $(ARGS)
|
||||
|
||||
.PHONY: desktop-release-upload
|
||||
desktop-release-upload: ## Загрузить обновления на инстанс: make desktop-release-upload HOST=user@server
|
||||
bash scripts/desktop-release.sh --remote "$(HOST)" \
|
||||
--base-url "$(DESKTOP_BASE_URL)" $(ARGS)
|
||||
|
||||
.PHONY: docker-build
|
||||
docker-build: ## Собрать образ приложения
|
||||
docker build \
|
||||
|
||||
Reference in New Issue
Block a user