Files
laude/RELEASING.md
AnRil 92e15e69a3
Some checks failed
CI / Typecheck + Tests (push) Has been cancelled
CI / Build (Windows) (push) Has been cancelled
feat: auto-update, тесты и CI/CD
Полная автоматизация релизного цикла.

== Auto-update (electron-updater) ==
- src/main/updater.ts — обёртка над autoUpdater с дискриминированным
  UpdaterStatus union и broadcast через IPC. autoDownload=false,
  пользователь сам жмёт «Скачать». allowDowngrade=false. Проверка
  каждые 6 часов, первая через 5с после старта.
- В dev-режиме (app.isPackaged=false) статус сразу становится
  'unsupported' с пояснением — никаких exceptions из updater'а.
- build.publish в package.json: provider=generic, url указывает на
  Gitea release assets конкретной версии.
- src/main/ipc.ts: 4 новых канала — status/check/download/install.
- src/preload: API window.api.updater* + onUpdaterStatus.
- src/renderer/src/components/UpdaterCard.tsx: HUD-карточка в Settings
  с состояниями idle/checking/available/downloading/downloaded/error,
  прогресс-бар с скоростью в МБ/с.

== Тесты (vitest) ==
- vitest.config.ts с алиасами @shared / @renderer
- 23 теста, все зелёные:
  * format.test.ts — formatCountdown, formatInterval (8 cases)
  * vdf.test.ts — parseVdf / stringifyVdf / round-trip (11 cases)
  * types.test.ts — DEFAULT_SETTINGS, SAMPLE_EXERCISES sanity (4)
- npm scripts: test (watch), test:run (CI)

== CI/CD (Gitea Actions) ==
- .gitea/workflows/ci.yml — на push/PR: typecheck + тесты + smoke-сборка
- .gitea/workflows/release.yml — на тег v*.*.*: сборка NSIS + Gitea release

== Локальный релизный скрипт ==
- scripts/release.ps1 — один скрипт от бампа версии до публикации
  через Gitea API (params: -Bump patch/minor/major, -Version, -DryRun)
- npm run release — обёртка
- RELEASING.md — полная инструкция

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 20:32:59 +07:00

147 lines
7.3 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.
# Релиз и автообновления
Документ описывает три способа выпустить новую версию. Все опираются на
один и тот же артефакт — NSIS-инсталлятор `Exercise-Reminder-Setup-X.Y.Z.exe`,
который сам решает: устанавливать заново или обновлять существующую копию.
## TL;DR
```pwsh
$env:GITEA_TOKEN = '<token из Gitea Settings → Applications>'
npm run release -- -Bump patch # 0.2.0 → 0.2.1
# или
npm run release -- -Version 0.3.0
```
Скрипт сделает всё сам: бамп версии, коммит, тег, push, тесты, сборка
инсталлятора, создание Gitea release с заметками из коммитов, загрузка
артефактов.
После публикации релиза установленные у пользователей копии в течение
~6 часов проверят `latest.yml` на Gitea и предложат обновление через UI.
---
## Как работает auto-update
1. На каждом релизе вместе с `.exe` публикуется `latest.yml`
манифест с версией, размером, sha512 хешем.
2. Приложение (через `electron-updater`) каждые 6 часов делает HTTP
GET на `<gitea>/AnRil/laude/releases/download/v<current>/latest.yml`.
3. Если версия в манифесте выше текущей — статус становится
`available`, в Settings → Обновления появляется кнопка «Скачать».
4. После скачивания — статус `downloaded`, кнопка «Перезапустить».
5. При перезапуске NSIS установщик из дельты или полный накатывается
поверх существующей инсталляции. Данные в `%APPDATA%\Exercise Reminder\`
сохраняются.
**Важно:** репозиторий `laude` приватный. Чтобы auto-update работал на
машинах конечных пользователей, либо:
- сделать репозиторий публичным, либо
- сделать публичными только релизы (Gitea: Release Settings),
- либо подписывать запросы токеном (нужен код в `updater.ts`,
использующий `autoUpdater.requestHeaders`).
## Способ 1 — скрипт релиза (рекомендованный сейчас)
Самый прямой путь, не зависит от Gitea Actions runners.
```pwsh
# Один раз — получить токен в Gitea (Settings → Applications)
# и сохранить в переменную окружения. Право — write:repository.
[Environment]::SetEnvironmentVariable('GITEA_TOKEN', '<token>', 'User')
# Релиз
npm run release -- -Bump patch # patch (0.2.0 → 0.2.1)
npm run release -- -Bump minor # minor (0.2.0 → 0.3.0)
npm run release -- -Bump major # major (0.2.0 → 1.0.0)
npm run release -- -Version 1.2.3 # точная версия
npm run release -- -DryRun # посмотреть план без действий
```
Что делает скрипт:
1. Проверяет что нет незакоммиченных изменений
2. Бампит версию в `package.json`, коммитит
3. Прогоняет `npm run typecheck` и `npm run test:run`
4. Собирает `npm run dist` (NSIS + блокмап + latest.yml)
5. Создаёт тег `vX.Y.Z`, пушит main и тег в origin
6. Через Gitea API создаёт release с заметками из git log
7. Загружает три файла как assets: `.exe`, `.exe.blockmap`, `latest.yml`
## Способ 2 — Gitea Actions (если есть runners)
Workflows лежат в `.gitea/workflows/`:
- **`ci.yml`** — на push в main и на PR. Запускает typecheck +
unit-тесты + smoke-сборку (без NSIS). Кладёт распакованную сборку
как artifact на 7 дней.
- **`release.yml`** — на push тега `v*.*.*`. Сверяет тег с версией
в `package.json`, прогоняет тесты, собирает NSIS-инсталлятор,
создаёт Gitea release с заметками, загружает артефакты.
Чтобы release workflow работал — в репозитории нужен secret
`GITEA_TOKEN` (Gitea Repo Settings → Secrets). Этот же токен может быть
переиспользован из `Способа 1`.
Для запуска release workflow:
```bash
git tag v0.3.0
git push origin v0.3.0
```
## Способ 3 — руками
Если что-то сломалось в автоматизации:
```pwsh
npm run typecheck
npm run test:run
npm run dist
# В release/ появятся:
# Exercise-Reminder-Setup-X.Y.Z.exe
# Exercise-Reminder-Setup-X.Y.Z.exe.blockmap
# latest.yml
```
Затем в Gitea UI: Releases → Draft new release → загрузить три файла.
## Тестирование auto-update
Удобный способ проверить, что цикл работает:
1. Релизнуть `0.x.0` через `npm run release`.
2. Установить полученный `.exe` на машину.
3. Релизнуть `0.x.1` (любой бамп).
4. На установленной копии открыть Settings → Обновления → Проверить.
Должно показать «Доступно обновление v0.x.1».
5. Скачать → Перезапустить → проверить версию в окне «О программе»
(или в Settings).
Для dev-режима (`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. Откатить bump-коммит: `git revert <hash>` или `git reset --hard HEAD~1`
(если ещё не пушили дальше).
4. Релизнуть тот же номер заново — auto-updater на клиентах увидит
тот же манифест и не предложит обновление (если sha512 совпадёт).
Если содержание поменялось — увидит и предложит обновиться. На
практике лучше выпустить hotfix-патч `X.Y.Z+1`, чем переписывать
существующий релиз.
## Что попадает в установщик
См. `build` секцию `package.json`:
- `out/**/*` — собранный код (main + preload + renderer)
- `resources/**/*` — иконки
Никаких node_modules, исходников, тестов, README — `electron-builder`
сам распаковывает и упаковывает только необходимое.