From 5a0162d4aaa967da123beab3caaad9fe895b1d91 Mon Sep 17 00:00:00 2001 From: EfeDurmaz16 Date: Sat, 18 Apr 2026 23:33:32 +0300 Subject: [PATCH] fix(release): use v tag format for nightly releases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nightly releases were being tagged as 'nightly-v' (e.g. 'nightly-v0.0.21-nightly.20260417.58'). This tag is not valid semver because the 'nightly-v' prefix does not match semver's leading (optional 'v' + digit) grammar. electron-updater's GitHubProvider relies on the 'semver' package in two places when resolving updates from the releases.atom feed: 1. Channel matching (providers/GitHubProvider.js:68): const hrefChannel = semver.prerelease(hrefTag)?.[0] || null; With 'channel = nightly' and allowPrerelease = true, a release is only picked when its tag parses as a semver prerelease whose first identifier equals 'nightly'. semver.prerelease('nightly-v...') is null, so no nightly release ever matches and the updater throws 'No published versions on GitHub' (#2181). 2. Release notes (providers/GitHubProvider.js:189): const versionRelease = /\/tag\/v?([^/]+)$/.exec(...)[1]; if (semver.valid(versionRelease) && ...) { ... } Same reason: the remainder after stripping an optional 'v' must be valid semver, which 'nightly-v...' is not. Dropping the 'nightly-' prefix yields 'v-nightly..', which IS valid semver with prerelease identifier 'nightly' — exactly the format electron-updater expects for a custom channel. Stable tags remain 'v' and are unaffected. Changes: - scripts/resolve-nightly-release.ts: emit 'v' instead of 'nightly-v'. - scripts/resolve-nightly-release.test.ts, scripts/release-smoke.ts: update fixtures for the new tag. - scripts/resolve-previous-release-tag.ts: - parseStableTag now rejects tags whose first prerelease identifier is 'nightly' (new nightly tags also start with 'v', so the stable resolver has to exclude them explicitly). - parseNightlyTag accepts both the new 'v' format and the legacy 'nightly-v' format so release-note diffs against the last published nightly keep working across the transition. - .github/workflows/release.yml: - last_nightly_tag lookup now matches 'v*-nightly.*' in addition to legacy 'nightly-v*'. - The push-tags trigger excludes 'v*-nightly.*' so the new nightly tags don't accidentally re-trigger the stable release path. Existing 'nightly-v*' tags stay in the repo as inert history; no retagging is performed. Nightly users affected by #2181 currently cannot update at all, so there is no update-path regression — only forward progress. Closes #2181 --- .github/workflows/release.yml | 3 ++- scripts/release-smoke.ts | 2 +- scripts/resolve-nightly-release.test.ts | 2 +- scripts/resolve-nightly-release.ts | 2 +- scripts/resolve-previous-release-tag.ts | 12 ++++++++++-- 5 files changed, 15 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 25b4ac213c1..366a6b4de3c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,7 @@ on: push: tags: - "v*.*.*" + - "!v*-nightly.*" schedule: - cron: "0 */3 * * *" workflow_dispatch: @@ -41,7 +42,7 @@ jobs: - id: check name: Compare HEAD to last nightly tag run: | - last_nightly_tag=$(git tag --list 'nightly-v*' --sort=-creatordate | head -n 1) + last_nightly_tag=$(git tag --list 'v*-nightly.*' 'nightly-v*' --sort=-creatordate | head -n 1) if [[ -z "$last_nightly_tag" ]]; then echo "No previous nightly tag found. Proceeding with release." echo "has_changes=true" >> "$GITHUB_OUTPUT" diff --git a/scripts/release-smoke.ts b/scripts/release-smoke.ts index 41f948c6851..362771d12eb 100644 --- a/scripts/release-smoke.ts +++ b/scripts/release-smoke.ts @@ -220,7 +220,7 @@ try { ); assertContains( nightlyReleaseMetadata, - "tag=nightly-v9.9.10-nightly.20260413.321", + "tag=v9.9.10-nightly.20260413.321", "Expected nightly metadata to contain the derived nightly tag.", ); assertContains( diff --git a/scripts/resolve-nightly-release.test.ts b/scripts/resolve-nightly-release.test.ts index 56358d6c142..82b25737a58 100644 --- a/scripts/resolve-nightly-release.test.ts +++ b/scripts/resolve-nightly-release.test.ts @@ -24,7 +24,7 @@ it("derives nightly metadata including the short commit sha in the release name" { baseVersion: "9.9.10", version: "9.9.10-nightly.20260413.321", - tag: "nightly-v9.9.10-nightly.20260413.321", + tag: "v9.9.10-nightly.20260413.321", name: "T3 Code Nightly 9.9.10-nightly.20260413.321 (abcdef123456)", shortSha: "abcdef123456", }, diff --git a/scripts/resolve-nightly-release.ts b/scripts/resolve-nightly-release.ts index 4a92ef63aed..5f9413db208 100644 --- a/scripts/resolve-nightly-release.ts +++ b/scripts/resolve-nightly-release.ts @@ -54,7 +54,7 @@ export const resolveNightlyReleaseMetadata = ( return { baseVersion, version, - tag: `nightly-v${version}`, + tag: `v${version}`, name: `T3 Code Nightly ${version} (${shortSha})`, shortSha, }; diff --git a/scripts/resolve-previous-release-tag.ts b/scripts/resolve-previous-release-tag.ts index 93f932821ff..5f2ef1316b2 100644 --- a/scripts/resolve-previous-release-tag.ts +++ b/scripts/resolve-previous-release-tag.ts @@ -75,11 +75,17 @@ const parseStableTag = (tag: string): StableVersion | undefined => { const [, major, minor, patch, prerelease] = match; if (!major || !minor || !patch) return undefined; + const prereleaseIdentifiers = prerelease ? prerelease.split(".") : []; + // Nightly tags also start with `v` and carry a `nightly.*` prerelease + // identifier. They must not be considered stable candidates when resolving + // the previous stable tag. + if (prereleaseIdentifiers[0] === "nightly") return undefined; + return { major: Number(major), minor: Number(minor), patch: Number(patch), - prerelease: prerelease ? prerelease.split(".") : [], + prerelease: prereleaseIdentifiers, }; }; @@ -92,7 +98,9 @@ const compareNightlyVersions = (left: NightlyVersion, right: NightlyVersion): nu }; const parseNightlyTag = (tag: string): NightlyVersion | undefined => { - const match = /^nightly-v(\d+)\.(\d+)\.(\d+)-nightly\.(\d{8})\.(\d+)$/.exec(tag); + // Accept both the current `v` format and the legacy `nightly-v` + // format so release note diffs keep working across the tag-format transition. + const match = /^(?:nightly-)?v(\d+)\.(\d+)\.(\d+)-nightly\.(\d{8})\.(\d+)$/.exec(tag); if (!match) return undefined; const [, major, minor, patch, date, runNumber] = match;