Skip to content

feat(release): publish native Linux arm64 artifacts - #1288

Merged
vastsa merged 2 commits into
mainfrom
feat/linux-arm64-release
Oct 1, 2026
Merged

vastsa merged 2 commits into
mainfrom
feat/linux-arm64-release

Conversation

@vastsa

@vastsa vastsa commented Oct 1, 2026 •

Copy link
Copy Markdown
Owner

Closes #1281.

Adds a native Linux arm64 release lane beside the existing x64 one. The request came from an arm64 Android tablet running PI-Desktop inside a Linux container, where the published x64 artifact cannot execute.

What changes

  • Two native Linux lanes. release.yml gains a Linux arm64 matrix entry on GitHub's ubuntu-22.04-arm runner next to ubuntu-22.04 for x64. Both lanes verify uname -m before packaging, so a mislabelled or emulated runner can no longer wrap one architecture's Electron app around the other architecture's pi-desktop-host-core. Both images are Ubuntu 22.04, so the documented glibc 2.35 floor is unchanged.
  • Architecture-labelled artifacts. The Linux targets drop their pinned arch (electron-builder prefers a target's configured arch list over the --x64/--arm64 flag, so pinning both would build the other architecture on each lane) and linux.artifactName becomes PI-Desktop-${version}-linux-${arch}.${ext}. The two lanes' AppImages can no longer collide on PI-Desktop-<version>.AppImage; deb/rpm keep their patterns and expand to amd64/arm64 and x86_64/aarch64.
  • Feed names are verified, not rewritten. electron-builder already names each Linux feed after the architecture it built (latest-linux.yml on x64, latest-linux-arm64.yml on arm64), which is what electron-updater requests on those architectures, so the lanes cannot overwrite each other's feed when the publish job merges their artifacts. Each lane fails before upload if its own feed is missing.
  • Arch-aware ASAR asset. scripts/export-linux-asar.mjs takes the lane architecture, reads linux-unpacked (x64) or linux-arm64-unpacked (arm64), and publishes PI-Desktop-<version>-linux-<arch>.asar.
  • pi-host parity. pi-host-bundle builds linux-arm64 too, and PUBLISHED_TARGETS in pi-host-release.ts accepts it, so an arm64 desktop can bootstrap an arm64 remote host instead of refusing a target the release serves.

Updater ownership, signing, and delivery modes are unchanged: the arm64 AppImage uses the same in-app electron-updater lane as x64, deb/rpm stay notify-and-link.

Compatibility note

The x64 AppImage asset is renamed from PI-Desktop-<version>.AppImage to PI-Desktop-<version>-linux-x64.AppImage. In-app updates are unaffected (the updater reads the published feed); download links that hard-code the old name need updating. This follows the macOS precedent (ADR 0145 / ADR 0191).

Known limitation

Microphone capture on arm64 Linux stays Raspberry Pi only: @picovoice/pvrecorder-node classifies Linux arm64 by /proc/cpuinfo CPU part. Speech-to-text (transcribe-cpp ships a linux-arm64-cpu-vulkan bundle) and everything else work on any arm64 Linux device. Recorded in ADR 0318 and the runbook's known limitations.

Verification

  • Full Release workflow dispatched on this branch (workflow_dispatch, sign_macos=false, publish job skipped): every job green, including Build Linux arm64. The lane produced PI-Desktop-0.16.0-beta.1-linux-arm64.AppImage, pi-desktop_0.16.0-beta.1_arm64.deb, pi-desktop-0.16.0-beta.1-aarch64.rpm, PI-Desktop-0.16.0-beta.1-linux-arm64.asar, and pi-host-0.16.0-beta.1-linux-arm64.tar.gz, on an aarch64 runner with an aarch64-unknown-linux-gnu rust toolchain, and its host-core passed the glibc check (needs 2.34, floor 2.35). The arm64 pi-host bundle job is green too.
  • The first dispatch of that run caught a real defect: electron-builder already writes latest-linux-arm64.yml for an arm64 build, so the lane must verify the feed name instead of renaming latest-linux.yml. Fixed in the second commit and re-verified by the green run.
  • apps/desktop unit suite: 3358 tests pass (node --test test/*.test.mjs), including new coverage for the arm64 lane, the feed name, the arch-aware ASAR export, the arm64 pi-host artifact, and the unpinned Linux targets.
  • biome lint, the desktop style-token check, and tsc --noEmit are clean; docs:check verifies all 83 locale pairs and 545 documentation pages.

The remaining item is a real arm64 installation (bytes-on-disk acceptance), which E2E-192a records as runner validation: install the AppImage/deb/rpm on an arm64 Linux machine and launch it.

Issue #1281 asks for a Linux arm64 build: the reporter runs PI-Desktop inside
a Linux container on a rooted arm64 Android tablet, where no x64 artifact can
execute and the Rust host sidecar makes a cross-built package unsafe.

- release.yml gains a native Linux arm64 lane on GitHub's ubuntu-22.04-arm
  runner, verifies uname -m on every native lane, and disambiguates the arm64
  updater feed to latest-linux-arm64.yml so merging both Linux lanes cannot
  drop the x64 feed.
- The static Linux targets drop their pinned arch (electron-builder prefers a
  target's configured arch list over --x64/--arm64), and linux.artifactName
  carries the architecture so the two lanes' AppImages cannot collide.
- scripts/export-linux-asar.mjs takes the lane architecture, reads
  linux-unpacked or linux-arm64-unpacked, and publishes
  PI-Desktop-<version>-linux-<arch>.asar.
- pi-host-bundle builds linux-arm64 as well, and PUBLISHED_TARGETS accepts it
  so an arm64 desktop can bootstrap an arm64 remote host.
- Tests cover the new lane, the feed rename, the arch-aware ASAR export, the
  linux-arm64 pi-host artifact, and the unpinned Linux target configuration.
- Docs: ADR 0318 / D638, release runbook and platform lists (en + zh-CN),
  decisions log, e2e E2E-192a.
Copilot AI balanced review requested due to automatic review settings October 1, 2026 15:12

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The core arm64 packaging lane still needs its documented native-runner validation before landing.

Review effort: Balanced
Findings: 1 Medium severity · 3 Low severity

Open (4)
What changed in this PR

Adds native Linux arm64 release support alongside x64, including installers, updater metadata, ASAR assets, and remote pi-host bundles.

Changes:

  • Adds native arm64 GitHub Actions release and host-bundle lanes.
  • Makes Linux artifact names, updater feeds, and ASAR exports architecture-aware.
  • Updates tests, ADRs, release specifications, and localized documentation.
File Description
.github/​workflows/​release.yml Adds native arm64 release and host-bundle jobs.
apps/​desktop/​package.json Makes Linux targets architecture-selectable and labelled.
apps/​desktop/​electron/​main/​remote/​pi-host-release.ts Allows published Linux arm64 hosts.
apps/​desktop/​test/​ci-workflow.test.mjs Tests release matrix and packaging configuration.
apps/​desktop/​test/​release-asar.test.mjs Tests architecture-aware ASAR export.
apps/​desktop/​test/​remote-host-pi-host-release.test.mjs Tests arm64 target publication.
apps/​desktop/​test/​remote-host-ssh-bootstrap.test.mjs Tests arm64 remote bootstrap.
scripts/​export-linux-asar.mjs Exports ASAR assets per architecture.
scripts/​README.md Documents dual Linux release lanes.
README.md Advertises Linux arm64 packages.
README.zh-CN.md Mirrors Linux arm64 availability in Chinese.
docs/​adr/​README.md Registers ADR 0318.
docs/​adr/​0318-linux-arm64-release-lane.md Records the arm64 release decision.
docs/​adr/​0292-ssh-remote-host-bootstrap.md Expands remote-host targets to arm64.
docs/​spec/​README.md Updates the release-platform summary.
docs/​spec/​00-baseline.md Adds arm64 to the frozen release baseline.
docs/​spec/​01-product/​01-product-scope.md Adds arm64 to shipped product scope.
docs/​spec/​02-architecture/​02-tech-stack.md Records the additional packaging lane.
docs/​spec/​06-delivery/​01-mvp-milestones.md Expands packaging deliverables.
docs/​spec/​06-delivery/​04-e2e-test-plan.md Adds arm64 release validation scenario.
docs/​spec/​06-delivery/​06-release-runbook.md Documents arm64 packaging and limitations.
docs/​spec/​08-meta/​decisions-log.md Records decision D638.
docs/​zh-CN/​spec/​README.md Mirrors the release-platform summary.
docs/​zh-CN/​spec/​00-baseline.md Mirrors the updated baseline.
docs/​zh-CN/​spec/​01-product/​01-product-scope.md Mirrors arm64 product scope.
docs/​zh-CN/​spec/​02-architecture/​02-tech-stack.md Mirrors packaging architecture coverage.
docs/​zh-CN/​spec/​06-delivery/​01-mvp-milestones.md Mirrors packaging milestones.
docs/​zh-CN/​spec/​06-delivery/​04-e2e-test-plan.md Mirrors arm64 E2E coverage.
docs/​zh-CN/​spec/​06-delivery/​06-release-runbook.md Mirrors release procedures and limitations.
docs/​zh-CN/​spec/​08-meta/​decisions-log.md Mirrors decision D638.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +125 to +129
- name: Linux arm64
# GitHub's native arm64 runner packages the Electron app and the
# host-core sidecar at the same architecture; the `-arm` image
# keeps the glibc 2.35 floor the x64 lane documents
# (ubuntu-24.04-arm would raise it to 2.39).
Raspberry Pi boards: `@picovoice/pvrecorder-node` classifies Linux arm64 by
`/proc/cpuinfo` CPU part and only knows Raspberry Pi parts. Speech-to-text
(`transcribe-cpp` ships a `linux-arm64-cpu-vulkan` bundle) and every other
feature have no architecture-specific dependency.
- Linux arm64 microphone capture works on Raspberry Pi boards only:
`@picovoice/pvrecorder-node` classifies Linux arm64 by `/proc/cpuinfo` CPU
part. Speech-to-text (`transcribe-cpp` ships a `linux-arm64-cpu-vulkan`
bundle) and every other feature work on any arm64 Linux device.
Comment thread scripts/README.md
Comment on lines +91 to +92
glibc. Each Linux runner (native x64 and arm64) also exports the exact
app.asar from its own unpacked tree as a versioned release asset; the macOS
The first arm64 run of the release workflow failed at the feed-rename step:
electron-builder already writes `latest-linux-arm64.yml` for an arm64 Linux
build (`getArchPrefixForUpdateFile`), so there is no `latest-linux.yml` to
rename and no feed collision to avoid. The lanes now verify the feed they will
publish (x64: latest-linux.yml, arm64: latest-linux-arm64.yml), which fails on
the runner if a name ever drifts from what electron-updater requests.

Verified by the run itself: the arm64 lane produced
PI-Desktop-0.16.0-beta.1-linux-arm64.AppImage,
pi-desktop_0.16.0-beta.1_arm64.deb, pi-desktop-0.16.0-beta.1-aarch64.rpm, and
PI-Desktop-0.16.0-beta.1-linux-arm64.asar before that step.
@vastsa
vastsa merged commit 66251e2 into main Oct 1, 2026
13 checks passed
JoyaWang added a commit to JoyaWang/PI-Desktop that referenced this pull request Oct 2, 2026
The rebase onto c5c77ca (vastsa#1288-era ask card rework) put the new
pending-ask registry cleanup next to upstream's Host-owned resolve path,
which now returns early when the Host still holds the ask. Keep both
exits clearing the registry, and pin it with a source-contract test so a
later simplification cannot drop one of the two.

Refs: vastsa#1014
@vastsa
vastsa deleted the feat/linux-arm64-release branch October 6, 2026 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] 增加Linux arm64构建

2 participants