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

7.2 KiB
Raw Blame History

Релиз и автообновления

Документ описывает, как выпускать новые версии и как устроена система авто-обновлений.

TL;DR

$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.jsonbuild.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 перед тем как сдаться.
  • Только ручной клик «Проверить обновления» показывает ошибку, если она есть.

Команды

# Один раз — токен из 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 сам выбирает только необходимое.