Skip to content

Test

Test #88

Workflow file for this run

# On-target hardware tests on self-hosted runners.
#
# Triggers:
# - workflow_call: invoked by ci.yml (prebuilt firmware) or manually from other workflows
# - workflow_dispatch: pick branch and test (all or one id from .github/test/tests.yml)
#
# When adding tests, update workflow_dispatch options below and .github/test/tests.yml.
#
# Hardware layout (91m1_ppp + nRF91 Serial Modem):
# - DUT 1 (provision, nRF54L15): provisioning test every CI (recover flash, full onboard)
# - DUT 2 (test, nRF54L15): coredump and FOTA as separate catalog entries on the same rig;
# stays provisioned
# - DUT 3 (provision + location, nRF54LM20 DK + nRF7002-EB2): plain-build cloud
# provisioning and Wi-Fi location verification (recover flash, full onboard)
#
# Runners (dedicated labels; do not rely on the default self-hosted label):
# - self-hosted-build: firmware builds, compliance, SonarCloud (build-A/B/C)
# - self-hosted-test: plan, coredump, and FOTA on DUT 2 (one runner, one job at a time)
# - self-hosted-provisioning: provisioning tests on DUT 1 and DUT 3
#
# CI scheduling:
# - provision, provision-nrf54lm20b, and provision-location start after plan on
# self-hosted-provisioning (DUT 1 and DUT 3), queued one at a time on that runner
# - coredump and FOTA start after plan on self-hosted-test (DUT 2)
# - coredump and FOTA share one test runner, so GitHub queues them one at a time
#
# Prerequisites:
# - Two self-hosted Linux runners with USB access to their DK rig (container: --privileged -v /dev:/dev)
# - SEGGER J-Link is installed in the job container (see run-hardware-test action)
# - Self-signed CA certificate and private key stored in GitHub secrets
# - nRF Cloud API key with permission to onboard/delete devices
#
# GitHub variables (DUT 1 — provisioning):
# CI_NRF54L15_PROVISION_SEGGER_SN
# CI_NRF54L15_PROVISION_SERIAL_MODEM_SEGGER_SN
# CI_NRF54L15_PROVISION_DEVICE_ID
# CI_NRF54L15_PROVISION_SERIAL_PORT (optional)
#
# GitHub variables (DUT 2 — FOTA + coredump, must be provisioned once out-of-band):
# CI_NRF54L15_SEGGER_SN
# CI_NRF54L15_SERIAL_MODEM_SEGGER_SN
# CI_NRF54L15_DEVICE_ID
# CI_NRF54L15_SERIAL_PORT (optional)
#
# GitHub variables (DUT 3 — provisioning + Wi-Fi location on nRF54LM20 DK):
# CI_NRF54LM20B_PROVISION_SEGGER_SN
# CI_NRF54LM20B_PROVISION_SERIAL_MODEM_SEGGER_SN
# CI_NRF54LM20B_PROVISION_DEVICE_ID
# CI_NRF54LM20B_PROVISION_SERIAL_PORT (optional)
#
# GitHub secrets:
# NRF_CLOUD_API_KEY, NRF_CLOUD_CA_CERT, NRF_CLOUD_CA_KEY, MEMFAULT_ORG_TOKEN
#
# GitHub variables (Memfault, linked nRF Cloud project):
# MEMFAULT_ORG, MEMFAULT_PROJECT
# MEMFAULT_COHORT (optional fallback; tests define dedicated cohorts in tests.yml)
# MEMFAULT_FLEET_SAMPLING_CONFIGURATION (optional fleet sampling config ID for dev mode)
name: Test
on:
workflow_call:
inputs:
test:
description: Test id to run, or all for every enabled test
required: false
type: string
default: all
use_prebuilt_firmware:
description: Flash firmware downloaded from the Build workflow instead of rebuilding
required: false
type: boolean
default: false
firmware_version:
description: Release semver embedded in prebuilt firmware (passed to FOTA tests)
required: false
type: string
default: ""
workflow_dispatch:
inputs:
test:
description: Which test to run
required: true
type: choice
default: all
options:
- all
- 91m1_ppp-provision-nrf54l15-nrf91
- 91m1_ppp-provision-nrf54lm20b-nrf91
- 91m1_ppp-provision-location-nrf54lm20b-nrf91
- 91m1_ppp-memfault-coredump-nrf54l15-nrf91
- 91m1_ppp-application-fota-nrf54l15-nrf91
use_prebuilt_firmware:
description: Download firmware artifacts from a prior Build run in this workflow
required: false
type: boolean
default: false
firmware_version:
description: Release semver for prebuilt firmware (optional; FOTA tests derive update as patch+1)
required: false
type: string
default: ""
permissions:
contents: read
jobs:
plan:
runs-on: self-hosted-test
container:
image: ghcr.io/zephyrproject-rtos/ci:v0.29.2
outputs:
run_provision: ${{ steps.resolve.outputs.run_provision }}
run_provision_nrf54lm20b: ${{ steps.resolve.outputs.run_provision_nrf54lm20b }}
run_provision_location: ${{ steps.resolve.outputs.run_provision_location }}
run_coredump: ${{ steps.resolve.outputs.run_coredump }}
run_fota: ${{ steps.resolve.outputs.run_fota }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
path: serial-modem-host-applications
- name: Resolve test selection
id: resolve
working-directory: serial-modem-host-applications
env:
TEST_FILTER: ${{ inputs.test || 'all' }}
run: |
pip install --quiet -r tests/on_target/requirements.txt
PYTHONPATH=tests/on_target python3 -m ci.catalog matrix --filter "$TEST_FILTER"
hardware_provision:
needs: plan
if: needs.plan.outputs.run_provision == 'true'
name: 91m1_ppp-provision-nrf54l15-nrf91
runs-on: self-hosted-provisioning
container:
image: ghcr.io/zephyrproject-rtos/ci:v0.29.2
options: --privileged -v /dev:/dev
env:
CMAKE_PREFIX_PATH: /opt/toolchains
NRFUTIL_HOME: /usr/local/share/nrfutil
CI_USE_PREBUILT_FIRMWARE: ${{ inputs.use_prebuilt_firmware && '1' || '0' }}
FIRMWARE_VERSION: ${{ inputs.firmware_version }}
NRF_CLOUD_API_KEY: ${{ secrets.NRF_CLOUD_API_KEY }}
NRF_CLOUD_CA_CERT: ${{ secrets.NRF_CLOUD_CA_CERT }}
NRF_CLOUD_CA_KEY: ${{ secrets.NRF_CLOUD_CA_KEY }}
CI_NRF54L15_PROVISION_SEGGER_SN: ${{ vars.CI_NRF54L15_PROVISION_SEGGER_SN }}
CI_NRF54L15_PROVISION_SERIAL_MODEM_SEGGER_SN: ${{ vars.CI_NRF54L15_PROVISION_SERIAL_MODEM_SEGGER_SN }}
CI_NRF54L15_PROVISION_SERIAL_PORT: ${{ vars.CI_NRF54L15_PROVISION_SERIAL_PORT }}
CI_NRF54L15_PROVISION_DEVICE_ID: ${{ vars.CI_NRF54L15_PROVISION_DEVICE_ID }}
MEMFAULT_ORG_TOKEN: ${{ secrets.MEMFAULT_ORG_TOKEN }}
MEMFAULT_ORG: ${{ vars.MEMFAULT_ORG }}
MEMFAULT_PROJECT: ${{ vars.MEMFAULT_PROJECT }}
MEMFAULT_COHORT: ${{ vars.MEMFAULT_COHORT }}
MEMFAULT_FLEET_SAMPLING_CONFIGURATION: ${{ vars.MEMFAULT_FLEET_SAMPLING_CONFIGURATION }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
path: serial-modem-host-applications
- name: Run hardware test
uses: ./serial-modem-host-applications/.github/actions/run-hardware-test
with:
test_id: 91m1_ppp-provision-nrf54l15-nrf91
use_prebuilt_firmware: ${{ inputs.use_prebuilt_firmware }}
hardware_provision_nrf54lm20b:
needs: plan
if: needs.plan.outputs.run_provision_nrf54lm20b == 'true'
name: 91m1_ppp-provision-nrf54lm20b-nrf91
runs-on: self-hosted-provisioning
container:
image: ghcr.io/zephyrproject-rtos/ci:v0.29.2
options: --privileged -v /dev:/dev
env:
CMAKE_PREFIX_PATH: /opt/toolchains
NRFUTIL_HOME: /usr/local/share/nrfutil
CI_USE_PREBUILT_FIRMWARE: ${{ inputs.use_prebuilt_firmware && '1' || '0' }}
FIRMWARE_VERSION: ${{ inputs.firmware_version }}
NRF_CLOUD_API_KEY: ${{ secrets.NRF_CLOUD_API_KEY }}
NRF_CLOUD_CA_CERT: ${{ secrets.NRF_CLOUD_CA_CERT }}
NRF_CLOUD_CA_KEY: ${{ secrets.NRF_CLOUD_CA_KEY }}
CI_NRF54LM20B_PROVISION_SEGGER_SN: ${{ vars.CI_NRF54LM20B_PROVISION_SEGGER_SN }}
CI_NRF54LM20B_PROVISION_SERIAL_MODEM_SEGGER_SN: ${{ vars.CI_NRF54LM20B_PROVISION_SERIAL_MODEM_SEGGER_SN }}
CI_NRF54LM20B_PROVISION_SERIAL_PORT: ${{ vars.CI_NRF54LM20B_PROVISION_SERIAL_PORT }}
CI_NRF54LM20B_PROVISION_DEVICE_ID: ${{ vars.CI_NRF54LM20B_PROVISION_DEVICE_ID }}
MEMFAULT_ORG_TOKEN: ${{ secrets.MEMFAULT_ORG_TOKEN }}
MEMFAULT_ORG: ${{ vars.MEMFAULT_ORG }}
MEMFAULT_PROJECT: ${{ vars.MEMFAULT_PROJECT }}
MEMFAULT_COHORT: ${{ vars.MEMFAULT_COHORT }}
MEMFAULT_FLEET_SAMPLING_CONFIGURATION: ${{ vars.MEMFAULT_FLEET_SAMPLING_CONFIGURATION }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
path: serial-modem-host-applications
- name: Run hardware test
uses: ./serial-modem-host-applications/.github/actions/run-hardware-test
with:
test_id: 91m1_ppp-provision-nrf54lm20b-nrf91
use_prebuilt_firmware: ${{ inputs.use_prebuilt_firmware }}
hardware_provision_location:
needs: plan
if: needs.plan.outputs.run_provision_location == 'true'
name: 91m1_ppp-provision-location-nrf54lm20b-nrf91
runs-on: self-hosted-provisioning
container:
image: ghcr.io/zephyrproject-rtos/ci:v0.29.2
options: --privileged -v /dev:/dev
env:
CMAKE_PREFIX_PATH: /opt/toolchains
NRFUTIL_HOME: /usr/local/share/nrfutil
CI_USE_PREBUILT_FIRMWARE: ${{ inputs.use_prebuilt_firmware && '1' || '0' }}
FIRMWARE_VERSION: ${{ inputs.firmware_version }}
NRF_CLOUD_API_KEY: ${{ secrets.NRF_CLOUD_API_KEY }}
NRF_CLOUD_CA_CERT: ${{ secrets.NRF_CLOUD_CA_CERT }}
NRF_CLOUD_CA_KEY: ${{ secrets.NRF_CLOUD_CA_KEY }}
CI_NRF54LM20B_PROVISION_SEGGER_SN: ${{ vars.CI_NRF54LM20B_PROVISION_SEGGER_SN }}
CI_NRF54LM20B_PROVISION_SERIAL_MODEM_SEGGER_SN: ${{ vars.CI_NRF54LM20B_PROVISION_SERIAL_MODEM_SEGGER_SN }}
CI_NRF54LM20B_PROVISION_SERIAL_PORT: ${{ vars.CI_NRF54LM20B_PROVISION_SERIAL_PORT }}
CI_NRF54LM20B_PROVISION_DEVICE_ID: ${{ vars.CI_NRF54LM20B_PROVISION_DEVICE_ID }}
MEMFAULT_ORG_TOKEN: ${{ secrets.MEMFAULT_ORG_TOKEN }}
MEMFAULT_ORG: ${{ vars.MEMFAULT_ORG }}
MEMFAULT_PROJECT: ${{ vars.MEMFAULT_PROJECT }}
MEMFAULT_COHORT: ${{ vars.MEMFAULT_COHORT }}
MEMFAULT_FLEET_SAMPLING_CONFIGURATION: ${{ vars.MEMFAULT_FLEET_SAMPLING_CONFIGURATION }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
path: serial-modem-host-applications
- name: Run hardware test
uses: ./serial-modem-host-applications/.github/actions/run-hardware-test
with:
test_id: 91m1_ppp-provision-location-nrf54lm20b-nrf91
use_prebuilt_firmware: ${{ inputs.use_prebuilt_firmware }}
hardware_coredump:
needs: plan
if: needs.plan.outputs.run_coredump == 'true'
name: 91m1_ppp-memfault-coredump-nrf54l15-nrf91
runs-on: self-hosted-test
container:
image: ghcr.io/zephyrproject-rtos/ci:v0.29.2
options: --privileged -v /dev:/dev
env:
CMAKE_PREFIX_PATH: /opt/toolchains
NRFUTIL_HOME: /usr/local/share/nrfutil
CI_USE_PREBUILT_FIRMWARE: ${{ inputs.use_prebuilt_firmware && '1' || '0' }}
FIRMWARE_VERSION: ${{ inputs.firmware_version }}
NRF_CLOUD_API_KEY: ${{ secrets.NRF_CLOUD_API_KEY }}
NRF_CLOUD_CA_CERT: ${{ secrets.NRF_CLOUD_CA_CERT }}
NRF_CLOUD_CA_KEY: ${{ secrets.NRF_CLOUD_CA_KEY }}
CI_NRF54L15_SEGGER_SN: ${{ vars.CI_NRF54L15_SEGGER_SN }}
CI_NRF54L15_SERIAL_MODEM_SEGGER_SN: ${{ vars.CI_NRF54L15_SERIAL_MODEM_SEGGER_SN }}
CI_NRF54L15_SERIAL_PORT: ${{ vars.CI_NRF54L15_SERIAL_PORT }}
CI_NRF54L15_DEVICE_ID: ${{ vars.CI_NRF54L15_DEVICE_ID }}
MEMFAULT_ORG_TOKEN: ${{ secrets.MEMFAULT_ORG_TOKEN }}
MEMFAULT_ORG: ${{ vars.MEMFAULT_ORG }}
MEMFAULT_PROJECT: ${{ vars.MEMFAULT_PROJECT }}
MEMFAULT_COHORT: ${{ vars.MEMFAULT_COHORT }}
MEMFAULT_FLEET_SAMPLING_CONFIGURATION: ${{ vars.MEMFAULT_FLEET_SAMPLING_CONFIGURATION }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
path: serial-modem-host-applications
- name: Run hardware test
uses: ./serial-modem-host-applications/.github/actions/run-hardware-test
with:
test_id: 91m1_ppp-memfault-coredump-nrf54l15-nrf91
use_prebuilt_firmware: ${{ inputs.use_prebuilt_firmware }}
hardware_fota:
needs: plan
if: needs.plan.outputs.run_fota == 'true'
name: 91m1_ppp-application-fota-nrf54l15-nrf91
runs-on: self-hosted-test
container:
image: ghcr.io/zephyrproject-rtos/ci:v0.29.2
options: --privileged -v /dev:/dev
env:
CMAKE_PREFIX_PATH: /opt/toolchains
NRFUTIL_HOME: /usr/local/share/nrfutil
CI_USE_PREBUILT_FIRMWARE: ${{ inputs.use_prebuilt_firmware && '1' || '0' }}
FIRMWARE_VERSION: ${{ inputs.firmware_version }}
NRF_CLOUD_API_KEY: ${{ secrets.NRF_CLOUD_API_KEY }}
NRF_CLOUD_CA_CERT: ${{ secrets.NRF_CLOUD_CA_CERT }}
NRF_CLOUD_CA_KEY: ${{ secrets.NRF_CLOUD_CA_KEY }}
CI_NRF54L15_SEGGER_SN: ${{ vars.CI_NRF54L15_SEGGER_SN }}
CI_NRF54L15_SERIAL_MODEM_SEGGER_SN: ${{ vars.CI_NRF54L15_SERIAL_MODEM_SEGGER_SN }}
CI_NRF54L15_SERIAL_PORT: ${{ vars.CI_NRF54L15_SERIAL_PORT }}
CI_NRF54L15_DEVICE_ID: ${{ vars.CI_NRF54L15_DEVICE_ID }}
MEMFAULT_ORG_TOKEN: ${{ secrets.MEMFAULT_ORG_TOKEN }}
MEMFAULT_ORG: ${{ vars.MEMFAULT_ORG }}
MEMFAULT_PROJECT: ${{ vars.MEMFAULT_PROJECT }}
MEMFAULT_COHORT: ${{ vars.MEMFAULT_COHORT }}
MEMFAULT_FLEET_SAMPLING_CONFIGURATION: ${{ vars.MEMFAULT_FLEET_SAMPLING_CONFIGURATION }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
path: serial-modem-host-applications
- name: Run hardware test
uses: ./serial-modem-host-applications/.github/actions/run-hardware-test
with:
test_id: 91m1_ppp-application-fota-nrf54l15-nrf91
use_prebuilt_firmware: ${{ inputs.use_prebuilt_firmware }}