diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cd7387e966..857d951d75 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -368,6 +368,10 @@ jobs: shopt -s nullglob found_windows_manifest=false for x64_manifest in release-assets/*-win-x64.yml; do + if [[ "$(basename "$x64_manifest")" == builder-debug-* ]]; then + continue + fi + arm64_manifest="${x64_manifest/-x64.yml/-arm64.yml}" output_manifest="${x64_manifest/-win-x64.yml/.yml}" if [[ ! -f "$arm64_manifest" ]]; then diff --git a/scripts/release-smoke.ts b/scripts/release-smoke.ts index 9c4a415106..0d95b4945d 100644 --- a/scripts/release-smoke.ts +++ b/scripts/release-smoke.ts @@ -1,5 +1,13 @@ import { execFileSync } from "node:child_process"; -import { cpSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"; +import { + cpSync, + existsSync, + mkdirSync, + mkdtempSync, + readFileSync, + rmSync, + writeFileSync, +} from "node:fs"; import { tmpdir } from "node:os"; import { dirname, join, resolve } from "node:path"; import { fileURLToPath } from "node:url"; @@ -70,12 +78,15 @@ releaseDate: '2026-03-08T10:36:07.540Z' return { arm64Path, x64Path }; } -function writeWindowsManifestFixtures(targetRoot: string): { arm64Path: string; x64Path: string } { +function writeWindowsManifestFixtures( + targetRoot: string, + channel: string, +): { arm64Path: string; x64Path: string } { const assetDirectory = resolve(targetRoot, "release-assets"); mkdirSync(assetDirectory, { recursive: true }); - const arm64Path = resolve(assetDirectory, "latest-win-arm64.yml"); - const x64Path = resolve(assetDirectory, "latest-win-x64.yml"); + const arm64Path = resolve(assetDirectory, `${channel}-win-arm64.yml`); + const x64Path = resolve(assetDirectory, `${channel}-win-x64.yml`); writeFileSync( arm64Path, @@ -112,12 +123,46 @@ releaseDate: '2026-03-08T10:36:07.540Z' return { arm64Path, x64Path }; } +function writeWindowsBuilderDebugFixtures(targetRoot: string): { + arm64Path: string; + x64Path: string; +} { + const assetDirectory = resolve(targetRoot, "release-assets"); + mkdirSync(assetDirectory, { recursive: true }); + + const arm64Path = resolve(assetDirectory, "builder-debug-win-arm64.yml"); + const x64Path = resolve(assetDirectory, "builder-debug-win-x64.yml"); + const debugFixture = `arm64: + firstOrDefaultFilePatterns: + - '**/*' +nsis: + script: |- + !include "example.nsh" +`; + + writeFileSync(arm64Path, debugFixture); + writeFileSync(x64Path, debugFixture); + + return { arm64Path, x64Path }; +} function assertContains(haystack: string, needle: string, message: string): void { if (!haystack.includes(needle)) { throw new Error(message); } } +function assertExists(path: string, message: string): void { + if (!existsSync(path)) { + throw new Error(message); + } +} + +function assertMissing(path: string, message: string): void { + if (existsSync(path)) { + throw new Error(message); + } +} + const tempRoot = mkdtempSync(join(tmpdir(), "t3-release-smoke-")); try { @@ -211,15 +256,52 @@ try { "Merged manifest is missing the x64 asset.", ); - const { arm64Path: winArm64Path, x64Path: winX64Path } = writeWindowsManifestFixtures(tempRoot); + const { arm64Path: winArm64Path, x64Path: winX64Path } = writeWindowsManifestFixtures( + tempRoot, + "latest", + ); + const mergedWindowsManifestPath = resolve(tempRoot, "release-assets/latest.yml"); + const { arm64Path: nightlyWinArm64Path, x64Path: nightlyWinX64Path } = + writeWindowsManifestFixtures(tempRoot, "nightly"); + const mergedNightlyWindowsManifestPath = resolve(tempRoot, "release-assets/nightly.yml"); + const { arm64Path: previewWinArm64Path, x64Path: previewWinX64Path } = + writeWindowsManifestFixtures(tempRoot, "preview"); + const mergedPreviewWindowsManifestPath = resolve(tempRoot, "release-assets/preview.yml"); + const { arm64Path: winDebugArm64Path, x64Path: winDebugX64Path } = + writeWindowsBuilderDebugFixtures(tempRoot); execFileSync( - process.execPath, + "bash", [ - resolve(repoRoot, "scripts/merge-update-manifests.ts"), - "--platform", - "win", - winArm64Path, - winX64Path, + "-lc", + ` + release_assets_dir=${JSON.stringify(resolve(tempRoot, "release-assets"))} + shopt -s nullglob + found_windows_manifest=false + for x64_manifest in "$release_assets_dir"/*-win-x64.yml; do + if [[ "$(basename "$x64_manifest")" == builder-debug-* ]]; then + continue + fi + + arm64_manifest="\${x64_manifest/-x64.yml/-arm64.yml}" + output_manifest="\${x64_manifest/-win-x64.yml/.yml}" + if [[ ! -f "$arm64_manifest" ]]; then + echo "Missing matching arm64 Windows manifest for $x64_manifest" >&2 + exit 1 + fi + + found_windows_manifest=true + node ${JSON.stringify(resolve(repoRoot, "scripts/merge-update-manifests.ts"))} --platform win \ + "$arm64_manifest" \ + "$x64_manifest" \ + "$output_manifest" + rm -f "$arm64_manifest" "$x64_manifest" + done + + if [[ "$found_windows_manifest" != true ]]; then + echo "No Windows updater manifests found to merge." >&2 + exit 1 + fi + `, ], { cwd: repoRoot, @@ -227,7 +309,7 @@ try { }, ); - const mergedWindowsManifest = readFileSync(winArm64Path, "utf8"); + const mergedWindowsManifest = readFileSync(mergedWindowsManifestPath, "utf8"); assertContains( mergedWindowsManifest, "T3-Code-9.9.9-smoke.0-arm64.exe", @@ -238,6 +320,57 @@ try { "T3-Code-9.9.9-smoke.0-x64.exe", "Merged Windows manifest is missing the x64 asset.", ); + const mergedNightlyWindowsManifest = readFileSync(mergedNightlyWindowsManifestPath, "utf8"); + assertContains( + mergedNightlyWindowsManifest, + "T3-Code-9.9.9-smoke.0-arm64.exe", + "Merged nightly Windows manifest is missing the arm64 asset.", + ); + assertContains( + mergedNightlyWindowsManifest, + "T3-Code-9.9.9-smoke.0-x64.exe", + "Merged nightly Windows manifest is missing the x64 asset.", + ); + const mergedPreviewWindowsManifest = readFileSync(mergedPreviewWindowsManifestPath, "utf8"); + assertContains( + mergedPreviewWindowsManifest, + "T3-Code-9.9.9-smoke.0-arm64.exe", + "Merged preview Windows manifest is missing the arm64 asset.", + ); + assertContains( + mergedPreviewWindowsManifest, + "T3-Code-9.9.9-smoke.0-x64.exe", + "Merged preview Windows manifest is missing the x64 asset.", + ); + assertMissing( + winArm64Path, + "Windows release smoke unexpectedly kept the arm64 updater manifest.", + ); + assertMissing(winX64Path, "Windows release smoke unexpectedly kept the x64 updater manifest."); + assertMissing( + nightlyWinArm64Path, + "Windows release smoke unexpectedly kept the nightly arm64 updater manifest.", + ); + assertMissing( + nightlyWinX64Path, + "Windows release smoke unexpectedly kept the nightly x64 updater manifest.", + ); + assertMissing( + previewWinArm64Path, + "Windows release smoke unexpectedly kept the preview arm64 updater manifest.", + ); + assertMissing( + previewWinX64Path, + "Windows release smoke unexpectedly kept the preview x64 updater manifest.", + ); + assertExists( + winDebugArm64Path, + "Windows release smoke unexpectedly removed the arm64 builder debug fixture.", + ); + assertExists( + winDebugX64Path, + "Windows release smoke unexpectedly removed the x64 builder debug fixture.", + ); console.log("Release smoke checks passed."); } finally {