CI integration
Run the same labwired test command on your laptop and in GitHub Actions, GitLab, or Azure Pipelines. Pin a CLI release so firmware changes are judged by a fixed simulator version.
Default pin used in examples: v0.23.0.
Local first
curl -fsSL https://labwired.com/install.sh | LABWIRED_VERSION=v0.23.0 sh
labwired test \
--script tests/firmware-test.yaml \
--output-dir out/labwired \
--junit out/labwired/junit.xml
Exit 0 = pass. Non-zero = fail. Typical artifacts: result.json, uart.log, JUnit XML.
Product page: labwired.com/ci.
GitHub Actions
Use the public action from w1ne/labwired-core. Pin both the action commit and the CLI version.
name: Firmware simulation
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build firmware
run: # your normal firmware build; produce an ELF or flash image
- id: labwired
name: Run LabWired
uses: w1ne/labwired-core/.github/actions/labwired-test@64ed5d9723e2d9f5f4a851a81a3468025671d94e
with:
script: tests/firmware-test.yaml
version: v0.23.0
output-dir: out/labwired
args: --no-uart-stdout
- name: Link the automatic LabWired artifact
if: always()
run: echo "${{ steps.labwired.outputs.artifact-url }}" >> "$GITHUB_STEP_SUMMARY"
The public action reference is an immutable action-source pin to
64ed5d9723e2d9f5f4a851a81a3468025671d94e. Inputs: script (required), version
(default v0.23.0), output-dir, and args. The action downloads that CLI
release, writes JUnit to output-dir/junit.xml, appends summary.md to the job
summary, and always uploads the output directory (including on failure).
Outputs: status, summary-md, report-html, artifact-url, exit-code
(via the labwired step id).
Container runner
The release image uses labwired as the entrypoint. Pass test after the image
name — do not repeat labwired in the container command:
docker run --rm \
--user "$(id -u):$(id -g)" \
--volume "$PWD:/workspace" \
--workdir /workspace \
ghcr.io/w1ne/labwired:v0.23.0 \
test --script tests/firmware-test.yaml \
--output-dir out/labwired \
--no-uart-stdout
When you bind-mount a workspace, pass the caller UID/GID so generated artifacts stay writable on the host.
GitLab CI
Clear the image entrypoint so GitLab can start its job shell. See integration-templates/gitlab-ci.yml:
test:firmware:
image:
name: ghcr.io/w1ne/labwired:v0.23.0
entrypoint: [""]
script:
- labwired test --script tests/firmware-test.yaml --output-dir out/labwired --no-uart-stdout
Azure Pipelines
Install the pinned release on the agent, then publish the CLI's JUnit into the Tests tab:
- script: |
curl -fsSL https://github.com/w1ne/labwired-core/releases/download/v0.23.0/labwired-v0.23.0-linux-x86_64.tar.gz \
| tar -xz -C "$AGENT_TEMPDIRECTORY"
echo "##vso[task.prependpath]$AGENT_TEMPDIRECTORY"
displayName: Install LabWired CLI
- script: labwired test --script tests/firmware-test.yaml --output-dir out/labwired --junit out/labwired/junit.xml --no-uart-stdout
displayName: Run LabWired tests
continueOnError: true
- task: PublishTestResults@2
displayName: Publish LabWired results
condition: succeededOrFailed()
inputs:
testResultsFormat: JUnit
testResultsFiles: '**/junit.xml'
searchFolder: out/labwired
failTaskOnFailedTests: false
For the full example — build summary, build tag, one upserted pull request
comment, and the unproven gate — copy the azure/ directory from
LabWired/firmware-test.
Artifacts
Use --output-dir everywhere. A run writes result.json, uart.log, and JUnit
under that directory. The GitHub action always uploads the directory; other CI
systems should retain it on failure.
Advanced: build from source
cargo build --release -p labwired-cli
./target/release/labwired test \
--script tests/firmware-test.yaml \
--output-dir out/labwired
More templates: integration templates.
What to assert
Use the test script schema: UART substrings, register values, stop reasons, step limits. Prefer checks that match product behavior — not only “boot completed.”
Next
| Run firmware (CLI) | Local install and run / test |
| Test script schema | YAML fields |
| Fidelity | What pass means |
| Troubleshooting | Max steps, empty UART, … |