Files
laude/RELEASING.md
AnRil d6f94ee1c9 docs+chore: retry upload on TLS/504 + refresh README/RELEASING
Upload script:
- Retry curl on transient network failures (504, schannel TLS abrupt
  close): up to 4 retries with 15s/45s/2m/5m backoff. Before each retry,
  list the release assets server-side — Gitea sometimes commits the
  body but times out the response, so the file may already be there at
  the expected size (skip retry). If present at wrong size (partial),
  delete before re-uploading. ASCII-only (PS5.1 reads files in CP1251
  without BOM).

Docs:
- README: bump release/test badges to v0.5.1 / 51 tests; mention silent
  retry in the auto-update feature line.
- RELEASING: rewrite around the new update-channel architecture, bridge
  tags, and dropped Gitea Actions workflows.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 22:37:33 +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://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 перед тем как сдаться.
  • Только ручной клик «Проверить обновления» показывает ошибку, если она есть.

Команды

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