feat: publish intel mac builds
This commit is contained in:
62
.github/workflows/release-stable.yml
vendored
62
.github/workflows/release-stable.yml
vendored
@@ -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
|
||||
|
||||
47
.github/workflows/release.yml
vendored
47
.github/workflows/release.yml
vendored
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
38
docs/adr/0083-dual-architecture-macos-release-artifacts.md
Normal file
38
docs/adr/0083-dual-architecture-macos-release-artifacts.md
Normal file
@@ -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.
|
||||
@@ -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 |
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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<StablePlatformKey, { buttonLabel: string; label: string }> = {
|
||||
'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<StablePlatformKey, { buttonLabel: string; label:
|
||||
|
||||
const PLATFORM_ORDER: StablePlatformKey[] = [
|
||||
'darwin-aarch64',
|
||||
'darwin-x86_64',
|
||||
'windows-x86_64',
|
||||
'linux-x86_64',
|
||||
]
|
||||
@@ -196,6 +205,7 @@ function extractPlatformDownloadUrl(
|
||||
|
||||
switch (platform) {
|
||||
case 'darwin-aarch64':
|
||||
case 'darwin-x86_64':
|
||||
return (
|
||||
normalizeUrl(payload.download_url)
|
||||
?? normalizeUrl(payload.dmg_url)
|
||||
@@ -231,16 +241,30 @@ function isPublicStableRelease(release: GitHubReleasePayload): boolean {
|
||||
return release.draft !== true && release.prerelease !== true
|
||||
}
|
||||
|
||||
function classifyMacReleaseAsset(name: string): {
|
||||
platform: StablePlatformKey
|
||||
preference: number
|
||||
} | null {
|
||||
const normalized = name.toLowerCase()
|
||||
const isDmg = normalized.endsWith('.dmg')
|
||||
const isUpdaterTarball = normalized.endsWith('.app.tar.gz')
|
||||
if (!isDmg && !isUpdaterTarball) return null
|
||||
|
||||
const preference = isDmg ? 2 : 1
|
||||
if (/(?:^|[-_.])(x64|x86_64|intel)(?:[-_.]|$)/.test(normalized)) {
|
||||
return { platform: 'darwin-x86_64', preference }
|
||||
}
|
||||
|
||||
return { platform: 'darwin-aarch64', preference }
|
||||
}
|
||||
|
||||
function classifyReleaseAsset(name: string): {
|
||||
platform: StablePlatformKey
|
||||
preference: number
|
||||
} | null {
|
||||
if (name.endsWith('.dmg')) {
|
||||
return { platform: 'darwin-aarch64', preference: 2 }
|
||||
}
|
||||
if (name.endsWith('.app.tar.gz')) {
|
||||
return { platform: 'darwin-aarch64', preference: 1 }
|
||||
}
|
||||
const macAsset = classifyMacReleaseAsset(name)
|
||||
if (macAsset) return macAsset
|
||||
|
||||
if (name.endsWith('-setup.exe')) {
|
||||
return { platform: 'windows-x86_64', preference: 2 }
|
||||
}
|
||||
@@ -398,6 +422,9 @@ function buildRedirectMarkup(downloads: StableDownloadTargets): string {
|
||||
<script>
|
||||
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);
|
||||
}
|
||||
</script>`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user