Skip to content

Commit d947550

Browse files
Resolve desktop artifact version from HEAD semver tags
1 parent 35721d9 commit d947550

2 files changed

Lines changed: 73 additions & 1 deletion

File tree

scripts/build-desktop-artifact.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { assert, it } from "@effect/vitest";
33
import { ConfigProvider, Effect, Option } from "effect";
44

55
import {
6+
resolveDesktopArtifactVersion,
67
resolveBuildOptions,
78
resolveDesktopBuildIconAssets,
89
resolveDesktopProductName,
@@ -23,6 +24,28 @@ it.layer(NodeServices.layer)("build-desktop-artifact", (it) => {
2324
assert.equal(resolveDesktopProductName("0.0.17-nightly.20260413.42"), "T3 Code (Nightly)");
2425
});
2526

27+
it("resolves explicit desktop artifact versions before HEAD tags", () => {
28+
assert.equal(resolveDesktopArtifactVersion("9.9.9", ["v1.2.3"], "0.0.22"), "9.9.9");
29+
});
30+
31+
it("falls back to the server package version when HEAD has no exact semver tags", () => {
32+
assert.equal(
33+
resolveDesktopArtifactVersion(undefined, ["release-1.2.3", "1.2", "1.2.3-dev+"], "0.0.22"),
34+
"0.0.22",
35+
);
36+
});
37+
38+
it("strips a leading v from exact semver tags on HEAD", () => {
39+
assert.equal(resolveDesktopArtifactVersion(undefined, ["v1.2.3"], "0.0.22"), "1.2.3");
40+
});
41+
42+
it("resolves multiple HEAD semver tags deterministically", () => {
43+
assert.equal(
44+
resolveDesktopArtifactVersion(undefined, ["v1.2.4", "1.2.3", "not-a-version"], "0.0.22"),
45+
"1.2.4",
46+
);
47+
});
48+
2649
it("switches desktop packaging icons to the nightly artwork for nightly versions", () => {
2750
assert.deepStrictEqual(resolveDesktopBuildIconAssets("0.0.17"), {
2851
macIconPng: BRAND_ASSET_PATHS.productionMacIconPng,

scripts/build-desktop-artifact.ts

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,31 @@ const resolveGitCommitHash = Effect.fn("resolveGitCommitHash")(function* (repoRo
150150
return hash.toLowerCase();
151151
});
152152

153+
const resolveGitHeadTags = Effect.fn("resolveGitHeadTags")(function* (repoRoot: string) {
154+
const result = yield* spawnAndCollectOutput(
155+
ChildProcess.make("git", ["tag", "--points-at", "HEAD"], {
156+
cwd: repoRoot,
157+
}),
158+
).pipe(
159+
Effect.catch(() =>
160+
Effect.succeed({
161+
stdout: "",
162+
stderr: "",
163+
exitCode: 1,
164+
}),
165+
),
166+
);
167+
168+
if (result.exitCode !== 0) {
169+
return [];
170+
}
171+
172+
return result.stdout
173+
.split(/\r?\n/)
174+
.map((tag) => tag.trim())
175+
.filter((tag) => tag.length > 0);
176+
});
177+
153178
const resolvePythonForNodeGyp = Effect.fn("resolvePythonForNodeGyp")(function* () {
154179
const fs = yield* FileSystem.FileSystem;
155180
const path = yield* Path.Path;
@@ -532,6 +557,26 @@ export function resolveDesktopUpdateChannel(version: string): "latest" | "nightl
532557
return /-nightly\.\d{8}\.\d+$/.test(version) ? "nightly" : "latest";
533558
}
534559

560+
const ExactSemverTagPattern =
561+
/^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
562+
563+
export function resolveDesktopArtifactVersion(
564+
explicitVersion: string | undefined,
565+
headTags: ReadonlyArray<string>,
566+
fallbackVersion: string,
567+
): string {
568+
if (explicitVersion) {
569+
return explicitVersion;
570+
}
571+
572+
const headSemverVersions = headTags
573+
.filter((tag) => ExactSemverTagPattern.test(tag))
574+
.map((tag) => tag.replace(/^v/, ""))
575+
.toSorted((a, b) => a.localeCompare(b, "en"));
576+
577+
return headSemverVersions.at(-1) ?? fallbackVersion;
578+
}
579+
535580
export function resolveDesktopBuildIconAssets(version: string): DesktopBuildIconAssets {
536581
if (resolveDesktopUpdateChannel(version) === "nightly") {
537582
return {
@@ -710,7 +755,11 @@ const buildDesktopArtifact = Effect.fn("buildDesktopArtifact")(function* (
710755
}),
711756
});
712757

713-
const appVersion = options.version ?? serverPackageJson.version;
758+
const appVersion = resolveDesktopArtifactVersion(
759+
options.version,
760+
yield* resolveGitHeadTags(repoRoot),
761+
serverPackageJson.version,
762+
);
714763
const iconAssets = resolveDesktopBuildIconAssets(appVersion);
715764
const commitHash = yield* resolveGitCommitHash(repoRoot);
716765
const mkdir = options.keepStage ? fs.makeTempDirectory : fs.makeTempDirectoryScoped;

0 commit comments

Comments
 (0)