{"id":13883458,"url":"https://github.com/pguyot/arm-runner-action","last_synced_at":"2025-04-05T13:08:03.147Z","repository":{"id":37245966,"uuid":"361153193","full_name":"pguyot/arm-runner-action","owner":"pguyot","description":"Run tests natively and build images directly from GitHub Actions using a chroot-based virtualized Raspberry Pi (raspios/raspbian) environment","archived":false,"fork":false,"pushed_at":"2024-08-24T15:21:08.000Z","size":115,"stargazers_count":153,"open_issues_count":6,"forks_count":31,"subscribers_count":7,"default_branch":"main","last_synced_at":"2024-10-22T03:30:24.578Z","etag":null,"topics":["aarch64","arm","armv6l","armv7l","qemu","raspberry-pi","raspberry-pi-zero"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pguyot.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["pguyot"]}},"created_at":"2021-04-24T12:13:53.000Z","updated_at":"2024-09-30T21:28:32.000Z","dependencies_parsed_at":"2024-05-13T07:30:45.851Z","dependency_job_id":"7f92085b-efb0-4cdc-90b9-cf87287006ae","html_url":"https://github.com/pguyot/arm-runner-action","commit_stats":{"total_commits":81,"total_committers":16,"mean_commits":5.0625,"dds":"0.32098765432098764","last_synced_commit":"5864a9437a962fa84b1cd4bb9197a5b81ecf4fa9"},"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pguyot%2Farm-runner-action","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pguyot%2Farm-runner-action/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pguyot%2Farm-runner-action/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pguyot%2Farm-runner-action/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pguyot","download_url":"https://codeload.github.com/pguyot/arm-runner-action/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247157276,"owners_count":20893220,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aarch64","arm","armv6l","armv7l","qemu","raspberry-pi","raspberry-pi-zero"],"created_at":"2024-08-06T09:01:32.998Z","updated_at":"2025-04-05T13:08:03.127Z","avatar_url":"https://github.com/pguyot.png","language":"Shell","funding_links":["https://github.com/sponsors/pguyot"],"categories":["Shell"],"sub_categories":[],"readme":"# arm-runner-action\n\nRun tests natively and build images directly from GitHub Actions using a\nchroot-based virtualized Raspberry Pi (raspios/raspbian) environment.\n\nWith this action, you can:\n\n- run tests in an environment closer to a real embedded system, using qemu\nuserland Linux emulation;\n- build artifacts in such environment and upload them;\n- prepare images that are ready to run on Raspberry Pi and other ARM embedded\ndevices.\n\nThis action works with both 32 bits (arm) and 64 bits (aarch64) images.\n\n## Usage\n\nMinimal usage is as follows:\n\n```yaml\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n    - uses: pguyot/arm-runner-action@v2\n      with:\n        commands: |\n            commands to run tests\n```\n\nTypical usage to upload an image as an artifact:\n\n```yaml\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v2\n    - uses: pguyot/arm-runner-action@v2\n      id: build_image\n      with:\n        base_image: raspios_lite:2022-04-04\n        commands: |\n            commands to build image\n    - name: Compress the release image\n      if: github.ref == 'refs/heads/releng' || startsWith(github.ref, 'refs/tags/')\n      run: |\n        mv ${{ steps.build_image.outputs.image }} my-release-image.img\n        xz -0 -T 0 -v my-release-image.img\n    - name: Upload release image\n      uses: actions/upload-artifact@v2\n      if: github.ref == 'refs/heads/releng' || startsWith(github.ref, 'refs/tags/')\n      with:\n        name: Release image\n        path: my-release-image.img.xz\n```\n\nSeveral scenarios are actually implemented as [tests](/.github/workflows).\n\n### Host and guest OS\n\nThe action has been tested with `ubuntu-latest` (currently equivalent to\n`ubuntu-20.04`) and `ubuntu-22.04`. It requires a Linux kernel that is\ncompatible enough with the guest system as it uses qemu userland emulation. It\nrelies on binfmt.\n\n### Commands\n\nThe repository is copied to the image before the commands script is executed\nin the chroot environment. The commands script is copied to /tmp/ and is\ndeleted on cleanup.\n\n### Inputs\n\n#### `commands`\n\nCommands to execute. Written to a script within the image. Required.\n\n#### `base_image`\n\nBase image to use. By default, uses latest `raspios_lite` image. Please note\nthat this is not necessarily well suited for continuous integration as\nthe latest image can change with new releases.\n\nThe following values are allowed:\n\n-   `raspbian_lite:2020-02-13`\n-   `raspbian_lite:latest`\n-   `raspios_lite:2021-03-04`\n-   `raspios_lite:2021-05-07`\n-   `raspios_lite:2021-10-30`\n-   `raspios_lite:2022-01-28`\n-   `raspios_lite:2022-04-04`\n-   `raspios_lite:2023-05-03`\n-   `raspios_lite:latest` (armhf build, *default*)\n-   `raspios_oldstable_lite:2023-05-03`\n-   `raspios_lite_arm64:2022-01-28` (arm64)\n-   `raspios_lite_arm64:2022-04-04` (arm64)\n-   `raspios_lite_arm64:2023-05-03` (arm64)\n-   `raspios_lite_arm64:latest` (arm64)\n-   `dietpi:rpi_armv6_bullseye`\n-   `dietpi:rpi_armv7_bullseye`\n-   `dietpi:rpi_armv8_bullseye` (arm64)\n-   `dietpi:rpi_armv6_bookworm`\n-   `dietpi:rpi_armv7_bookworm`\n-   `dietpi:rpi_armv8_bookworm` (arm64)\n-   `raspi_1_bullseye:20220121` (armel)\n-   `raspi_2_bullseye:20230102` (armhf)\n-   `raspi_3_bullseye:20230102` (arm64)\n-   `raspi_4_bullseye:20230102` (arm64)\n-   `raspi_1_bookworm:20231109` (armel)\n-   `raspi_2_bookworm:20231109` (armhf)\n-   `raspi_3_bookworm:20231109` (arm64)\n-   `raspi_4_bookworm:20231109` (arm64)\n\nThe input parameter also accepts any custom URL beginning in http(s)://...\n\nIt also accepts file:// URIs, which can be useful for caching steps in multistep builds. See [cache test example](.github/workflows/test-cache.yml).\n\nUnfortunately, Archlinux ARM does not publish images that are ready to be\nflashed. See [ArchLinux example](.github/workflows/test-archlinux.yml) as a\nworkaround to build the image following the official ArchLinux ARM\ninstructions.\n\nMore images will be added, eventually. Feel free to submit PRs.\n\n#### `image_additional_mb`\n\nEnlarge the image by this number of MB. Default is to not enlarge the image.\n\n#### `cpu`\n\nCPU to pass to qemu. Pass either a single CPU value or a pair\n`\u003carm_cpu\u003e:\u003caarch64_cpu\u003e`.\n\nDefault is `arm1176:cortex-a53`, i.e. `arm1176` for arm and `cortex-a53` for\naarch64. This is the most compatible pair for Raspberry Pi. Indeed, `arm1176`\nis the CPU of BCM2835 which is the SOC of first generation RaspberryPi and\nRaspberryPi Zero, while `cortex-a53` is the 64 bits CPU of the first 64 bits\nRaspberry Pi models. Code compiled for `arm1176` can be run on later 32 bits\nCPUs.\n\nThe following values are specially processed:\n- `arm1176` equivalent to `arm1176:cortex-a53`.\n- `cortex-a7` equivalent to `cortex-a7:cortex-a53`. Optimized for later Pi\n  models (Pi 3/Pi 4 and Pi Zero 2). Not suitable for Pi 1/Pi 2/Pi Zero.\n- `cortex-a8` equivalent to `cortex-a8:max`.\n- `cortex-a53` equivalent to `max:cortex-a53`.\n- `cortex-a76` equivalent to `max:cortex-a76`. Note that this requires a newer\n  version of qemu, for example with runner ubuntu 24.04. See `test_cortex_a76`\n  in [cpu_info test](.github/workflows/test-cpu_info.yml).\n\nSome software uses the output of `uname -m` or equivalent. This command is\ndirectly driven by this `cpu` option. You might want to compile 32 bits\nbinaries with both `arm1176` which translates to `armv6l` and `cortex-a7` which\ntranslates to `armv7l`.\n\nFor FPU and vector instruction sets, software usually automatically looks into\n`/proc/cpuinfo` or equivalent. See `cpu_info` option below.\n\nWhether code is executed in 32 bits or 64 bits (and build generates 32 bits\nor 64 bits binaries) depend on the image. See _32 and 64 bits_ below.\n\n#### `copy_artifact_path`\n\nSource paths(s) inside the image to copy outside after the commands have\nexecuted. Relative to the `/\u003crepository_name\u003e` directory or the directory\ndefined with `copy_repository_path`. Globs are allowed. To copy multiple paths,\nprovide a list of paths, separated by semicolons. Default is not to copy.\n\n#### `copy_artifact_dest`\n\nDestination path to copy outside the image after the commands have executed.\nRelative to the working directory (outside the image). Defaults to `.`\n\n#### `copy_repository_path`\n\nAbsolute path, inside the image, where the repository is copied or mounted.\nDefaults to `/\u003crepository_name\u003e`. It is also the working directory where\ncommands are executed.\n\nThe repository is copied unless `bind_mount_repository` is set to true.\n\n#### `bind_mount_repository`\n\nBind mount the repository within the image instead of copying it. Default is\nto copy files.\n\nIf mounted, any modification of files within the repository by the target\nemulated system will persist after execution. It does not accelerate execution\nsignificantly but can simplify the logic by avoiding the copy artifact step\nfrom the target system.\n\n#### `cpu_info`\n\nPath to a fake cpu_info file to be used instead of `/proc/cpuinfo`. Default is\nto not fake the CPU. With older versions of qemu, including the one provided\nby ubuntu-latest as of this writing (ubuntu 22.04, qemu 6), `/proc/cpuinfo` is\nnot intercepted and will report amd64 CPU of GitHub runner.\n\nSome software checks for features using `/proc/cpuinfo` and this option can be\nused to trick them. The path is relative to the action (to use pre-defined\nsettings) or to the local repository.\n\nBundled with the action are the following 32 bits CPU infos:\n- `cpuinfo/raspberrypi_zero_w`\n- `cpuinfo/raspberrypi_3b` (requires `cortex-a7` cpu)\n- `cpuinfo/raspberrypi_zero2_w` (requires `cortex-a7` cpu)\n\nAs well as the following 64 bits CPU infos:\n- `cpuinfo/raspberrypi_4b`\n- `cpuinfo/raspberrypi_zero2_w_arm64`\n- `cpuinfo/raspberrypi_5`\n\nOn real hardware, the `/proc/cpuinfo` file content depends on the CPU being\nused in 32 bits or 64 bits mode, which in turn depends on the base image.\nConsequently, you may want to use `cpuinfo/raspberrypi_zero2_w_arm64` for\n64 bits builds and `cpuinfo/raspberrypi_zero2_w` for 32 bits builds.\n\nTo avoid illegal instruction crashes, the `cpu_info` option must match what is\npassed to `cpu` option. In particular, when using 32 bits `cpu_info`, the\ndefault emulated CPU for 32 bits may not work and you should set `cpu` option\nto `cortex-a7`.\n\nqemu 8.2 and higher do intercept `/proc/cpuinfo` to report something related\nto the passed cpu option. So if you are running ubuntu-24.04 or if you install\nyour own version of qemu-user-arm/aarch64, this option will be effectless.\n\n#### `optimize_image`\n\nZero-fill unused filesystem blocks and shrink root filesystem during final clean-up, to make any later\nimage compression more efficient. Default is to optimize image.\n\n#### `use_systemd_nspawn`\n\nUse `systemd-nspawn` instead of chroot to run commands. Default is to use\nchroot.\n\n#### `systemd_nspawn_options`\n\nAdditional options passed to `systemd-nspawn`. For example, `-E CI=${CI}` to pass\nCI environment variable. See [systemd-nspawn(1)](https://manpages.ubuntu.com/manpages/focal/man1/systemd-nspawn.1.html).\n\n#### `rootpartition`\n\nIndex (starting with 1) of the root partition. Default is 2, which is suitable\nfor Raspberry Pi. NVIDIA Jetson images require 1. This is the partition that is\nresized with `image_additional_mb` option.\n\n#### `bootpartition`\n\nIndex (starting with 1) of the boot partition which gets mounted at /boot.\nDefault is 1, which is suitable for Raspberry Pi. If the value is empty,\nthe partition is not mounted.\n\n#### `shell`\n\nPath to shell or shell name to run the commands in. Defaults to /bin/sh.\nIf missing, it will be installed. See `shell_package`.\nIf defined as basename filename, it will be used as long as the shell binary\nexists under PATH after the package is installed.\n\nParameters can be passed to the shell, e.g.:\n```yaml\nshell: /bin/bash -eo pipefail\n```\n\n#### `shell_package`\n\nThe shell package to install, if different from shell. It may be handy\nwith some shells that come packaged under a different package name.\n\nFor example, to use `ksh93` as shell, set `shell` to `ksh93` and\n`shell_package` to `ksh`.\n\n#### `user`\n\nUser to run commands within the image. It must exists.\nBy default, commands are run with user 0 (root).\nUnless you are using `systemd-nspawn`, you can also specify the group with\nthe `user:group` syntax.\n\n#### `exit_on_fail`\n\nExit immediately if a command exits with a non-zero status. Default is to exit.\nSet to `no` or `false` to disable exiting on command failure. This only works\nwith `sh`, `bash` and `ksh` shells.\n\n#### `copy_artifacts_on_fail`\n\nCopy artifacts if a command exits with a non-zero status. Default is to no copy.\nSet to `yes` to copy artifacts.\n\n#### `debug`\n\nDisplay executed commands as they are executed. Enabled by default.\n\n#### `import_github_env`\n\nImports variables written so far to `$GITHUB_ENV` to the image. Default is not\nto import any environment. This may be useful for sharing external variables with\nthe virtual environment. Set to `yes` or `true` to enable.\n\nPractically, this setting allows constructs like `${VARIABLE_NAME}` instead of\n`${{ env.VARIABLE_NAME }}` within the command set.\n\n#### `export_github_env`\n\nEnables `$GITHUB_ENV` for commands in the image and exports its contents on\ncompletion to subsequent tasks. This option is an alternative to using a\nfile-based artifact for passing the results of commands outside the image\nenvironment.\n\nNote this parameter does not enable importing any contents written to\n`$GITHUB_ENV` ahead of running the commands. For that, use `import_github_env`.\n\n### Outputs\n\n#### `image`\n\nPath to the image, useful after the step to upload the image as an artifact.\n\n### 32 and 64 bits\n\nMany RaspberryPis and ARM boards are based on 64-bits chipsets than can run\n32 bits and 64 bits kernels. RaspberryPi OS, as well as other distributions,\nare now provided in 32 bits and 64 bits flavors.\n\nThis action works for images built for 32 bits and 64 bits ARM architectures.\nDefault input values imply 32 bits images. For 64 bits, the CPU and the\nbase image should match.\n\nThe following matrix will build on armv6l, armv7l and aarch64 using the latest\nRaspberryPi OS images.\n\n```yaml\nname: Test architecture matrix\non: [push, pull_request, workflow_dispatch]\njobs:\n  build:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        arch: [armv6l, armv7l, aarch64]\n        include:\n        - arch: armv6l\n          cpu: arm1176\n          base_image: raspios_lite:latest\n          cpu_info: raspberrypi_zero_w\n        - arch: armv7l\n          cpu: cortex-a7\n          base_image: raspios_lite:latest\n          cpu_info: raspberrypi_3b\n        - arch: aarch64\n          cpu: cortex-a53\n          base_image: raspios_lite_arm64:latest\n          cpu_info: raspberrypi_zero2_w_arm64_w\n    steps:\n    - uses: pguyot/arm-runner-action@v2\n      with:\n        base_image: ${{ matrix.base_image }}\n        cpu: ${{ matrix.cpu }}\n        cpu_info: ${{ matrix.cpu_info }}\n        commands: |\n            test `uname -m` = ${{ matrix.arch }}\n            grep Model /proc/cpuinfo\n```\n\nInternally, the `cpu` value is embedded in a wrapper for `qemu-arm-static` and\n`qemu-aarch64-static`. The actual qemu invoked depends on executables within\nthe base image.\n\n## Examples\n\nReal world examples include:\n\n-   [pguyot/wm8960](https://github.com/pguyot/wm8960/blob/master/.github/workflows/arm-runner.yml) : compilation and tests\n-   [nabaztag2018/pynab](https://github.com/nabaztag2018/pynab/blob/master/.github/workflows/arm-runner.yml) : compilation, tests and disk image.\n\n## Releases\n\nReleases are listed on [dedicated page](https://github.com/pguyot/arm-runner-action/releases).\nRelease numbers follow semantic versionning : incompatible changes in invocation will be reflected with major release upgrades.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpguyot%2Farm-runner-action","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpguyot%2Farm-runner-action","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpguyot%2Farm-runner-action/lists"}