Using the new GitHub ARM runners
Just yesterday at the time of writing, GitHub (finally) released their public ARM runners for Open-Source projects.
This means you can now build ARM programs natively on Linux without having to fiddle with weird cross-compilation.
One way to achieve that is through a Matrix. Considering the following workflow to build, then upload an artifact (taken from the YDMS Opus workflow I wrote):
on: [push]
jobs:
Build-Linux:
name: Builds Opus for Linux
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Download models
run: ./autogen.sh
- name: Create build directory
run: mkdir build
- name: Create build out variable
id: buildoutput
run: echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"
- name: Configure CMake
working-directory: ${{ steps.buildoutput.outputs.build-output-dir }}
run: cmake .. -DBUILD_SHARED_LIBS=ON
- name: Build Opus for Linux
working-directory: ${{ steps.buildoutput.outputs.build-output-dir }}
run: cmake --build . --config Release --target package
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: opus-linux
path: ${{ steps.buildoutput.outputs.build-output-dir }}/**/*.so
We can now easily make it build for ARM by using a matrix referencing the new ubuntu-24.04-arm
runner label.
For instance, we can add this before the job steps:
strategy:
matrix:
osver: [ubuntu-latest, ubuntu-24.04-arm]
Then change the runs-on
configuration to specify ${{ matrix.osver }}
which will create jobs for all the OS versions specified in the matrix.
One issue that might then arise is a name conflict when uploading the job artifacts. For instance, if our old Linux build uses:
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: opus-linux
path: ${{ steps.buildoutput.outputs.build-output-dir }}/**/*.so
And the same step is used by the ARM workflow, we will get an error that the artifact matching the name opus-linux
already exists for this workflow run.
This is where a small conditional step can be added to set an environment variable with the desired name:
- name: Set dist name
run: |
if ${{ matrix.osver == 'ubuntu-24.04-arm' }}; then
echo "distname=opus-linux-arm" >> "$GITHUB_ENV"
else
echo "distname=opus-linux" >> "$GITHUB_ENV"
fi
We can then change our artifact upload step to use these new names:
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ env.distname }}
path: ${{ steps.buildoutput.outputs.build-output-dir }}/**/*.so
As a bit of a sidetrack, you can also use checks like this to conditionally skip (or execute) steps depending on the architecture, using a if
statement:
- name: Mystep
uses: actions/myaction@v4
if: ${{ matrix.osver != 'ubuntu-24.04-arm' }}
steps: |
echo Hello world
In the end, it’s good that this GitHub feature finally landed. Before that, you had to use “large” runners which can cost quite a bit in the end.