Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .github/workflows/build-desktop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ jobs:
node_target: 'x86_64-unknown-linux-gnu'
label: 'Linux-x64'
timeout: 120
- platform: 'ubuntu-24.04-arm'
args: '--target aarch64-unknown-linux-gnu'
node_target: 'aarch64-unknown-linux-gnu'
label: 'Linux-ARM64'
timeout: 120

runs-on: ${{ matrix.platform }}
name: Build (${{ matrix.label }})
Expand All @@ -77,7 +82,7 @@ jobs:
uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7
with:
toolchain: stable
targets: ${{ contains(matrix.platform, 'macos') && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
targets: ${{ contains(matrix.platform, 'macos') && 'aarch64-apple-darwin,x86_64-apple-darwin' || (matrix.label == 'Linux-ARM64' && 'aarch64-unknown-linux-gnu' || '') }}

- name: Rust cache
uses: swatinem/rust-cache@ad397744b0d591a723ab90405b7247fac0e6b8db
Expand Down Expand Up @@ -298,7 +303,7 @@ jobs:
shell: bash
run: |
sudo apt-get install -y xvfb imagemagick
APPIMAGE=$(find src-tauri/target/release/bundle/appimage -name '*.AppImage' | head -1)
APPIMAGE=$(find src-tauri/target -path '*/bundle/appimage/*.AppImage' | head -1)
if [ -z "$APPIMAGE" ]; then
echo "::error::No AppImage found after build"
exit 1
Expand Down
1 change: 1 addition & 0 deletions api/download.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const PLATFORM_PATTERNS = {
'macos-arm64': (name) => name.endsWith('_aarch64.dmg'),
'macos-x64': (name) => name.endsWith('_x64.dmg') && !name.includes('setup'),
'linux-appimage': (name) => name.endsWith('_amd64.AppImage'),
'linux-appimage-arm64': (name) => name.endsWith('_aarch64.AppImage'),
};

const VARIANT_IDENTIFIERS = {
Expand Down
25 changes: 23 additions & 2 deletions scripts/download-node.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Supported targets:
- x86_64-apple-darwin
- aarch64-apple-darwin
- x86_64-unknown-linux-gnu
- aarch64-unknown-linux-gnu

Environment:
NODE_VERSION Node.js version to bundle (default: 22.14.0)
Expand Down Expand Up @@ -72,7 +73,14 @@ if [[ -z "${TARGET}" ]]; then
esac
;;
Linux)
TARGET="x86_64-unknown-linux-gnu"
case "${RUNNER_ARCH:-}" in
ARM64|arm64)
TARGET="aarch64-unknown-linux-gnu"
;;
*)
TARGET="x86_64-unknown-linux-gnu"
;;
esac
;;
*)
echo "Unsupported RUNNER_OS: ${RUNNER_OS}" >&2
Expand All @@ -96,7 +104,14 @@ if [[ -z "${TARGET}" ]]; then
esac
;;
Linux)
TARGET="x86_64-unknown-linux-gnu"
case "$(uname -m)" in
aarch64|arm64)
TARGET="aarch64-unknown-linux-gnu"
;;
*)
TARGET="x86_64-unknown-linux-gnu"
;;
esac
;;
MINGW*|MSYS*|CYGWIN*|Windows_NT)
TARGET="x86_64-pc-windows-msvc"
Expand Down Expand Up @@ -135,6 +150,12 @@ case "${TARGET}" in
NODE_RELATIVE_PATH="bin/node"
OUTPUT_NAME="node"
;;
aarch64-unknown-linux-gnu)
DIST_NAME="node-v${NODE_VERSION}-linux-arm64"
ARCHIVE_NAME="${DIST_NAME}.tar.gz"
NODE_RELATIVE_PATH="bin/node"
OUTPUT_NAME="node"
;;
*)
echo "Unsupported target: ${TARGET}" >&2
exit 1
Expand Down
4 changes: 3 additions & 1 deletion src/app/desktop-updater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,9 @@ export class DesktopUpdater implements AppModule {
}

if (normalizedOs === 'linux') {
return normalizedArch === 'x86_64' ? 'linux-appimage' : null;
if (normalizedArch === 'x86_64') return 'linux-appimage';
if (normalizedArch === 'aarch64') return 'linux-appimage-arm64';
return null;
}

return null;
Expand Down
7 changes: 5 additions & 2 deletions src/components/DownloadBanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function dismiss(panel: HTMLElement, fromDownload = false): void {
panel.addEventListener('transitionend', () => panel.remove(), { once: true });
}

type Platform = 'macos-arm64' | 'macos-x64' | 'macos' | 'windows' | 'linux' | 'unknown';
type Platform = 'macos-arm64' | 'macos-x64' | 'macos' | 'windows' | 'linux' | 'linux-x64' | 'linux-arm64' | 'unknown';

function detectPlatform(): Platform {
const ua = navigator.userAgent;
Expand Down Expand Up @@ -64,7 +64,8 @@ function allButtons(): DlButton[] {
{ cls: 'mac', href: '/api/download?platform=macos-arm64', label: `\uF8FF ${t('modals.downloadBanner.macSilicon')}` },
{ cls: 'mac', href: '/api/download?platform=macos-x64', label: `\uF8FF ${t('modals.downloadBanner.macIntel')}` },
{ cls: 'win', href: '/api/download?platform=windows-exe', label: `\u229E ${t('modals.downloadBanner.windows')}` },
{ cls: 'linux', href: '/api/download?platform=linux-appimage', label: `\u{1F427} ${t('modals.downloadBanner.linux')}` },
{ cls: 'linux', href: '/api/download?platform=linux-appimage', label: `\u{1F427} ${t('modals.downloadBanner.linux')} (x64)` },
{ cls: 'linux', href: '/api/download?platform=linux-appimage-arm64', label: `\u{1F427} ${t('modals.downloadBanner.linux')} (ARM64)` },
];
}

Expand All @@ -76,6 +77,8 @@ function buttonsForPlatform(p: Platform): DlButton[] {
case 'macos': return buttons.filter(b => b.cls === 'mac');
case 'windows': return buttons.filter(b => b.cls === 'win');
case 'linux': return buttons.filter(b => b.cls === 'linux');
case 'linux-x64': return buttons.filter(b => b.href.includes('linux-appimage') && !b.href.includes('arm64'));
case 'linux-arm64': return buttons.filter(b => b.href.includes('linux-appimage-arm64'));
default: return buttons;
}
}
Expand Down