Skip to content

Latest commit

 

History

11 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LabWired for GitHub Actions

Run firmware tests in CI against a simulated MCU. No hardware, no toolchain, no self-hosted runner.

name: firmware tests
on: [push, pull_request]

jobs:
  labwired:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write        # hosted report
      pull-requests: write   # results comment
    steps:
      - uses: actions/checkout@v4
      - uses: labwired/firmware-test@v1
        with:
          script: tests/labwired.yml

That's it — no API key and no signup. The simulation runs on your own GitHub runner; LabWired hosts the report.

Inputs

Input Default Description
script (required) Path to your LabWired test script YAML.
firmware "" Firmware ELF, if not set inside the script.
system "" System manifest YAML, if not set inside the script.
output_dir out/artifacts Where result.json, uart.log and junit.xml land.
version v0.18.0 LabWired CLI release tag.
gallery true List public repos at https://app.labwired.com/ci. Set false to stay unlisted.
comment true Post a results comment on pull requests.
allow_unproven false Let an unproven run pass the job.

Outputs

status (pass/fail/error/unproven), report_url, artifacts_dir.

Unproven runs

A twin imported from a schematic contains only the parts LabWired can model. The importer lists the rest as design-only, and LabWired's compiler writes that list into the system manifest as one coverage: line. A run on such a twin can pass every assertion and still say nothing about the board you designed: the op-amp that is not on the twin explains a missing ADC reading as well as a firmware bug does.

So when the manifest carries a coverage record, the action reports one of four verdicts instead of three:

Verdict When
error The run did not complete. Coverage is not consulted.
unproven The run completed, and design-only parts are still missing from the twin, or it passed without asserting anything.
fail An assertion failed on a complete twin.
pass Every assertion passed on a complete twin.

An unproven run fails the job with exit code 4 and an error naming the missing parts. The summary and pull request comment list them, and the gallery shows the run as Unproven. To accept an unproven run while the catalog catches up with your design, set allow_unproven: true. The job's result then follows the simulator's exit code, and every report still says unproven.

A manifest with no coverage record, which includes every hand-written one, is judged exactly as before.

Azure DevOps Pipelines

Vendor the reporter into an azure/ directory in your repository — the pipeline, report_azure.py, and the two modules it shares with the GitHub action (verdict.py and comment.py):

mkdir -p azure
base=https://raw.githubusercontent.com/LabWired/firmware-test/main
curl -fsSL -o azure/azure-pipelines.yml "$base/azure/azure-pipelines.yml"
curl -fsSL -o azure/report_azure.py "$base/azure/report_azure.py"
curl -fsSL -o azure/verdict.py "$base/verdict.py"
curl -fsSL -o azure/comment.py "$base/comment.py"

Set script in the pipeline and push. The same pinned CLI release runs on the agent and the run reports natively:

Surface Where Needs
Assertions Tests tab, via PublishTestResults@2 on the CLI's junit.xml nothing
Build summary Build summary tab (##vso[task.uploadsummary]) nothing
Build tag labwired-pass / labwired-fail / labwired-error / labwired-unproven nothing
Pull request one upserted thread comment System.AccessToken mapped (the example does) and the build service identity granted Contribute to pull requests
Artifacts result.json, uart.log, junit.xml, labwired-summary.md nothing
Hosted report linked from the summary, listed in the gallery System.AccessToken mapped (the example does) and a public Azure DevOps project

The build fails on fail and error, and on unproven unless allow_unproven: true — the same verdicts and exit code 4 as the GitHub action. The reporter reuses the action's verdict.py; to pick up reporter fixes, re-run the vendoring commands above.

The hosted report is authenticated by the pipeline's own System.AccessToken: LabWired asks Azure DevOps for the build record, so no secret is created or stored. Private projects are rejected server-side before the run body is read. Set gallery: false to keep the run unlisted and send run metadata only — no firmware bundle leaves the agent.

Privacy

Private repositories are never uploaded: the action checks github.event.repository.private before sending anything, so no request leaves the runner for a private repo (the API also rejects private repos server-side, as a backstop).

Public repositories are listed in the public gallery by default and their result metadata plus firmware artifact bundle are uploaded. Set gallery: false to opt out — this does not merely unlist the run, it changes what is sent: only run metadata (status, test counts, board, timings) is uploaded, and the firmware artifact bundle is never sent, because a stored bundle is retrievable unauthenticated by hash once it exists. Email andrii@labwired.com to have an existing gallery listing removed.

Uploading is best-effort — if the LabWired API is unreachable, your build still passes or fails on the test result alone.

Licence

MIT.

About

Run LabWired firmware simulation tests in GitHub Actions — no hardware, no toolchain

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages