CI/CD Integration

You can integrate the Testbox into your CI/CD setup. To do this, you need a computer that is connected to the Internet and to which the test box is connected. At the moment we are using a setup with a Raspberry PI 5. We provide an Image on Docker Hub for the Raspberry Pi 5 which has installed all neccessary libraries which are needed to run a test. In the following chapters, you will find step-by-step instructions for various CI/CD tools.

Github

You can find an example for an automated test with our testbox in our example project on Github: Tasterplatine. The description below will explain all steps for this example.

Setup Runner

First you have to install the action-runner on your PC. Open your Repository in your browser.

Click on Settings –> Actions –> Runners

Create Acrion Runner

Click on the top right Button New self-hostet runner.

Choose your operating system and Architecture and run all displayed commands on your PC.

With the given commands you start the runner manually. If you want to start your runner automatically on each boot, run:

  • On Linux:

    • sudo ./svc.sh install

    • sudo ./svc.sh start

  • On Windows:

    • .\svc install

    • .\svc start

If your setup runs correctly - your runner should be displayed in green with the state “Idle” on the Action-runner page on Github. For example:

Create Acrion Runner

Now your setup is ready to run automated tests!

In the next step you have to define your workflow.

Create Workflow

The easiest way to create a new Workflow is to open your repository on github in the webbrowser, klick on Actions and use the link set up a workflow yourself.

Create new Workflow

Copy & Paste the following configuration:

name: Build and Test

on:
push:
    branches:
    - main

jobs:
build:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
    uses: actions/checkout@v3

    - name: Build STM32CubeIde project
    uses: xanderhendriks/action-build-stm32cubeide@v11.0
    with:
        project-path: '.'
        project-target: 'Testplatine'
    env:
        ENV_VERSION_MAJOR: 1
        ENV_VERSION_MINOR: 0
        ENV_VERSION_BUGFIX: 0

    - name: Upload build artifacts
    uses: actions/upload-artifact@v4
    with:
        name: build-artifact
        path: Debug/Testplatine.bin

remote-test:
    needs: build
    runs-on: [self-hosted, linux]

    steps:
    - name: Checkout code
    uses: actions/checkout@v3

    - name: Download artifact
    uses: actions/download-artifact@v4
    with:
        name: build-artifact
        path: ./firmware

    - name: Run Test
    env:
        test-project-folder: "Tests"
        test-project-file: "project.etp"
    run: |
        docker pull emintes/testplattform:arm64
        docker run --rm --name test-container --device=/dev --privileged \
        -v "${{ github.workspace }}:/workspace/repo" \
        -e TEST_PROJECT_FOLDER="${{ env.test-project-folder }}" \
        -e TEST_PROJECT_FILE="${{ env.test-project-file }}" \
        -e EXTRA_COMMANDS="${{ env.extra-commands }}" \
        emintes/testplattform:arm64
    - name: Upload Testreport artifact
    if: always()
    uses: actions/upload-artifact@v4
    with:
        name: Testreport
        path: Tests/Reports/Testreport.html

Description:

This workflow contains of two jobs: build and remote-test.

The build job runs on github hostet runner and consits of three steps:

  • Checkout code: to checkout your repository

  • Build STM32CubeIde project: compiles your code. In our example its code, written in STM32Cube IDE. So we are using the xanderhendriks/action-build-stm32cubeide action for compiling the code. This step must be adapted to your development environment.

  • Upload build artifacts: This uploads the firmware-binary as an artifact.

The remote-test job runs on the self-hostet runner and consits of the following steps:

  • Checkout code: to checkout your repository

  • Download artifact: to download the previously built firmware-artifact.

  • Run Test: here the test gets executed in a docker container. For detailed description of all parameteres, see documentation on docker-hub

  • Upload Testreport artifact: when the test is finished, we upload the testreport as an artifact to github.

After a successfully run of this workflow, we get this result:

Workflow Result

In the middle you see that the build job has passed successfully and the remote-test too.

On the bottom area you can now download the Testreport and the firmware-file of this run.

Azure DevOps

Setup Agent

Create an Agent Pool in Azure DevOps

  • Go to your project in Azure DevOps.

  • Click the gear icon (Project settings) in the top-right corner.

  • Select Agent pools on the left.

  • Click Add pool → give it a name (e.g., SelfHostedPool).

  • Optional: Grant access permission to all pipelines aktivieren, damit der Pool ohne Extra-Rechte nutzbar ist.

Register a Self-Hosted Agent

  • Select your newly created agent pool.

  • Click on New agent.

  • Choose the operating system of the target machine (Windows, Linux, Mac).

  • Azure DevOps will show exact commands to download and register the agent.

  • When running ./config.sh (Linux) or config.cmd (Windows), you will be prompted for:

    • Server URL: https://dev.azure.com/<org-name>

    • Authentication type: PAT (Personal Access Token)

    • Agent pool: Name of your pool (SelfHostedPool)

    • Agent name: Any name, e.g., build01

Create a Personal Access Token (PAT)

  • In Azure DevOps, click your profile picture in the top-right → Personal access tokens.

  • Click New Token:

    • Scope: at least Agent Pools (read, manage)

    • Organisation: select your organization.

    • Expiration date: set appropriately (not too short if you want it to run continuously)

  • Enter this token when prompted in config.sh or config.cmd.

Start Agent

  • run ./run.sh on linux or .\run.cmd on Windows.

Autostart Agent

To start your agent automatically on each boot, run:

  • On Linux:

    • sudo ./svc.sh install

    • sudo ./svc.sh start

  • On Windows:

    • .\svc install

    • .\svc start

Create Pipeline

Go to your Azure DevOps project. In the left-hand menu, click Pipelines. Then click on New pipeline (usually top-right).

Azure DevOps - create new pipeline

Choose the repository containing your code.

You may need to authorize Azure DevOps if using GitHub or another external repo.

Configure your Pipeline

Use Starter pipeline - this will create a minimal YAML template to start with.

Here is an example for the Tasterplatine example project:

trigger:
- master

jobs:
- job: Build
displayName: 'build'
pool:
    vmImage: 'ubuntu-latest'  # Microsoft hostet Agent
container:
    image: 'xanderhendriks/stm32cubeide:15.1'

steps:
- checkout: self
    displayName: 'Checkout code'

- script: |
    echo "Start Build for Testplatine..."
    echo $(Build.SourcesDirectory)
    cd $(Build.SourcesDirectory)
    stm32cubeide --launcher.suppressErrors -nosplash -application org.eclipse.cdt.managedbuilder.core.headlessbuild -data /tmp/stm-workspace -importAll $(Build.SourcesDirectory)
    headless-build.sh -data /tmp/stm-workspace -build "Testplatine/Debug"
    displayName: 'Build STM32CubeIde project'

- script: ls $(Build.SourcesDirectory) -R
    displayName: List files

- task: PublishBuildArtifacts@1
    inputs:
    pathToPublish: '$(Build.SourcesDirectory)/Debug/Testplatine.bin'
    artifactName: 'DebugBinary'
    publishLocation: 'Container'
    displayName: 'Upload build artifacts'

- job: remote_test
displayName: 'remote test'
dependsOn: Build      # wait until build is finished
pool:
    name: SelfHostedPool
steps:
- checkout: self
    displayName: 'Checkout code'

- task: DownloadBuildArtifacts@0
    inputs:
    buildType: 'current'
    downloadType: 'single'
    artifactName: 'DebugBinary'
    downloadPath: '$(Build.SourcesDirectory)/firmware'  # Target folder
    displayName: 'Download build artifact'

- script: |
    docker pull emintes/testplattform:arm64
    docker run --rm --name test-container --device=/dev --privileged \
        -v "$(Build.SourcesDirectory):/workspace/repo" \
        -e TEST_PROJECT_FOLDER="$test_project_folder" \
        -e TEST_PROJECT_FILE="${{ env.test_project_file }}" \
        -e EXTRA_COMMANDS="$extra_commands" \
        emintes/testplattform:arm64
    displayName: 'Run Test'
    env:
    test_project_folder: "Tests"
    test_project_file: "project.etp"
    extra_commands: ""

- task: PublishBuildArtifacts@1
    condition: always()
    inputs:
    pathToPublish: 'Tests/Reports/Testreport.html'
    artifactName: 'Testreport'
    publishLocation: 'Container'
    displayName: 'Upload Testreport artifact'

The Result of this Pipeline looks like this:

Azure DevOps - pipeline run - result

By clicking on the 2 published link you will see the artifacts of this run:

Azure DevOps - pipeline run - Artifacts