Skip to content

Conversation

@per1234
Copy link
Contributor

@per1234 per1234 commented Nov 2, 2025

The build workflows generate ARM 64-bit builds of the application for Linux, macOS, and Windows hosts. When those builds are performed in the x86 "ubuntu-latest" runner machine, they fail due to incompatibility between the Docker container in which the builds are performed and the runner architecture:

Status: Downloaded newer image for docker.elastic.co/beats-dev/golang-crossbuild:1.25.2-windows-arm64-debian12
WARNING: The requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64/v3) and no specific platform was requested
exec /crossbuild: exec format error
task: Failed to run task "dist:Windows_ARM64": exit status 255

The established solution (arduino/arduino-cli#2850, arduino/arduino-cli#2896, arduino/arduino-cli#3007, arduino/arduino-lint#952) for this problem is to instead use the Linux ARM "ubuntu-24.04-arm" runner machine for those
builds:

The builds can be performed on this runner due to it having the required host architecture for compatibility
with the build containers.

Previously (#93), an alternative solution was used in this project: using QEMU to emulate the required host architecture. That
solution was inferior in multiple ways:

  • Introduces an additional action dependency (docker/setup-qemu-action).
  • Less efficient due to the overhead of installing QEMU, and the inferior performance of the build under emulation.

Regarding the latter, here are the durations of the build job of the "Publish Tester Build" workflow, for the QEMU based approach implemented by #93 and the native approach proposed by this pull request:

Build main (s) PR (s)
Linux_ARM64 129.5 41.5
Linux_ARMv6 47.5 44.5
Linux_ARMv7 49.5 38.5
Linux_X86-32 50.5 41.5
Linux_X86-64 55 41.5
macOS_64 57 54.5
macOS_ARM64 181 80.5
Windows_ARM64 159.5 73.5
Windows_X86-32 51.5 50.5
Windows_X86-64 54.5 44

The durations are the averaged of two separate runs of each workflow, interleaved. This was done to reduce the possible influence of transient conditions on the results. The deviation between runs of each variant of the workflow was not significant.

For this reason, it is here proposed that the workflow be ported to using the appropriate runner machine for the ARM 64-bit build jobs instead of depending on QEMU.

Additional context

It is standard practice to use the "latest" GitHub Actions runner identifiers in the project's workflows, which causes the workflow runs to always use the newest stable runner version. However, GitHub has broken from this established convention by choosing to not provide "latest" identifiers for the Linux ARM runners (actions/partner-runner-images#118 (comment)). For this reason, the version-specific runner name was used in the workflow. It will be necessary to manually update the runner name as new stable versions are made available (or more likely fail to do so until forced after GitHub's removal of the runner in use breaks the workflows).

The build workflows generate ARM 64-bit builds of the application for Linux, macOS, and Windows hosts. When those builds
are performed in the x86 "ubuntu-latest" runner machine, they fail due to incompatibility between the Docker container
in which the builds are performed and the runner architecture:

```
Status: Downloaded newer image for docker.elastic.co/beats-dev/golang-crossbuild:1.25.2-windows-arm64-debian12
WARNING: The requested image's platform (linux/arm64/v8) does not match the detected host platform (linux/amd64/v3) and no specific platform was requested
exec /crossbuild: exec format error
task: Failed to run task "dist:Windows_ARM64": exit status 255
```

The established solution for this problem is to instead use the Linux ARM "ubuntu-24.04-arm" runner machine for those
builds. The builds can be performed on this runner due to it having the required host architecture for compatibility
with the build containers.

Previously, an alternative solution was used in this project: using QEMU to emulate the required host architecture. That
solution was inferior in multiple ways:

- Introduces an additional action dependency ("docker/setup-qemu-action").
- Less efficient due to the overhead of installing QEMU, and the inferior performance of the build under emulation.

For this reason, the workflow is ported to using the appropriate runner machine for the ARM 64-bit build jobs instead of
depending on QEMU.
Copy link
Member

@cmaglie cmaglie left a comment

Choose a reason for hiding this comment

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

Nice! 🚀

I didn't find this solution because I was blinded by searching for a way to make the container work. We could backport the full solution to the arduino-cli repo.

@cmaglie cmaglie merged commit 9ba2660 into arduino:main Nov 3, 2025
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic: infrastructure Related to project infrastructure type: enhancement Proposed improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants