authorgravatar for me@t3.ggTheo Browne <me@t3.gg> 2026-03-07 04:05:36-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-03-07 04:05:36-08:00
logb74c7a79abbfbb7f6e8c5c4affb20784cea2b11c
tree39ad7783d0b9f0b789d3032937992f0cbc065294
parentf772720d8c2a90448154271d7e4623f40cdf83fc
signature Signed by PGP key B5690EEEBB952194

Handle prerelease tags in GitHub release publishing (#344)

* Handle prerelease tags when publishing GitHub releases - Derive `is_prerelease` and `make_latest` from the version format in preflight - Mark suffixed versions (for example `1.2.3-alpha.1`) as prereleases - Keep only plain `X.Y.Z` releases marked as latest - Document prerelease/latest behavior in `docs/release.md` * Force desktop auto-updates to stable latest channel - set Electron updater channel to `latest` - disable prerelease and downgrade updates regardless of app version

3 files changed, 19 insertions(+), 2 deletions(-)

.github/workflows/release.yml+11-1
......@@ -22,6 +22,8 @@ jobs:
2222 outputs:
2323 version: ${{ steps.release_meta.outputs.version }}
2424 tag: ${{ steps.release_meta.outputs.tag }}
25 is_prerelease: ${{ steps.release_meta.outputs.is_prerelease }}
26 make_latest: ${{ steps.release_meta.outputs.make_latest }}
2527 ref: ${{ github.sha }}
2628 steps:
2729 - name: Checkout
......@@ -45,6 +47,13 @@ jobs:
4547
4648 echo "version=$version" >> "$GITHUB_OUTPUT"
4749 echo "tag=v$version" >> "$GITHUB_OUTPUT"
50 if [[ "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
51 echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
52 echo "make_latest=true" >> "$GITHUB_OUTPUT"
53 else
54 echo "is_prerelease=true" >> "$GITHUB_OUTPUT"
55 echo "make_latest=false" >> "$GITHUB_OUTPUT"
56 fi
4857
4958 - name: Setup Bun
5059 uses: oven-sh/setup-bun@v2
......@@ -260,7 +269,8 @@ jobs:
260269 target_commitish: ${{ needs.preflight.outputs.ref }}
261270 name: T3 Code v${{ needs.preflight.outputs.version }}
262271 generate_release_notes: true
263 make_latest: true
272 prerelease: ${{ needs.preflight.outputs.is_prerelease }}
273 make_latest: ${{ needs.preflight.outputs.make_latest }}
264274 files: |
265275 release-assets/*.dmg
266276 release-assets/*.zip
apps/desktop/src/main.ts+6-1
......@@ -58,6 +58,8 @@ const LOG_FILE_MAX_FILES = 10;
5858const APP_RUN_ID = Crypto.randomBytes(6).toString("hex");
5959const AUTO_UPDATE_STARTUP_DELAY_MS = 15_000;
6060const AUTO_UPDATE_POLL_INTERVAL_MS = 4 * 60 * 60 * 1000;
61const DESKTOP_UPDATE_CHANNEL = "latest";
62const DESKTOP_UPDATE_ALLOW_PRERELEASE = false;
6163
6264type DesktopUpdateErrorContext = DesktopUpdateState["errorContext"];
6365
......@@ -725,7 +727,10 @@ function configureAutoUpdater(): void {
725727
726728 autoUpdater.autoDownload = false;
727729 autoUpdater.autoInstallOnAppQuit = false;
728 autoUpdater.allowPrerelease = app.getVersion().includes("-");
730 // Keep alpha branding, but force all installs onto the stable update track.
731 autoUpdater.channel = DESKTOP_UPDATE_CHANNEL;
732 autoUpdater.allowPrerelease = DESKTOP_UPDATE_ALLOW_PRERELEASE;
733 autoUpdater.allowDowngrade = false;
729734 let lastLoggedDownloadMilestone = -1;
730735
731736 autoUpdater.on("checking-for-update", () => {
docs/release.md+2
......@@ -12,6 +12,8 @@ This document covers how to run desktop releases from one tag, first without sig
1212 - Linux `x64` AppImage
1313 - Windows `x64` NSIS installer
1414- Publishes one GitHub Release with all produced files.
15 - Versions with a suffix after `X.Y.Z` (for example `1.2.3-alpha.1`) are published as GitHub prereleases.
16 - Only plain `X.Y.Z` releases are marked as the repository's latest release.
1517- Includes Electron auto-update metadata (for example `latest*.yml` and `*.blockmap`) in release assets.
1618- Publishes the CLI package (`apps/server`, npm package `t3`) with OIDC trusted publishing.
1719- Signing is optional and auto-detected per platform from secrets.