Files
laude/RELEASING.md
AnRil 0cace2975d chore(remote): миграция Gitea-URL на сабдомен git.
Gitea переехал с path-prefix (xn--90adajar8af4h.xn--p1ai/git/) на
выделенный сабдомен (git.xn--90adajar8af4h.xn--p1ai). Старый URL теперь
отдаёт чужое приложение и для git мёртв.

- package.json: publish.url (канал авто-апдейта) -> новый хост
- scripts/release.ps1, upload-release-assets.ps1: $giteaHost (API + release URL)
- README, CHANGELOG, RELEASING.md, CLAUDE.md: ссылки на репозиторий/релизы

Прим.: уже установленные копии (<=0.5.8) запекли старый URL в бинарник —
их авто-апдейт нужно мигрировать отдельно (bridge-теги), правкой конфига
это ретроактивно не лечится.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 22:03:16 +07:00

143 lines
7.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Релиз и автообновления
Документ описывает, как выпускать новые версии и как устроена система
авто-обновлений.
## TL;DR
```pwsh
$env:GITEA_TOKEN = '<token из Gitea Settings → Applications>'
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://git.xn--90adajar8af4h.xn--p1ai/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', '<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 <bump-hash>` (бамп уже запушен).
4. Если артефакты успели уехать в `update-channel` — перезалить туда
предыдущую версию: `pwsh scripts/upload-release-assets.ps1 -Tag update-channel -AssetVersion <previous>`.
На практике лучше выпустить 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`
сам выбирает только необходимое.