# Релиз и автообновления Документ описывает, как выпускать новые версии и как устроена система авто-обновлений. ## TL;DR ```pwsh $env:GITEA_TOKEN = '' npm run release -- -Bump patch # 0.5.1 → 0.5.2 npm run release -- -Bump minor -BridgeTags v0.5.0 # 0.5.x → 0.6.0 + bridge npm run release -- -Version 1.0.0 ``` Скрипт делает всё сам: бамп версии, коммит, тег, push, тесты, сборка инсталлятора, загрузка в Gitea releases. ## Архитектура auto-update ### Где лежат артефакты Каждый выпуск публикует три файла: ``` Exercise-Reminder-Setup-X.Y.Z.exe # NSIS-инсталлятор (~80 MB) Exercise-Reminder-Setup-X.Y.Z.exe.blockmap # для differential update (~90 KB) latest.yml # манифест: версия + хеш + размер ``` И они одновременно публикуются в **три-четыре места** на Gitea: | Release tag | Назначение | |------------------|-------------------------------------------------------------| | `vX.Y.Z` | Архив + changelog для людей | | `update-channel` | **Фиксированный URL для auto-updater** (никогда не меняется) | | `vN.M.K` (bridge)| Мост: чтобы клиенты на старых версиях нашли обновление | ### Что приложение запекает в бинарник В `package.json` → `build.publish.url`: ``` https://xn--90adajar8af4h.xn--p1ai/git/AnRil/laude/releases/download/update-channel ``` Этот URL **никогда не меняется**. Все версии (и сегодняшние, и будущие) проверяют один и тот же `update-channel/latest.yml`. ### Цикл проверки 1. При запуске и каждый час `electron-updater` делает GET на `…/update-channel/latest.yml`. 2. Если в манифесте версия выше текущей — Settings → Обновления показывает «Доступно vX.Y.Z». По клику качается `.exe` (или differential по `.blockmap`). 3. После скачивания — кнопка «Перезапустить». NSIS обновляет инсталляцию поверх с сохранением `%APPDATA%\Exercise Reminder\app-state.json`. ### Bridge-теги (миграционный период) До v0.5.1 publish.url был `…/releases/download/v${version}` — у каждой версии свой адрес. Установленные ранее копии запекли старый URL. Чтобы они нашли обновление, новые артефакты также заливаются в их старые releases (флаг `-BridgeTags`). После того как все клиенты получили v0.5.1 или выше, аргумент `-BridgeTags` можно перестать использовать — все будущие версии берут обновления через `update-channel`. ### Поведение при ошибках - Hourly auto-check работает в **silent**-режиме: сетевые ошибки логируются в консоль, но **не** показываются как красный баннер. Следующая попытка через час. - Boot-check ретраит 3 раза с backoff 30s/2m/5m перед тем как сдаться. - Только ручной клик «Проверить обновления» показывает ошибку, если она есть. ## Команды ```pwsh # Один раз — токен из Gitea Settings -> Applications (write:repository). [Environment]::SetEnvironmentVariable('GITEA_TOKEN', '', 'User') # Релиз npm run release -- -Bump patch # patch (0.5.1 -> 0.5.2) npm run release -- -Bump minor # minor (0.5.x -> 0.6.0) npm run release -- -Bump major # major npm run release -- -Version 1.2.3 # точная версия npm run release -- -BridgeTags v0.4.0,v0.5.0 # дополнительные мосты npm run release -- -DryRun # план без действий ``` Что делает `release.ps1`: 1. Проверяет чистоту дерева. 2. Бампит `package.json`, коммитит как `chore(release): vX.Y.Z`. 3. `npm run typecheck` + `npm run test:run`. 4. `npm run dist` → NSIS-инсталлятор + blockmap + latest.yml в `release/`. 5. `git tag vX.Y.Z` и push main + tag в origin. 6. Через `upload-release-assets.ps1` заливает артефакты в каждый тег из списка: `vX.Y.Z`, `update-channel`, и все `-BridgeTags`. 7. Каждая заливка ретраит до 4 раз с backoff 15s/45s/2m/5m на 504. ## Тестирование auto-update 1. Установить какую-нибудь старую версию через `.exe` из её release. 2. Релизнуть свежую версию. 3. В установленной копии: Settings → Обновления → Проверить. 4. Должно показать «Доступна vX.Y.Z» с кнопкой «Скачать». 5. Скачать → Перезапустить → проверить версию. Для `npm run dev` auto-updater отключён — статус сразу `unsupported`. ## Откат релиза 1. Удалить release в Gitea UI (или через API). 2. `git push origin :refs/tags/vX.Y.Z` и `git tag -d vX.Y.Z`. 3. `git revert ` (бамп уже запушен). 4. Если артефакты успели уехать в `update-channel` — перезалить туда предыдущую версию: `pwsh scripts/upload-release-assets.ps1 -Tag update-channel -AssetVersion `. На практике лучше выпустить hotfix-патч `X.Y.Z+1`, чем откатывать. ## Gitea Actions Раньше в `.gitea/workflows/` лежали `ci.yml` и `release.yml`. Они требуют Gitea Actions runners (отдельная служба, у нас не настроена), поэтому каждая push-операция оставляла зависший workflow run в Actions tab. Workflows удалены, has_actions на репозитории выключен, Actions tab возвращает 404. Если когда-нибудь захочется CI — добавить обратно `.gitea/workflows/*.yml` + поднять runners. ## Что попадает в установщик См. `build.files` в `package.json`: - `out/**/*` — собранный код (main + preload + renderer) - `resources/**/*` — иконки Без `node_modules`, без исходников, без тестов — `electron-builder` сам выбирает только необходимое.