How to run Arm Virtual Hardware inside GitHub Actions for an efficient CI workflow

November 1, 2022 // 11 min read

image

Arm has integrated with GitHub to revolutionize Internet of Things (IoT) software development leveraging GitHub Actions. With the GitHub Actions workflow, you can execute commands on a Virtual Machine (GitHub runner) hosted by GitHub or via your own hosting. In this guide, we will show you how to use the Arm Virtual Hardware AMI as your self-hosted GitHub runner followed by an example using the GitHub-hosted runner and connect with Arm Virtual Hardware AMI via Arm Virtual Hardware client (avhclient).

Authors: Liliya Wu on behalf of the Arm Software Developer’s Team

Introduction

As a key part of Arm Total Solutions for IoT, Arm Virtual Hardware enables software development in advance of silicon, simplifying the development experience and accelerating Arm-based IoT product development. It delivers test platforms for developers to verify and validate embedded and IoT applications during the complete software design cycle. Arm Virtual Hardware runs as a simple cloud application for simulating memory and peripherals, removing the complexity of building and configuring board farms and removes any delays with hardware delivery. By combining it with modern software development technologies such as CI/CD (DevOps) and MLOps, you will feel the charm brought by cloud-native technology for embedded and IoT application development.

Arm Virtual Hardware is available for Corstone platforms and Cortex processors via an Amazon Machine Image (AMI) on AWS Marketplace as well for 3rd party hardware available via Arm’s SaaS platform. This example we use Arm Virtual Hardware with Corstone platforms and Cortex processors via AWS.

GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform that allows you to automate your build, test, and deployment pipeline. In this step-by-step guide, we will show you how to use Arm Virtual Hardware with GitHub Actions for an efficient CI workflow.

With the GitHub Actions workflow, you can execute commands on a Virtual Machine (GitHub runner) hosted by GitHub or via your own hosting. In this guide, we will show you how to use the Arm Virtual Hardware AMI as your self-hosted GitHub runner followed by an example using the GitHub-hosted runner and connect with Arm Virtual Hardware AMI via Arm Virtual Hardware client (avhclient).

Table of Contents

Requirements

  1. Prepare an AWS account
  2. Prepare a GitHub account
  3. Choose a GitHub repository
    • You can fork ARM-software’s AVH-TFLmicrospeech example project to experience directly or start from scratch with your own project.
    • Please note since the AVH-TFLmicrospeech repository is maintained by the Arm Software Team, the scripts we mention in this blog may not be exactly the same as the latest code you obtained from the repository. The scripts used in this example help you to understand a basic simple workflow using Arm Virtual Hardware with GitHub Actions.

Example 1: self-hosted runner

To run GitHub Actions with Arm Virtual Hardware as a self-hosted runner, start with following five steps:

  1. Setup GitHub Actions runner
  2. Setup AWS EC2 Arm Virtual Hardware instance
  3. Create GitHub Actions workflow
  4. Trigger test workflow
  5. Check dashboard

1. Setup GitHub Actions runner

From your GitHub repository, navigate to Settings>Actions>Runners>New self-hosted runner. Figure 1 GitHub Actions Runners setup page

Currently, Arm Virtual Hardware hosted in AWS only supports 64-bit(x86) Amazon Machine Image (AMI), so select Linux as Runner Image and x64 as Architecture. In the subsequent contents on the same page, some command scripts are generated automatically to help you download the runner package, configure, and create a runner in your self-hosted runner (refers to Arm Virtual Hardware AMI in this use case). The scripts in your own page can be used directly in the next step.

Figure 2 Example of self-hosted Runner setting page

2. Setup AWS EC2 Arm Virtual Hardware instance

Create an Arm Virtual Hardware AMI instance on AWS EC2 and log into the instance using ssh connection command ssh -i <key.pem> ubuntu@<AMI_IP_addr> After connecting successfully, you can see the username change to ubuntu@<AMI_IP_addr>:~$ in the AMI terminal. For more verbose Arm Virtual Hardware AMI instance launch instructions, see this document. By default, when you log in, you are under the base directory /home/ubuntu. Copy scripts under the Download and Configure session directly from your own self-hosted Runner settings page to execute in instance. The token value (specified by --token) is dynamic and may be invalid if you don’t use it in time. Ensure to keep your webpage fresh when you try to configure this in your AMI terminal. Figure 3 Example of self-hosted Runner configuration in the AMI terminal

After using command: ./config.sh --url https://github.com/Your_github_account/Path_to_your_repository --token Your_dynamic_token You will see some prompt information as shown in Figure 3. Enter your custom name or press Enter to use Default name. In Figure3, I specify Arm Virtual Hardware as the name of the runner and add AVH as an additional label. Once the configuration step is finished, run it with command ./run.sh and you will see a prompt information to show the connection is successful. Figure 4 Run Arm Virtual Hardware AMI as a self-hosted runner

Meanwhile, in the self-hosted runner settings page, you will see a runner named as Arm Virtual Hardware and additionally labeled by AVH established. The runner is ready to use and once you trigger the GitHub Action CI test workflow, the jobs will be executed in Arm Virtual Hardware AMI instance directly as your self-hosted runner. Figure 5 Example of self-hosted runner setting page

3. Create GitHub Actions workflow

GitHub Actions are event-driven, meaning that you can run a series of commands after a specified event has occurred. You can configure a GitHub Actions workflow to be triggered when an event occurs in your repository. A repository can have multiple workflows, each of which can perform a different set of tasks and they are defined in the YAML file under .github/workflows directory in a repository. If you are new to GitHub Actions, see Understanding GitHub Actions to learn some core concepts and essential terminology of GitHub Actions, or refer to GitHub Actions Guide for more verbose features.

We already defined a basic workflow in AVH-TFLmicrospeech repository to help you get started with Actions on CMSIS projects. For further details, see virtual_hardware_sh.yml, which enables GitHub Actions CI tests running on the Arm Virtual Hardware AMI instance as a self-hosted runner using the following steps:

a) Set workflow name

name: Arm Virtual Hardware example - self-hosted (AWS) runner

b) Set trigger event.

on: # To allow you to run this workflow manually from the GitHub Actions tab add workflow_dispatch:

If you hope to trigger the workflow on every push or pull request events for the "main" branch, remove the comment symbol # before the command line as below:

on:
# Triggers the workflow on push or pull request events but only for the "main" branch push:
branches: [ main ]

pull_request: branches: [ main ]

# To allow you to run this workflow manually from the GitHub Actions tab add
__  workflow_dispatch:

c) Set jobs details for this workflow. Below is a part of the code, see full code scripts at virtual_hardware_sh.yml. This workflow has only one job named ci_demonstration. By using command runs-on:self-hosted, it will allow this ci_demonstration job to be executed in self-hosted runners which is the Arm Virtual Hardware AWS AMI instance in this use case.

jobs:
  ci_demonstration:
    runs-on: self-hosted.
    env:
      working-directory: ${{ github.workspace }}/Platform_FVP_Corstone_SSE-300_Ethos-U55/
steps:
      - name: Check out repository code
        uses: actions/checkout@v2

      - name: What has been cloned?
        run: echo "${{ github.repository }} has been cloned."
        …

It takes several steps to finish this job. In the provided example, the script finishes a process using the CMSIS-Build toolchain to build a simple CMSIS project and make it run on Corstone-300 FVP Platform. If you are not familiar with the YAML syntax, see Understanding the workflow file and Workflow syntax for GitHub Actions. Note, these steps depend on what you hope to do in your CI test.

4. Trigger test workflow

As mentioned in step 3, if you don’t change any code in the provided YAML file, you can only trigger the GitHub Actions CI test manually from the GitHub Actions tab. Navigate to Actions>Arm Virtual Hardware example - self-hosted (AWS) runner>Run workflow and click Run workflow to trigger the GitHub Actions CI test. When you run the test, ensure your Arm Virtual Hardware AMI instance keeps running and is well connected to the GitHub. You will also see some test log information in your AMI terminal.

Figure 6 Example of GitHub Actions CI test

5. Check dashboard

The test results will be displayed in the visualizer dashboard in the Actions Page. You can click on each workflow to see more running details like jobs, steps, and time duration. The live log provided can conveniently help you figure out whether the test has failed or not and why.

Figure 7 Example of visualizer dashboard

When running GitHub Actions with the Arm Virtual Hardware AMI as your self-hosted runner, you need to manually launch, configure, and stop the AMI instance. Please remember to terminate the instance when you no longer need your CI test otherwise you will be charged. For detailed pricing information, see the Arm Virtual Hardware AMI product page in AWS Marketplace. You can also register to access 100 hours worth of free AWS EC2 CPU credits from Arm and AWS here.

Example 2: GitHub-hosted runner

As mentioned above, with GitHub-hosted runner, you can execute part of the actions(such as testing) on the Arm Virtual Hardware AMI instance by using Arm Virtual Hardware Client (avhclient). avhclient is a python module that manages remote connection, upload, build, and execution of programs on the Arm Virtual Hardware AMI instances. See Run AMI with GitHub Actions for a more detailed explanation of GitHub Actions workflow between GitHub Runner and Arm Virtual Hardware AMI instance.

To run GitHub Actions with GitHub-hosted runner, start with following five steps:

  1. Setup AWS infrastructure
  2. Create GitHub Actions workflow
  3. Configure GitHub Actions secrets
  4. Trigger test workflow
  5. Check dashboard

1. Setup AWS infrastructure

As mentioned above, we use the avhclient to deploy projects on Arm Virtual Hardware from a command-line interface, so we need to setup the AWS infrastructure at first to ensure that all resources required for running avhclient are available.

The simplest way to do this is explained verbosely in Arm Virtual Hardware AWS-CloudFormation repository and it relies on AWS CloudFormation service with the template file to create necessary AWS resources and obtain the values required for AWS backend setup. Once you have finished, as shown in Figure 8 in the Ouput tab, you will obtain several items as below which you may need for using an Arm Virtual Hardware AMI. Remember the region where you have established the stack (Shown in the upper right corner of the page, on the same line as your AWS Account information) as this will be used too.

  • One S3 Bucket to store temporary files.
  • One EC2 Security Group to be associated with the EC2 instances.
  • One IAM User and Access Keys to limit access rights in the AWS.
  • One IAM Role to be associated with the EC2 Instances.

Figure 8 Example of CloudFormation Service Output

2. Create GitHub Actions workflow

We have already defined a basic workflow in AVH-TFLmicrospeech repository to help you get started with Actions on CMSIS projects using the GitHub-hosted runner. See more details at virtual_hardware_gh.yml.

a). Set workflow name

name: Arm Virtual Hardware example - github hosted - remote AWS via avhclient

b) Set trigger event.

on:
# To allow you to run this workflow manually from the GitHub Actions tab add
  workflow_dispatch:

c) Set environment variables. You need to pass your AWS infrastructure information to avhclient for automatic operation with the Arm Virtual Hardware AMI instance. For account security protection, we use GitHub Actions Secrets to deliver the value to related environment variables.

env:
  AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
  AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
  AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }}
  AWS_S3_BUCKET_NAME: ${{ secrets.AWS_S3_BUCKET_NAME }}
  AWS_IAM_PROFILE: ${{ secrets.AWS_IAM_PROFILE }}
  AWS_SECURITY_GROUP_ID: ${{ secrets.AWS_SECURITY_GROUP_ID }}
  AWS_SUBNET_ID: ${{ secrets.AWS_SUBNET_ID }}

d). Set jobs details for this workflow.

This workflow has only one job named arm_virtual_hardware. By using command runs-on:ubuntu-latest, the actions is to run in an ubuntu-based runner hosted by GitHub.

 jobs:
  arm_virtual_hardware:
runs-on: ubuntu-latest
steps:
  - uses: actions/checkout@v2
  - name: Set up Python 3.10
uses: actions/setup-python@v2
with:
  python-version: '3.10'
  - name: Install AVH Client for Python
run: |
  pip install git+https://github.com/ARM-software/avhclient.git@v0.1.1
  - name: Execute test suite on Arm Virtual Hardware at AWS
run: |
  avhclient -b aws execute --specfile ./avh.yml
  - name: Fetch results from Arm Virtual Hardware
run: |
   cat ./Platform_FVP_Corstone_SSE-300_Ethos-U55/microspeech.log

In the provided example, the scripts install python 3.10 and avhclient in the GitHub-hosted runner. Then, by using command avhclient -b aws execute --specfile ./avh.yml, it will specify aws as the avhclient backend by -b and specify avh.yml under current directory as YAML specfile by --specfile to run avhclient execute command. To check more verbose and the latest details about how the avhclient works, visit Arm-Software’s avhclient repository. For more details of what this CI test will do in the Arm Virtual Hardware instance, see avh.yml file.

3. Configure GitHub Actions secrets

As mentioned in step 2, we use GitHub Actions Secrets to configure running environment variables. Navigate to Settings>Secrets>Actions>New repository secret and add all the secrets you need in your own workflow YAML file.

Figure 9 GitHub Actions Configuration page

In provided example, add the following secret list to your repository’s Secrets.

GitHub Actions Secrets Places to find value
AWS_ACCESS_KEY_ID In CloudFormation Service Output Tab shown in step1
AWS_SECRET_ACCESS_KEY In CloudFormation Service Output Tab shown in step1
AWS_DEFAULT_REGION The region that you use CloudFormation Service to create the stack. The value is next to your account.
AWS_S3_BUCKET_NAME In CloudFormation Service Output Tab shown in step1
AWS_IAM_PROFILE In CloudFormation Service Output Tab shown in step1
AWS_SECURITY_GROUP_ID In CloudFormation Service Output Tab shown in step1
AWS_SUBNET_ID In VPC Service

Figure 10 Example of GitHub Actions Secrets configuration

4. Trigger test workflow

Similar to step 4 when using a self-hosted runner, the provided sample workflow can only be triggered manually from the GitHub Actions tab. When you trigger the GitHub Actions workflow using your provided AWS infrastructure information, an instance will be automatically launched and terminated in your AWS EC2 console. Log into your AWS EC2 console and you will find an instance named as runner@unknown is running when the GitHub Actions workflow is running.

Figure 11 Example of GitHub Actions CI test

Figure 12 Instance is launched automatically in your AWS EC2 Console

5. Check dashboard

Check with the visualizer dashboard in Actions Page to see more workflow running details.

Figure13 Example of visualizer dashboard

When running GitHub Actions with a GitHub-hosted runner, avhclient will help you launch, configure, and stop the AMI instance automatically and you don’t need to worry about forgetting to terminate your instance which may cause extra expense. Please note that since the GitHub Runner (Virtual Machine to run GitHub Actions workflow) is provided by GitHub, please learn more about potential billing expenses and the runner configuration details via Billing for GitHub Actions.

To briefly summarize, the major differences between a self-hosted runner and a GitHub-hosted runner can be found in the following table. You can use each way according to your demands.

Table I Differences between a self-hosted runner and a GitHub-hosted runner when using Arm Virtual Hardware with GitHub Actions

Difference Self-hosted runner GitHub-hosted runner
Runner to execute the actions All actions are executed in the Arm Virtual Hardware AMI instance A) Part of the actions are executed in a standard runner provided by GitHub. B) Part of the actions (such as testing) are executed in the Arm Virtual Hardware AMI instance.
Benefits A) Highly customize your testing environment in one time and keep it used for all tests. B) Shorten overall test time, without waiting for instances to be ready in every test. A) The Arm Virtual Hardware AMI instance will be launched and terminated automatically to help control the budget.

Conclusions

This guide has shown you how to use the Arm Virtual Hardware AMI with GitHub Actions in both self-hosted runner and GitHub-hosted runner use cases. The provided example project demonstrates a basic sample workflow to get started with GitHub Actions and Arm Virtual Hardware on CMSIS projects. Don’t hesitate to try the sample code or start with your own Arm-based projects. We are excited for you to experience the efficient CI workflow brought by Arm Virtual Hardware and GitHub Actions!

Learn More

Wondering how GitHub can help your business?

Tell us more about your needs

octocaptcha spinner