diff --git a/.github/workflows/publish-packages.yml b/.github/workflows/publish-packages.yml index 5f9d765224..c31586b755 100644 --- a/.github/workflows/publish-packages.yml +++ b/.github/workflows/publish-packages.yml @@ -47,7 +47,7 @@ jobs: TAG="${{ steps.version.outputs.tag }}" ASSETS=( - "${PRODUCT_NAME}_${VERSION}_aarch64.dmg" + "${PRODUCT_NAME}_${VERSION}_arm64.dmg" "${PRODUCT_NAME}_${VERSION}_x64.dmg" "${PRODUCT_NAME}_${VERSION}_x64-setup.exe" "${PRODUCT_NAME}_${VERSION}_arm64-setup.exe" @@ -83,7 +83,7 @@ jobs: } echo "SHA256 hashes:" - compute_hash "artifacts/${PRODUCT_NAME}_${VERSION}_aarch64.dmg" "sha_dmg_arm64" + compute_hash "artifacts/${PRODUCT_NAME}_${VERSION}_arm64.dmg" "sha_dmg_arm64" compute_hash "artifacts/${PRODUCT_NAME}_${VERSION}_x64.dmg" "sha_dmg_x64" compute_hash "artifacts/${PRODUCT_NAME}_${VERSION}_x64-setup.exe" "sha_exe_x64" compute_hash "artifacts/${PRODUCT_NAME}_${VERSION}_arm64-setup.exe" "sha_exe_arm64" @@ -104,7 +104,7 @@ jobs: cat > Casks/dbx.rb <<'RUBY_EOF' cask "dbx" do - arch arm: "aarch64", intel: "x64" + arch arm: "arm64", intel: "x64" version "__VERSION__" sha256 arm: "__SHA_ARM64__", diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e9dd00a55e..233933f4f4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -122,14 +122,20 @@ jobs: fail-fast: false matrix: include: + # assetNamePattern renames every bundle artifact of a matrix leg, so + # it is set only on aarch64 legs (aarch64 -> arm64). x64 legs leave + # it empty and keep the default Tauri CLI names (x64.dmg, amd64 + # deb/rpm/AppImage) used by downloadLinks and package consumers. - platform: macos-latest target: aarch64-apple-darwin + asset_pattern: "DBX_[version]_arm64[setup][ext]" - platform: macos-15-intel target: x86_64-apple-darwin - platform: ubuntu-22.04 target: x86_64-unknown-linux-gnu - platform: ubuntu-22.04-arm target: aarch64-unknown-linux-gnu + asset_pattern: "DBX_[version]_arm64[setup][ext]" runs-on: ${{ matrix.platform }} env: @@ -268,6 +274,8 @@ jobs: with: tagName: ${{ github.ref_name }} releaseDraft: true + # Empty on x64 legs: tauri-action then keeps the default Tauri CLI names. + assetNamePattern: ${{ matrix.asset_pattern }} args: --target ${{ matrix.target }} - name: Verify AppImage input methods @@ -412,6 +420,8 @@ jobs: with: tagName: ${{ github.ref_name }} releaseDraft: true + # No assetNamePattern: the default Tauri CLI names already produce + # DBX_[version]_x64/arm64-setup.exe and keep the _en-US.msi names. args: --target ${{ matrix.target }} --config src-tauri/tauri.vsign.conf.json - name: Verify Windows bundles @@ -445,7 +455,7 @@ jobs: $version = "${env:GITHUB_REF_NAME}".TrimStart("v") $arch = "${{ matrix.arch }}" $bundleDir = "target/${{ matrix.target }}/release/bundle/nsis" - $offlineName = "DBX_${version}_${arch}-webview2-offline-setup.exe" + $offlineName = "DBX_${version}_${arch}-offline-setup.exe" $before = @{} if (Test-Path $bundleDir) { @@ -638,7 +648,7 @@ jobs: run: | $version = "${env:GITHUB_REF_NAME}".TrimStart("v") $bundleDir = "target/x86_64-win7-windows-msvc/release/bundle/nsis" - $offlineName = "DBX_${version}_x64-win7-server2012r2-webview2-109-offline-setup.exe" + $offlineName = "DBX_${version}_x64-win7-server2012r2-offline-setup.exe" $checksumName = "${offlineName}.sha256" $cargoMetadata = cargo metadata --no-deps --format-version 1 | ConvertFrom-Json $appVersion = ($cargoMetadata.packages | Where-Object { $_.name -eq "dbx" } | Select-Object -First 1).version diff --git a/apps/desktop/src/lib/__tests__/windowsInstallerTemplate.spec.ts b/apps/desktop/src/lib/__tests__/windowsInstallerTemplate.spec.ts index 31b5e222a9..3482bbc911 100644 --- a/apps/desktop/src/lib/__tests__/windowsInstallerTemplate.spec.ts +++ b/apps/desktop/src/lib/__tests__/windowsInstallerTemplate.spec.ts @@ -25,7 +25,7 @@ describe("Windows offline installer template", () => { expect(template).toContain("${If} ${IsWin7}"); expect(template).toContain("${OrIf} ${IsWin2012R2}"); expect(template).toContain('MessageBox MB_ICONSTOP|MB_YESNO|MB_DEFBUTTON1 "$(dbxWin7InstallerRequired)" IDYES dbx_open_win7_installer'); - expect(template).toContain("https://dl.dbxio.com/releases/v${VERSION}/DBX_${VERSION}_x64-win7-server2012r2-webview2-109-offline-setup.exe?v=${VERSION}"); + expect(template).toContain("https://dl.dbxio.com/releases/v${VERSION}/DBX_${VERSION}_x64-win7-server2012r2-offline-setup.exe?v=${VERSION}"); expect(template).toContain("SetErrorLevel 1633"); expect(template).toContain("${OrIf} $PassiveMode = 1"); }); diff --git a/docs/lib/downloadLinks.test.ts b/docs/lib/downloadLinks.test.ts index b2745c2c56..7133fea04c 100644 --- a/docs/lib/downloadLinks.test.ts +++ b/docs/lib/downloadLinks.test.ts @@ -36,7 +36,7 @@ test("Windows downloads include standard, offline, and Windows 7 installers", () driverLinkLabel: "数据库离线驱动", descriptionSuffix: undefined, badge: "内网", - href: "https://dl.dbxio.com/releases/v0.5.82/DBX_0.5.82_x64-webview2-offline-setup.exe?v=0.5.82", + href: "https://dl.dbxio.com/releases/v0.5.82/DBX_0.5.82_x64-offline-setup.exe?v=0.5.82", }, { id: "windows-7-offline", @@ -46,7 +46,7 @@ test("Windows downloads include standard, offline, and Windows 7 installers", () driverLinkLabel: "数据库离线驱动", descriptionSuffix: undefined, badge: "旧系统", - href: "https://dl.dbxio.com/releases/v0.5.82/DBX_0.5.82_x64-win7-server2012r2-webview2-109-offline-setup.exe?v=0.5.82", + href: "https://dl.dbxio.com/releases/v0.5.82/DBX_0.5.82_x64-win7-server2012r2-offline-setup.exe?v=0.5.82", }, ], ); diff --git a/docs/lib/downloadLinks.ts b/docs/lib/downloadLinks.ts index 8f1c4db410..72330aa3de 100644 --- a/docs/lib/downloadLinks.ts +++ b/docs/lib/downloadLinks.ts @@ -39,7 +39,7 @@ const downloadArtifacts: DownloadArtifact[] = [ id: "macos-arm", iconId: "macos-arm", labels: { en: "For macOS (Apple Silicon)", cn: "适用于 macOS (Apple Silicon)" }, - suffix: "aarch64.dmg", + suffix: "arm64.dmg", }, { id: "macos-intel", @@ -62,7 +62,7 @@ const downloadArtifacts: DownloadArtifact[] = [ descriptions: { en: "Includes WebView2 offline runtime · Does not include", cn: "内置 WebView2 离线运行库 · 不含" }, driverLinkLabels: { en: "offline database drivers", cn: "数据库离线驱动" }, badges: { en: "Intranet", cn: "内网" }, - suffix: "x64-webview2-offline-setup.exe", + suffix: "x64-offline-setup.exe", }, { id: "windows-7-offline", @@ -71,7 +71,7 @@ const downloadArtifacts: DownloadArtifact[] = [ descriptions: { en: "Includes WebView2 offline runtime · Does not include", cn: "内置 WebView2 离线运行库 · 不含" }, driverLinkLabels: { en: "offline database drivers", cn: "数据库离线驱动" }, badges: { en: "Legacy", cn: "旧系统" }, - suffix: "x64-win7-server2012r2-webview2-109-offline-setup.exe", + suffix: "x64-win7-server2012r2-offline-setup.exe", }, { id: "linux", @@ -83,7 +83,7 @@ const downloadArtifacts: DownloadArtifact[] = [ id: "linux-arm", iconId: "linux-arm", labels: { en: "For Linux ARM64", cn: "适用于 Linux ARM64" }, - suffix: "aarch64.AppImage", + suffix: "arm64.AppImage", }, { id: "linux-browser", diff --git a/scripts/release.mjs b/scripts/release.mjs index 9c2bd0cbd2..a3e2dd279b 100644 --- a/scripts/release.mjs +++ b/scripts/release.mjs @@ -362,15 +362,19 @@ function validateRollbackRelease(rollbackRelease, latestRelease) { } const version = formatVersion(rollbackVersion); + // Rollback targets may predate the aarch64 -> arm64 dmg rename, so either + // asset name satisfies the Apple Silicon requirement. const requiredAssets = [ - "latest.json", - `DBX_${version}_aarch64.dmg`, - `DBX_${version}_x64.dmg`, - `DBX_${version}_x64-setup.exe`, - `DBX_${version}_arm64-setup.exe`, + ["latest.json"], + [`DBX_${version}_arm64.dmg`, `DBX_${version}_aarch64.dmg`], + [`DBX_${version}_x64.dmg`], + [`DBX_${version}_x64-setup.exe`], + [`DBX_${version}_arm64-setup.exe`], ]; const assetNames = new Set(rollbackRelease.assets.map((asset) => asset.name)); - const missingAssets = requiredAssets.filter((asset) => !assetNames.has(asset)); + const missingAssets = requiredAssets + .filter((candidates) => !candidates.some((asset) => assetNames.has(asset))) + .map((candidates) => candidates.join(" or ")); if (missingAssets.length > 0) { fail(`Rollback target ${rollbackRelease.tagName} is missing required distribution assets: ${missingAssets.join(", ")}`); } diff --git a/scripts/release.test.mjs b/scripts/release.test.mjs index bbb255b12c..5f648c7907 100644 --- a/scripts/release.test.mjs +++ b/scripts/release.test.mjs @@ -41,7 +41,7 @@ function createMockGh() { " const version = tagName.slice(1);", " const assets = [", ' "latest.json",', - ' "DBX_" + version + "_aarch64.dmg",', + ' "DBX_" + version + "_" + (process.env.MOCK_ARM64_DMG_ARCH || "arm64") + ".dmg",', ' "DBX_" + version + "_x64.dmg",', ' "DBX_" + version + "_x64-setup.exe",', ' "DBX_" + version + "_arm64-setup.exe",', @@ -100,6 +100,33 @@ test("rollback rejects a target that is not older than latest", () => { assert.match(result.stderr, /must be older than the current latest release v0\.5\.64/); }); +test("rollback accepts pre-rename releases that ship the aarch64 dmg asset", () => { + const mockBin = createMockGh(); + const logPath = join(mockBin, "gh.log"); + const result = runRelease(["rollback", "v0.5.63", "--yes", "--skip-fetch"], { + PATH: `${mockBin}:${process.env.PATH}`, + GH_LOG: logPath, + MOCK_LATEST_TAG: "v0.5.64", + MOCK_ARM64_DMG_ARCH: "aarch64", + }); + + assert.equal(result.status, 0, result.stderr); + const commands = readFileSync(logPath, "utf8").trim().split("\n"); + assert.equal(commands.length, 3); +}); + +test("rollback rejects a release missing both arm64 dmg asset names", () => { + const mockBin = createMockGh(); + const result = runRelease(["rollback", "v0.5.63", "--yes", "--skip-fetch"], { + PATH: `${mockBin}:${process.env.PATH}`, + MOCK_LATEST_TAG: "v0.5.64", + MOCK_ARM64_DMG_ARCH: "armv7", + }); + + assert.equal(result.status, 1); + assert.match(result.stderr, /missing required distribution assets: DBX_0\.5\.63_arm64\.dmg or DBX_0\.5\.63_aarch64\.dmg/); +}); + test("rollback rejects prerelease tag syntax", () => { const result = runRelease(["rollback", "v0.5.63-rc.1", "--dry-run", "--skip-fetch"]); @@ -133,7 +160,12 @@ test("Windows 7 release build does not use sccache", () => { assert.notEqual(start, -1); assert.notEqual(end, -1); - const win7Job = workflow.slice(start, end); + const win7Job = workflow + .slice(start, end) + // Ignore comments; the job itself documents why sccache is absent. + .split("\n") + .filter((line) => !line.trim().startsWith("#")) + .join("\n"); assert.doesNotMatch(win7Job, /RUSTC_WRAPPER|SCCACHE_|sccache/i); }); diff --git a/src-tauri/windows/nsis/installer.nsi b/src-tauri/windows/nsis/installer.nsi index bc51b79027..489df03c1b 100644 --- a/src-tauri/windows/nsis/installer.nsi +++ b/src-tauri/windows/nsis/installer.nsi @@ -546,7 +546,7 @@ Function .onInit Quit dbx_open_win7_installer: - ExecShell "open" "https://dl.dbxio.com/releases/v${VERSION}/DBX_${VERSION}_x64-win7-server2012r2-webview2-109-offline-setup.exe?v=${VERSION}" + ExecShell "open" "https://dl.dbxio.com/releases/v${VERSION}/DBX_${VERSION}_x64-win7-server2012r2-offline-setup.exe?v=${VERSION}" SetErrorLevel 1633 Quit ${EndIf}