Skip to content

test(meshcore): Phase 2 — companion channel + repeater DM auto-ack messaging system-test #1167

test(meshcore): Phase 2 — companion channel + repeater DM auto-ack messaging system-test

test(meshcore): Phase 2 — companion channel + repeater DM auto-ack messaging system-test #1167

Workflow file for this run

name: System Tests
# Two trigger paths, both opt-in:
# 1. `workflow_dispatch` — manual run from the Actions UI or
# `gh workflow run "System Tests" --ref <branch>`. Use when there's no
# PR open yet, or when iterating on the system-tests scripts.
# 2. PR with the `system-test` label — adding the label flags the PR for
# hardware evaluation; subsequent pushes to the labeled PR re-run the
# suite. Remove the label to stop re-running.
#
# The suite is intentionally NOT triggered on every push. The hardware-
# dependent steps (Yeraze Station G2 DM round-trip, modem-preset round-trip
# via Configuration Import) are slow and serialize through a single
# self-hosted runner — see PR #3082 for the long-running flake history.
on:
workflow_dispatch:
pull_request:
types: [labeled, synchronize]
# Scope concurrency so distinct triggers don't cancel each other unless they
# target the same branch. The self-hosted hardware runner physically
# serializes execution anyway; this just avoids one user superseding
# another's in-progress invocation on the same ref.
concurrency:
group: system-tests-${{ github.head_ref || github.ref }}
cancel-in-progress: true
permissions:
contents: read
pull-requests: write
jobs:
system-tests:
name: System Tests (Hardware)
runs-on: [self-hosted, meshmonitor-hw]
# workflow_dispatch always runs. PR events only run when the
# `system-test` label is set on the PR — either the labeled action
# added that label, or the PR carried it through a synchronize.
if: >
github.event_name == 'workflow_dispatch' ||
(github.event_name == 'pull_request' &&
contains(github.event.pull_request.labels.*.name, 'system-test'))
timeout-minutes: 90
env:
# Skip puppeteer's chrome-headless-shell download during npm install.
# System tests are shell-script API tests with no browser automation,
# so the headless browser is unused on this runner. Without this,
# `npm install --prefer-offline` fails on hosts that don't already
# have the chrome binary cached and can't reach the puppeteer CDN.
PUPPETEER_SKIP_DOWNLOAD: 'true'
steps:
- name: Checkout code
uses: actions/checkout@v7
with:
persist-credentials: false
- name: Initialize submodules
run: git submodule update --init --recursive
- name: Install dependencies
run: npm install --prefer-offline --no-audit --legacy-peer-deps
- name: Create .env file
run: touch .env
- name: Run system tests
run: ./tests/system-tests.sh
- name: Upload test results
if: always()
uses: actions/upload-artifact@v7
with:
name: system-test-results
path: test-results.md
- name: Post results to PR
# Only meaningful when triggered from a PR (the labeled path). On
# workflow_dispatch there is no PR context — results are still in
# the artifact and job logs.
if: always() && github.event_name == 'pull_request'
run: |
if [ -f test-results.md ]; then
{
echo "<details><summary>System Test Results</summary>"
echo ""
cat test-results.md
echo ""
echo "</details>"
} > /tmp/system-test-comment.md
gh pr comment "${{ github.event.pull_request.number }}" \
--body-file /tmp/system-test-comment.md
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}