From 5b34ec2980f6fb0d2a203847c752d02838ca4e8f Mon Sep 17 00:00:00 2001 From: lucaronin Date: Sun, 26 Apr 2026 06:07:33 +0200 Subject: [PATCH] feat: publish intel mac builds --- .github/workflows/release-stable.yml | 62 ++++++++++++++++++- .github/workflows/release.yml | 47 +++++++++++++- docs/ABSTRACTIONS.md | 4 +- docs/ARCHITECTURE.md | 10 +-- ...al-architecture-macos-release-artifacts.md | 38 ++++++++++++ docs/adr/README.md | 3 +- src/utils/releaseDownloadPage.test.ts | 43 ++++++++++--- src/utils/releaseDownloadPage.ts | 54 ++++++++++++---- 8 files changed, 232 insertions(+), 29 deletions(-) create mode 100644 docs/adr/0083-dual-architecture-macos-release-artifacts.md diff --git a/.github/workflows/release-stable.yml b/.github/workflows/release-stable.yml index 24002767..f7349803 100644 --- a/.github/workflows/release-stable.yml +++ b/.github/workflows/release-stable.yml @@ -62,6 +62,8 @@ jobs: include: - arch: aarch64 target: aarch64-apple-darwin + - arch: x86_64 + target: x86_64-apple-darwin steps: - uses: actions/checkout@v4 @@ -497,6 +499,50 @@ jobs: - name: Download all artifacts uses: actions/download-artifact@v4 + - name: Normalize macOS release artifact names + run: | + normalize_macos_artifacts() { + local arch="$1" + local updater_dir="updater-${arch}" + local updater_file + updater_file=$(find "$updater_dir" -maxdepth 1 -name "*.app.tar.gz" -print -quit) + if [ -z "$updater_file" ]; then + echo "::error::Missing macOS updater artifact in ${updater_dir}" >&2 + return 1 + fi + + local sig_file="${updater_file}.sig" + if [ ! -f "$sig_file" ]; then + echo "::error::Missing macOS updater signature for ${updater_file}" >&2 + return 1 + fi + + local normalized_updater="${updater_dir}/Tolaria_${arch}.app.tar.gz" + local normalized_sig="${normalized_updater}.sig" + if [ "$updater_file" != "$normalized_updater" ]; then + mv "$updater_file" "$normalized_updater" + fi + if [ "$sig_file" != "$normalized_sig" ]; then + mv "$sig_file" "$normalized_sig" + fi + + local dmg_dir="dmg-${arch}" + local dmg_file + dmg_file=$(find "$dmg_dir" -maxdepth 1 -name "*.dmg" -print -quit) + if [ -z "$dmg_file" ]; then + echo "::error::Missing macOS DMG artifact in ${dmg_dir}" >&2 + return 1 + fi + + local normalized_dmg="${dmg_dir}/Tolaria_${arch}.dmg" + if [ "$dmg_file" != "$normalized_dmg" ]; then + mv "$dmg_file" "$normalized_dmg" + fi + } + + normalize_macos_artifacts aarch64 + normalize_macos_artifacts x86_64 + - name: Generate release notes run: | PREV_TAG=$(git tag --list 'stable-v*' --sort=-version:refname | grep -vx "${{ needs.version.outputs.tag }}" | head -n 1 || echo "") @@ -513,7 +559,7 @@ jobs: echo "---" echo "**Stable release — manually promoted from \`main\`**" echo "" - echo "**Includes macOS (Apple Silicon), Windows x64, and Linux x64 bundles**" + echo "**Includes macOS (Apple Silicon and Intel), Windows x64, and Linux x64 bundles**" echo "" echo "*Built from \`$(git rev-parse --short ${{ needs.version.outputs.tag }})\` on $(date -u +%Y-%m-%d)*" } > release_notes.md @@ -545,6 +591,12 @@ jobs: ARM_TARBALL=$(basename "$ARM_UPDATER_FILE") ARM_DMG=$(basename "$(find_required "dmg-aarch64/*.dmg")") + INTEL_SIG_FILE=$(find_required "updater-x86_64/*.app.tar.gz.sig") + INTEL_UPDATER_FILE="${INTEL_SIG_FILE%.sig}" + INTEL_SIG=$(cat "$INTEL_SIG_FILE") + INTEL_TARBALL=$(basename "$INTEL_UPDATER_FILE") + INTEL_DMG=$(basename "$(find_required "dmg-x86_64/*.dmg")") + LINUX_SIG_FILE=$(find_required "linux-x86_64-bundles/*/*.AppImage.sig" "linux-x86_64-bundles/*/*.AppImage.tar.gz.sig" "linux-x86_64-bundles/*/*.deb.sig" "linux-x86_64-bundles/*.AppImage.sig" "linux-x86_64-bundles/*.AppImage.tar.gz.sig" "linux-x86_64-bundles/*.deb.sig") LINUX_UPDATER_FILE="${LINUX_SIG_FILE%.sig}" LINUX_SIG=$(cat "$LINUX_SIG_FILE") @@ -568,6 +620,11 @@ jobs: "url": "https://github.com/${REPO}/releases/download/${TAG}/${ARM_TARBALL}", "dmg_url": "https://github.com/${REPO}/releases/download/${TAG}/${ARM_DMG}" }, + "darwin-x86_64": { + "signature": "${INTEL_SIG}", + "url": "https://github.com/${REPO}/releases/download/${TAG}/${INTEL_TARBALL}", + "dmg_url": "https://github.com/${REPO}/releases/download/${TAG}/${INTEL_DMG}" + }, "linux-x86_64": { "signature": "${LINUX_SIG}", "url": "https://github.com/${REPO}/releases/download/${TAG}/${LINUX_UPDATER}", @@ -595,6 +652,9 @@ jobs: dmg-aarch64/*.dmg updater-aarch64/*.app.tar.gz updater-aarch64/*.app.tar.gz.sig + dmg-x86_64/*.dmg + updater-x86_64/*.app.tar.gz + updater-x86_64/*.app.tar.gz.sig linux-x86_64-bundles/*.deb linux-x86_64-bundles/*.deb.sig linux-x86_64-bundles/*.AppImage diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2c54d475..cb16f29d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -121,6 +121,8 @@ jobs: include: - arch: aarch64 target: aarch64-apple-darwin + - arch: x86_64 + target: x86_64-apple-darwin steps: - uses: actions/checkout@v4 @@ -551,6 +553,37 @@ jobs: - name: Download all artifacts uses: actions/download-artifact@v4 + - name: Normalize macOS updater artifact names + run: | + normalize_updater() { + local arch="$1" + local artifact_dir="updater-${arch}" + local updater_file + updater_file=$(find "$artifact_dir" -maxdepth 1 -name "*.app.tar.gz" -print -quit) + if [ -z "$updater_file" ]; then + echo "::error::Missing macOS updater artifact in ${artifact_dir}" >&2 + return 1 + fi + + local sig_file="${updater_file}.sig" + if [ ! -f "$sig_file" ]; then + echo "::error::Missing macOS updater signature for ${updater_file}" >&2 + return 1 + fi + + local normalized_updater="${artifact_dir}/Tolaria_${arch}.app.tar.gz" + local normalized_sig="${normalized_updater}.sig" + if [ "$updater_file" != "$normalized_updater" ]; then + mv "$updater_file" "$normalized_updater" + fi + if [ "$sig_file" != "$normalized_sig" ]; then + mv "$sig_file" "$normalized_sig" + fi + } + + normalize_updater aarch64 + normalize_updater x86_64 + - name: Generate release notes run: | PREV_TAG=$(python3 <<'PY' @@ -587,7 +620,7 @@ jobs: echo "---" echo "**Alpha build — updated on every push to \`main\`**" echo "" - echo "**Includes macOS (Apple Silicon), Linux x64, and Windows x64 bundles**" + echo "**Includes macOS (Apple Silicon and Intel), Linux x64, and Windows x64 bundles**" echo "" echo "*Built from \`$(git rev-parse --short HEAD)\` on $(date -u +%Y-%m-%d)*" } > release_notes.md @@ -616,6 +649,11 @@ jobs: ARM_SIG=$(cat "$ARM_SIG_FILE") ARM_UPDATER=$(basename "$ARM_UPDATER_FILE") + INTEL_SIG_FILE=$(find_required "updater-x86_64/*.app.tar.gz.sig") + INTEL_UPDATER_FILE="${INTEL_SIG_FILE%.sig}" + INTEL_SIG=$(cat "$INTEL_SIG_FILE") + INTEL_UPDATER=$(basename "$INTEL_UPDATER_FILE") + LINUX_SIG_FILE=$(find_required "linux-x86_64-bundles/*/*.AppImage.sig" "linux-x86_64-bundles/*/*.AppImage.tar.gz.sig" "linux-x86_64-bundles/*/*.deb.sig" "linux-x86_64-bundles/*.AppImage.sig" "linux-x86_64-bundles/*.AppImage.tar.gz.sig" "linux-x86_64-bundles/*.deb.sig") LINUX_UPDATER_FILE="${LINUX_SIG_FILE%.sig}" LINUX_SIG=$(cat "$LINUX_SIG_FILE") @@ -639,6 +677,11 @@ jobs: "url": "https://github.com/${REPO}/releases/download/${TAG}/${ARM_UPDATER}", "download_url": "https://github.com/${REPO}/releases/download/${TAG}/${ARM_UPDATER}" }, + "darwin-x86_64": { + "signature": "${INTEL_SIG}", + "url": "https://github.com/${REPO}/releases/download/${TAG}/${INTEL_UPDATER}", + "download_url": "https://github.com/${REPO}/releases/download/${TAG}/${INTEL_UPDATER}" + }, "linux-x86_64": { "signature": "${LINUX_SIG}", "url": "https://github.com/${REPO}/releases/download/${TAG}/${LINUX_UPDATER}", @@ -665,6 +708,8 @@ jobs: files: | updater-aarch64/*.app.tar.gz updater-aarch64/*.app.tar.gz.sig + updater-x86_64/*.app.tar.gz + updater-x86_64/*.app.tar.gz.sig linux-x86_64-bundles/*.deb linux-x86_64-bundles/*.deb.sig linux-x86_64-bundles/*.AppImage diff --git a/docs/ABSTRACTIONS.md b/docs/ABSTRACTIONS.md index a4d526ed..0b44b7d9 100644 --- a/docs/ABSTRACTIONS.md +++ b/docs/ABSTRACTIONS.md @@ -706,6 +706,6 @@ Managed by `useSettings` hook and `SettingsPanel` component. `theme_mode` is ins - **`download_and_install_app_update`** — Channel-aware download/install with streamed progress events. ### CI/CD -- **`.github/workflows/release.yml`** — Alpha prereleases from every push to `main` using calendar-semver technical versions (`YYYY.M.D-alpha.N`) and clean `Alpha YYYY.M.D.N` release names. GitHub alpha tags zero-pad the prerelease sequence (`alpha-vYYYY.M.D-alpha.NNNN`) so GitHub release ordering stays chronological while the shipped app version remains `YYYY.M.D-alpha.N`. Publishes `alpha/latest.json` and refreshes the legacy `latest.json` / `latest-canary.json` aliases to the alpha feed. -- **`.github/workflows/release-stable.yml`** — Stable releases from `stable-vYYYY.M.D` tags. Publishes `stable/latest.json`, macOS Apple Silicon artifacts, Windows x64 installers/updater bundles, and Linux x86_64 `.deb` / AppImage artifacts. +- **`.github/workflows/release.yml`** — Alpha prereleases from every push to `main` using calendar-semver technical versions (`YYYY.M.D-alpha.N`) and clean `Alpha YYYY.M.D.N` release names. GitHub alpha tags zero-pad the prerelease sequence (`alpha-vYYYY.M.D-alpha.NNNN`) so GitHub release ordering stays chronological while the shipped app version remains `YYYY.M.D-alpha.N`. Publishes `alpha/latest.json` with macOS Apple Silicon/Intel, Linux x64, and Windows x64 updater entries, then refreshes the legacy `latest.json` / `latest-canary.json` aliases to the alpha feed. +- **`.github/workflows/release-stable.yml`** — Stable releases from `stable-vYYYY.M.D` tags. Publishes `stable/latest.json`, macOS Apple Silicon and Intel DMG/updater artifacts, Windows x64 installers/updater bundles, and Linux x86_64 `.deb` / AppImage artifacts. - **Beta cohorts** are handled in PostHog targeting only. There is no beta updater feed. diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 8efcf5b9..60033909 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -812,12 +812,13 @@ push to main → if stable already uses today, advance alpha to the next calendar day so semver still increases → build job: → pnpm install, stamp version, pnpm build, tauri build --target aarch64-apple-darwin --bundles app - → upload signed .app.tar.gz + .sig updater artifacts + → pnpm install, stamp version, pnpm build, tauri build --target x86_64-apple-darwin --bundles app + → upload signed Apple Silicon and Intel .app.tar.gz + .sig updater artifacts → build-windows job: → pnpm install, stamp version, tauri build --target x86_64-pc-windows-msvc --bundles nsis → upload NSIS installer, optional MSI artifacts, and signed Windows updater bundles → release job: - → generate alpha-latest.json + → generate alpha-latest.json with darwin-aarch64, darwin-x86_64, Linux, and Windows updater URLs → publish GitHub prerelease alpha-vYYYY.M.D-alpha.NNNN named Tolaria Alpha YYYY.M.D.N → pages job: → build static HTML release history page @@ -834,7 +835,8 @@ push stable-vYYYY.M.D tag → version job: validate YYYY.M.D from the tag → build job: → pnpm install, stamp version, pnpm build, tauri build --target aarch64-apple-darwin - → upload signed .app.tar.gz + .sig and .dmg artifacts + → pnpm install, stamp version, pnpm build, tauri build --target x86_64-apple-darwin + → upload signed Apple Silicon and Intel .app.tar.gz + .sig and .dmg artifacts → build-linux job: → pnpm install, stamp version, tauri build --target x86_64-unknown-linux-gnu --bundles deb,appimage → upload .deb, .AppImage, and signed Linux updater bundles @@ -842,7 +844,7 @@ push stable-vYYYY.M.D tag → pnpm install, stamp version, tauri build --target x86_64-pc-windows-msvc --bundles nsis → upload NSIS installer, optional MSI artifacts, and signed Windows updater bundles → release job: - → generate stable-latest.json with macOS, Linux, and Windows updater URLs plus platform-specific manual download URLs + → generate stable-latest.json with macOS Apple Silicon, macOS Intel, Linux, and Windows updater URLs plus platform-specific manual download URLs → publish GitHub release Tolaria YYYY.M.D → pages job: → publish stable/latest.json diff --git a/docs/adr/0083-dual-architecture-macos-release-artifacts.md b/docs/adr/0083-dual-architecture-macos-release-artifacts.md new file mode 100644 index 00000000..3d4a0470 --- /dev/null +++ b/docs/adr/0083-dual-architecture-macos-release-artifacts.md @@ -0,0 +1,38 @@ +--- +type: ADR +id: "0083" +title: "Dual-architecture macOS release artifacts" +status: active +date: 2026-04-26 +supersedes: "0080" +--- + +## Context + +ADR-0080 made Tolaria's desktop release pipeline cross-platform, but the macOS leg still shipped only Apple Silicon artifacts. That left Intel Mac users without a compatible build in both the alpha feed and stable releases, even though Tauri and Rust can produce `x86_64-apple-darwin` bundles from the same release workflow. + +The updater manifest also needs to distinguish macOS CPU architectures. A generic `darwin` or macOS-only entry would make it too easy for an Intel installation to see an Apple Silicon updater bundle, and browser user agents cannot reliably tell Apple Silicon Macs apart from Intel Macs. + +## Decision + +**Tolaria publishes macOS release artifacts for both Apple Silicon (`darwin-aarch64`) and Intel (`darwin-x86_64`) in every alpha and stable release.** + +- Alpha and stable workflows build the macOS matrix for `aarch64-apple-darwin` and `x86_64-apple-darwin`. +- Alpha manifests include signed updater tarballs for `darwin-aarch64` and `darwin-x86_64`. +- Stable manifests include both macOS updater tarballs and both manual DMG downloads, alongside the existing Windows x64 and Linux x86_64 entries. +- Release jobs normalize macOS artifact filenames with the architecture suffix before publishing so GitHub release assets stay unambiguous. +- The stable download page exposes separate Apple Silicon and Intel Mac links. When both Mac links exist, a generic macOS browser is not auto-redirected because user-agent architecture detection is unreliable. +- The cross-platform filename portability decisions from ADR-0080 remain in force. + +## Options considered + +- **Publish separate Apple Silicon and Intel Mac artifacts** (chosen): gives each updater client an architecture-specific manifest key and gives users explicit manual download links. Cons: doubles the macOS release matrix and signing/notarization surface. +- **Publish a universal macOS binary**: gives users one download, but requires lipo/re-sign/notarize coordination and reintroduces the artifact-combining complexity the release pipeline intentionally avoided. +- **Keep Apple Silicon-only macOS releases**: keeps CI cheaper, but leaves Intel Mac users unsupported and makes the release artifacts inconsistent with Tolaria's desktop support goals. + +## Consequences + +- macOS release jobs now run one matrix entry per CPU architecture. +- Release manifest consumers must treat `darwin-aarch64` and `darwin-x86_64` as distinct platform keys. +- Stable manual downloads show two Mac choices instead of pretending browser detection can select the right CPU architecture. +- Future macOS release changes must validate both updater and manual-download artifacts for both architectures. diff --git a/docs/adr/README.md b/docs/adr/README.md index c3baf684..c4196022 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -135,6 +135,7 @@ proposed → active → superseded | [0077](0077-concurrent-safe-vault-cache-replacement.md) | Concurrent-safe vault cache replacement | active | | [0078](0078-scoped-unsigned-fallback-for-app-managed-git-commits.md) | Scoped unsigned fallback for app-managed git commits | active | | [0079](0079-linux-window-chrome-and-menu-reuse.md) | Linux window chrome and menu reuse | active | -| [0080](0080-cross-platform-desktop-release-artifacts-and-portable-vault-names.md) | Cross-platform desktop release artifacts and portable vault names | active | +| [0080](0080-cross-platform-desktop-release-artifacts-and-portable-vault-names.md) | Cross-platform desktop release artifacts and portable vault names | superseded → [0083](0083-dual-architecture-macos-release-artifacts.md) | | [0081](0081-internal-light-dark-theme-runtime.md) | Internal light and dark theme runtime | active | | [0082](0082-markdown-durable-math-notes.md) | Markdown-durable math in notes | active | +| [0083](0083-dual-architecture-macos-release-artifacts.md) | Dual-architecture macOS release artifacts | active | diff --git a/src/utils/releaseDownloadPage.test.ts b/src/utils/releaseDownloadPage.test.ts index d01235f8..8337e0b8 100644 --- a/src/utils/releaseDownloadPage.test.ts +++ b/src/utils/releaseDownloadPage.test.ts @@ -11,7 +11,10 @@ describe('extractStableDownloadTargets', () => { extractStableDownloadTargets({ platforms: { 'darwin-aarch64': { - download_url: 'https://example.com/Tolaria.dmg', + download_url: 'https://example.com/Tolaria-aarch64.dmg', + }, + 'darwin-x86_64': { + download_url: 'https://example.com/Tolaria-x64.dmg', }, 'linux-x86_64': { download_url: 'https://example.com/Tolaria.AppImage', @@ -23,8 +26,12 @@ describe('extractStableDownloadTargets', () => { }), ).toMatchObject({ 'darwin-aarch64': { - label: 'macOS', - url: 'https://example.com/Tolaria.dmg', + label: 'macOS Apple Silicon', + url: 'https://example.com/Tolaria-aarch64.dmg', + }, + 'darwin-x86_64': { + label: 'macOS Intel', + url: 'https://example.com/Tolaria-x64.dmg', }, 'linux-x86_64': { label: 'Linux', @@ -42,9 +49,14 @@ describe('buildStableDownloadRedirectPage', () => { it('builds a redirect page with platform-specific download links', () => { const html = buildStableDownloadRedirectPage({ 'darwin-aarch64': { - buttonLabel: 'Download Tolaria for macOS', - label: 'macOS', - url: 'https://example.com/Tolaria.dmg', + buttonLabel: 'Download Tolaria for macOS Apple Silicon', + label: 'macOS Apple Silicon', + url: 'https://example.com/Tolaria-aarch64.dmg', + }, + 'darwin-x86_64': { + buttonLabel: 'Download Tolaria for Intel Mac', + label: 'macOS Intel', + url: 'https://example.com/Tolaria-x64.dmg', }, 'windows-x86_64': { buttonLabel: 'Download Tolaria for Windows', @@ -56,7 +68,10 @@ describe('buildStableDownloadRedirectPage', () => { expect(html).toContain('Tolaria Stable Download') expect(html).toContain('DOWNLOAD_TARGETS') expect(html).toContain('Download Tolaria for Windows') - expect(html).toContain('Download Tolaria for macOS') + expect(html).toContain('Download Tolaria for macOS Apple Silicon') + expect(html).toContain('Download Tolaria for Intel Mac') + expect(html).toContain('hasMultipleMacDownloads') + expect(html).toContain('Choose the Apple Silicon or Intel Mac download below.') expect(html).toContain('window.location.replace') expect(html).toContain('color-scheme: light dark') expect(html).toContain('@media (prefers-color-scheme: dark)') @@ -78,7 +93,7 @@ describe('resolveStableDownloadTargets', () => { const latestPayload = { platforms: { 'darwin-aarch64': { - download_url: 'https://example.com/Tolaria.dmg', + download_url: 'https://example.com/Tolaria-aarch64.dmg', }, }, } @@ -86,6 +101,10 @@ describe('resolveStableDownloadTargets', () => { { prerelease: false, assets: [ + { + name: 'Tolaria_x64.dmg', + browser_download_url: 'https://example.com/Tolaria-x64.dmg', + }, { name: 'Tolaria-setup.exe', browser_download_url: 'https://example.com/Tolaria-setup.exe', @@ -99,6 +118,9 @@ describe('resolveStableDownloadTargets', () => { ] expect(extractStableDownloadTargetsFromReleases(releasesPayload)).toMatchObject({ + 'darwin-x86_64': { + url: 'https://example.com/Tolaria-x64.dmg', + }, 'linux-x86_64': { url: 'https://example.com/Tolaria.AppImage', }, @@ -108,7 +130,10 @@ describe('resolveStableDownloadTargets', () => { }) expect(resolveStableDownloadTargets(latestPayload, releasesPayload)).toMatchObject({ 'darwin-aarch64': { - url: 'https://example.com/Tolaria.dmg', + url: 'https://example.com/Tolaria-aarch64.dmg', + }, + 'darwin-x86_64': { + url: 'https://example.com/Tolaria-x64.dmg', }, 'linux-x86_64': { url: 'https://example.com/Tolaria.AppImage', diff --git a/src/utils/releaseDownloadPage.ts b/src/utils/releaseDownloadPage.ts index 4274a16b..c586e333 100644 --- a/src/utils/releaseDownloadPage.ts +++ b/src/utils/releaseDownloadPage.ts @@ -1,6 +1,10 @@ const RELEASE_HISTORY_URL = 'https://refactoringhq.github.io/tolaria/' -type StablePlatformKey = 'darwin-aarch64' | 'linux-x86_64' | 'windows-x86_64' +type StablePlatformKey = + | 'darwin-aarch64' + | 'darwin-x86_64' + | 'linux-x86_64' + | 'windows-x86_64' type PlatformPayload = { dmg_url?: unknown @@ -41,8 +45,12 @@ type DownloadPageContent = { const PLATFORM_METADATA: Record = { 'darwin-aarch64': { - buttonLabel: 'Download Tolaria for macOS', - label: 'macOS', + buttonLabel: 'Download Tolaria for macOS Apple Silicon', + label: 'macOS Apple Silicon', + }, + 'darwin-x86_64': { + buttonLabel: 'Download Tolaria for Intel Mac', + label: 'macOS Intel', }, 'linux-x86_64': { buttonLabel: 'Download Tolaria for Linux', @@ -56,6 +64,7 @@ const PLATFORM_METADATA: Record const DOWNLOAD_TARGETS = ${serializedTargets}; const PLATFORM_ORDER = ${JSON.stringify(PLATFORM_ORDER)}; + const hasMultipleMacDownloads = Boolean( + DOWNLOAD_TARGETS['darwin-aarch64'] && DOWNLOAD_TARGETS['darwin-x86_64'] + ); function detectPlatform(userAgent) { if (/Windows/i.test(userAgent)) return 'windows-x86_64'; @@ -410,6 +437,7 @@ function buildRedirectMarkup(downloads: StableDownloadTargets): string { const resolvedTarget = ( detectedPlatform && DOWNLOAD_TARGETS[detectedPlatform] ) || DOWNLOAD_TARGETS[PLATFORM_ORDER.find((platform) => DOWNLOAD_TARGETS[platform])] || null; + const requiresMacChoice = hasMultipleMacDownloads && /Mac OS X|Macintosh/i.test(navigator.userAgent); if (resolvedTarget) { const link = document.getElementById('download-link'); @@ -419,9 +447,13 @@ function buildRedirectMarkup(downloads: StableDownloadTargets): string { link.textContent = resolvedTarget.buttonLabel; } if (message) { - message.textContent = 'Redirecting to the latest stable Tolaria download for ' + resolvedTarget.label + '.'; + message.textContent = requiresMacChoice + ? 'Choose the Apple Silicon or Intel Mac download below.' + : 'Redirecting to the latest stable Tolaria download for ' + resolvedTarget.label + '.'; + } + if (!requiresMacChoice) { + window.location.replace(resolvedTarget.url); } - window.location.replace(resolvedTarget.url); } ` }