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>
PS5.1 Get-Content -Raw without -Encoding utf8 reads in CP1251, mangling
non-ASCII like em-dash. Set-Content -Encoding utf8 writes a BOM that
breaks PostCSS / electron-builder reads of package.json.
Use .NET ReadAllText/WriteAllText with UTF8Encoding(false) to guarantee
roundtrip-safe UTF-8 without BOM.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The auto-update system used a per-version publish URL
(releases/download/v${version}), so each installed build only ever
checked its own release page for new versions. To deliver an update we
had to manually copy the new manifest into every old release — easy to
forget, and any half-uploaded state showed users red "check failed"
banners.
Architectural fix:
- New rolling 'update-channel' Gitea release. publish.url is now a
fixed path (.../releases/download/update-channel) that never moves.
- release.ps1 uploads each new build to three places:
1. vX.Y.Z (historical archive + changelog)
2. update-channel (what every client polls)
3. -BridgeTags (transition: also fill in old releases so users
still on those versions can find the new build)
- upload-release-assets.ps1 gains -AssetVersion to upload version-X.Y.Z
artifacts into a non-version tag (channel/bridge).
Resilience fixes for the updater itself:
- Hourly checks and the boot check now run in SILENT mode: network
errors don't promote to a red error state, they're logged and
retried on the next tick. Only user-initiated "Check now" surfaces
errors. This prevents the cascade of "Ошибка проверки" cards on
flaky networks or partial uploads.
- Boot check retries up to 3 times (30s/2m/5m backoff) before giving
up until the hourly tick.
- Track lastCheckedAt; "Up to date" subtitle now shows "checked Nm ago".
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Полная автоматизация релизного цикла.
== 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>