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>
This commit is contained in:
146
RELEASING.md
Normal file
146
RELEASING.md
Normal file
@@ -0,0 +1,146 @@
|
||||
# Релиз и автообновления
|
||||
|
||||
Документ описывает три способа выпустить новую версию. Все опираются на
|
||||
один и тот же артефакт — 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`
|
||||
сам распаковывает и упаковывает только необходимое.
|
||||
Reference in New Issue
Block a user