Releasing VoiceStudio
Electron is the only maintained desktop distribution. Tauri ended at v0.5.3; its signed updater feeds and installers are immutable compatibility assets.
Credentials
Electron publication uses these GitHub Actions secrets:
ELECTRON_MACOS_CSC_LINKandELECTRON_MACOS_CSC_KEY_PASSWORDfor the Developer ID Application.p12certificate and its password.APPLE_ID,APPLE_APP_SPECIFIC_PASSWORD(not the Apple ID login password) andAPPLE_TEAM_IDfor macOS notarization and stapling.ELECTRON_WINDOWS_CSC_LINKandELECTRON_WINDOWS_CSC_KEY_PASSWORDfor Windows Authenticode signing. The macOS certificate cannot sign Windows apps.- The repository
GITHUB_TOKENfor draft creation and asset uploads. DOCKERHUB_USERNAMEandDOCKERHUB_TOKENfor the Docker Hub mirror.
The archived TAURI_SIGNING_PRIVATE_KEY* secrets are retained only so the final
Tauri release can be audited. Do not use .github/workflows/release.yml for a new
version. TAURI_SUNSET_TAG must continue to identify v0.5.3 so Electron releases
can copy the final signed latest.json and latest-user.json feeds unchanged.
Those feeds must always point to immutable v0.5.3 Tauri assets; old Tauri clients
must never receive an Electron installer.
Versioning
frontend/package.json is the single source of truth for the maintained app
version. Electron Builder reads it directly. Keep these active mirrors equal:
pyproject.tomlbackend/core/version.py(_FALLBACK_VERSION)
The archived Tauri manifests stay frozen at their final release. Do not bump or
rebuild them. tests/test_app_version.py enforces the active version contract.
Version bumps are manual and require owner approval. Until a bump is requested,
main may remain at the latest released version. For a release, bump the
canonical version and both maintained mirrors together, then tag that exact
version only after validation.
Before tagging
- Merge only after required CI and review are green.
- Run the artifact-only Electron rehearsal,
.github/workflows/electron-build.yml, and inspect all four outputs: Linux x64, Windows x64, macOS arm64, macOS x64. It first checks the setup screen, then installs and starts the managed Python runtime in a separate temporary profile on Linux, Windows and Apple Silicon. Intel Macs retain packaging/setup checks under their existing UI/remote-only contract. The local-runtime test downloads runtime packages, keeps model downloads disabled, verifies the live backend connection and clean shutdown, and removes the test profile. A setup-screen check alone is not evidence that runtime installation works. - Verify a packaged launch and managed backend startup on the changed platforms.
- Rename
## [Unreleased]inCHANGELOG.mdto## [X.Y.Z] — YYYY-MM-DD. Lead with the largest user-visible change, keep Highlights to 3–5 bullets, include migration steps and real screenshots when relevant, and verify human contributors and bug reporters from the tag comparison and included PRs. - Run
uv run pytest tests/test_app_version.py tests/test_changelog_style.py -q. - Confirm the version matches the intended tag.
Build a release draft
git tag vX.Y.Z
git push origin vX.Y.Z
The tag starts .github/workflows/electron-release.yml. It builds all four
platform targets, validates packaged startup and updater metadata, creates or
updates a draft, and uploads:
- Electron installers and platform-specific
electron-stable-*.ymlfeeds SHA256SUMS.txt- authored CHANGELOG release notes
- immutable copies of the final Tauri updater feeds for old clients
Tag pushes never publish. Inspect the draft and downloaded installers first.
If the workflow itself needs a fix after tagging, keep the tag immutable. Merge
and validate the workflow fix on main, then dispatch electron-release.yml
from main with release_tag=vX.Y.Z. Every build still checks out the exact tag;
only the workflow definition comes from main.
Publish
Dispatch electron-release.yml for the exact tag with publish=true. Signing
and notarization are required by default. The owner may explicitly set
allow_unsigned=true; the workflow then adds the installer-trust disclosure to
the release notes. Never select that exception without the owner's decision.
After publication, verify each maintained channel:
| Channel | Workflow | Verification |
|---|---|---|
| GitHub Release | electron-release.yml |
Four platform targets, updater feeds, checksums, CHANGELOG notes, retained v0.5.3 Tauri feeds |
| GHCR CUDA | docker.yml |
:X.Y.Z, :X.Y, :stable manifests |
| GHCR ROCm | docker.yml |
:X.Y.Z-rocm, :X.Y-rocm, :stable-rocm manifests |
| Docker Hub | docker.yml |
Matching CUDA/ROCm tags |
| Docker Hub overview | docker.yml |
Read the Update Docker Hub description step log; the step may continue after a 403 |
| Rolling containers | docker.yml on main |
:latest, :main, and :rocm timestamps move |
A missing channel is a release bug. There are no RC tags; previews source from
main, never a side branch. The Electron artifact workflow is the desktop
rehearsal channel; no Tauri or desktop-preview build is maintained.
Package requirements
Linux packages must carry the native helper's non-glibc libraries under
resources/native/lib. Packaging checks reject missing or host-resolved
libraries. AppImages use the static runtime, which needs no host libfuse2; test
the downloaded image on a clean host because build-runner libraries can hide
relocation errors.
Linux release AppImages include gh-releases-zsync update information and a
versioned .AppImage.zsync asset for AppImageUpdate/AppImageLauncher. Stable
images follow the latest stable GitHub release; previews follow the preview
release instead of downgrading to stable. The build uses readelf and
zsyncmake (Ubuntu package zsync) to embed this information before
regenerating electron-updater's blockmap and checksums; the existing in-app
updater still uses its separate channel manifest. Verify both update paths
against the final downloaded artifact, not the pre-publish build.
Electron update manifests use platform and architecture channels. Confirm every manifest names an uploaded installer, reports the tagged version, and matches the artifact bytes. Exercise at least one installed update hop before publication.
Signed Electron macOS releases require a paid Apple Developer identity and the
secrets above. A draft build without credentials can remain unsigned; a normal
publish refuses missing signing/notarization credentials and verifies both the
signature and stapled ticket. Do not accept allow_unsigned merely to close a
signing report. Tauri signing keys cannot sign Electron packages. Existing
artifact names, app IDs, data paths, and updater channels are compatibility
contracts.
Retry and rollback
Re-run failed jobs in the same workflow run when possible. The release job replaces only the current draft's Electron assets. It refuses to overwrite a published release.
Clients only accept newer versions. To roll back, fix or revert the code, choose a higher patch version with owner approval, test it, and publish that version. Do not move or recreate an existing tag.