Home

Awesome

Run-On-Arch GitHub Action

A GitHub Action that executes commands on non-x86 CPU architecture (armv6, armv7, aarch64, s390x, ppc64le) via QEMU.

Usage

This action requires three input parameters:

The action also accepts some optional input parameters:

Basic example

A basic example that sets an output variable for use in subsequent steps:

on: [push, pull_request]

jobs:
  armv7_job:
    # The host should always be Linux
    runs-on: ubuntu-22.04
    name: Build on ubuntu-22.04 armv7
    steps:
      - uses: actions/checkout@v4
      - uses: uraimo/run-on-arch-action@v2
        name: Run commands
        id: runcmd
        with:
          arch: armv7
          distro: ubuntu22.04

          # Not required, but speeds up builds by storing container images in
          # a GitHub package registry.
          githubToken: ${{ github.token }}

          # Set an output parameter `uname` for use in subsequent steps
          run: |
            uname -a
            echo ::set-output name=uname::$(uname -a)

      - name: Get the output
        # Echo the `uname` output parameter from the `runcmd` step
        run: |
          echo "The uname output was ${{ steps.runcmd.outputs.uname }}"

Advanced example

This shows how to use a matrix to produce platform-specific artifacts, and includes example values for the optional input parameters setup, shell, env, and dockerRunArgs.

on: [push, pull_request]

jobs:
  build_job:
    # The host should always be linux
    runs-on: ubuntu-22.04
    name: Build on ${{ matrix.distro }} ${{ matrix.arch }}

    # Run steps on a matrix of 4 arch/distro combinations
    strategy:
      matrix:
        include:
          - arch: aarch64
            distro: ubuntu22.04
          - arch: aarch64
            distro: bullseye 
          - arch: ppc64le
            distro: alpine_latest
          - arch: none
            distro: none
            base_image: riscv64/busybox
    steps:
      - uses: actions/checkout@v4
      - uses: uraimo/run-on-arch-action@v2
        name: Build artifact
        id: build
        with:
          arch: ${{ matrix.arch }}
          distro: ${{ matrix.distro }}

          # Not required, but speeds up builds
          githubToken: ${{ github.token }}

          # Create an artifacts directory
          setup: |
            mkdir -p "${PWD}/artifacts"

          # Mount the artifacts directory as /artifacts in the container
          dockerRunArgs: |
            --volume "${PWD}/artifacts:/artifacts"

          # Pass some environment variables to the container
          env: | # YAML, but pipe character is necessary
            artifact_name: git-${{ matrix.distro }}_${{ matrix.arch }}

          # The shell to run commands with in the container
          shell: /bin/sh

          # Install some dependencies in the container. This speeds up builds if
          # you are also using githubToken. Any dependencies installed here will
          # be part of the container image that gets cached, so subsequent
          # builds don't have to re-install them. The image layer is cached
          # publicly in your project's package repository, so it is vital that
          # no secrets are present in the container state or logs.
          install: |
            case "${{ matrix.distro }}" in
              ubuntu*|jessie|stretch|buster|bullseye)
                apt-get update -q -y
                apt-get install -q -y git
                ;;
              fedora*)
                dnf -y update
                dnf -y install git which
                ;;
              alpine*)
                apk update
                apk add git
                ;;
            esac

          # Produce a binary artifact and place it in the mounted volume
          run: |
            cp $(which git) "/artifacts/${artifact_name}"
            echo "Produced artifact at /artifacts/${artifact_name}"

      - name: Show the artifact
        # Items placed in /artifacts in the container will be in
        # ${PWD}/artifacts on the host.
        run: |
          ls -al "${PWD}/artifacts"

Supported Platforms

This table details the valid arch/distro combinations:

archdistro
armv6stretch, buster, bullseye, bookworm, alpine_latest
armv7stretch, buster, bullseye, bookworm, ubuntu20.04, ubuntu22.04, ubuntu_latest, ubuntu_rolling, ubuntu_devel, fedora_latest, alpine_latest, archarm_latest
aarch64stretch, buster, bullseye, bookworm, ubuntu20.04, ubuntu22.04, ubuntu_latest, ubuntu_rolling, ubuntu_devel, fedora_latest, alpine_latest, archarm_latest
riscv64ubuntu20.04, ubuntu22.04, ubuntu_latest, ubuntu_rolling, ubuntu_devel, alpine_edge
s390xstretch, buster, bullseye, bookworm, ubuntu20.04, ubuntu22.04, ubuntu_latest, ubuntu_rolling, ubuntu_devel, alpine_latest
ppc64lestretch, buster, bullseye, bookworm, ubuntu20.04, ubuntu22.04, ubuntu_latest, ubuntu_rolling, ubuntu_devel, alpine_latest

Using an invalid arch/distro combination will fail.

Architecture emulation

This project makes use of an additional QEMU container to be able to emulate via software architectures like ARM, s390x, ppc64le, etc... that are not natively supported by GitHub. You should keep this into consideration when reasoning about the expected running time of your jobs, there will be a visible impact on performance when compared to a job executed on a vanilla runner.

Contributing

New distros and archs can be added simply by creating a Dockerfile named Dockerfile.{arch}.{distro} (that targets an image for the desired combination) in the Dockerfiles directory. Pull requests welcome!

Authors

Umberto Raimondi

Elijah Shaw-Rutschman

And many other contributors.

License

This project is licensed under the BSD 3-Clause License.