PR report bot
Bowire runs on the developer's machine, so a reviewer sees the code diff but
nothing about the API impact of a pull request. The bowire-pr GitHub
Action closes that gap: it runs the API-schema delta, the test suite, and the
security scan on the PR's head, and posts a single comment — updated in
place on every push — with what changed.
## Bowire PR report
| Section | Status |
| --- | --- |
| API schema | 🟢 |
| Tests | 🔴 |
| Security | 🟢 |
**API schema:** +2 methods, ~1 changed.
...
The API-delta section needs an unreleased CLI.
bowire difflanded after the v2.4.0 tag, so no publishedKuestenlogik.Bowire.Toolcarries it yet. Until the next release, that section only works withbuild-from-source: trueand a checked-out Bowire tree; leavebase-snapshotunset to skip it. Every other section works against the published CLI (tracked in #582).
What it does
| Section | Command behind it | Gate input |
|---|---|---|
| API schema | bowire diff — a base snapshot vs. a head snapshot captured from the running target |
fail-on-schema: none \| breaking \| any |
| Tests | bowire test --junit |
fail-on-tests: any \| never |
| Security | bowire scan + bowire scan report --baseline |
fail-on-scan: never \| any |
| Perf | the head JUnit report's per-test timings vs. a base-branch JUnit (test-baseline) |
fail-on-perf: never \| any |
The Perf section needs no separate benchmark run: bowire test --junit already
times every test case, so the latency delta is a diff over two reports you
already produce. A test is only listed when it moved past both thresholds —
relative (perf-threshold-pct) and absolute (perf-threshold-ms) — so a 2 ms
test drifting to 4 ms doesn't fill the comment with runner noise.
Everything runs inside the runner — the action hits your service on localhost,
never calls back to Bowire infrastructure, and no secrets leave the job.
Minimal usage
The action captures the head snapshot itself from the running service; the base snapshot is captured on the base branch and handed over so the diff has something to compare against. The canonical shape is a two-step job:
name: Bowire PR report
on: pull_request
permissions:
contents: read
pull-requests: write # for the comment upsert
jobs:
bowire:
runs-on: ubuntu-latest
steps:
# 1. Capture the base snapshot: check out the base branch, start the
# service, and snapshot its API surface.
- uses: actions/checkout@v7
with:
ref: ${{ github.event.pull_request.base.sha }}
- name: Start the base service
run: ./scripts/start-service.sh & # your service on :8080
- name: Capture base snapshot
run: |
dotnet tool install -g Kuestenlogik.Bowire.Tool
bowire diff snapshot http://localhost:8080 -o base.snapshot.json
# 2. Check out the head, start the service, run the report.
- uses: actions/checkout@v7
- name: Start the head service
run: ./scripts/start-service.sh &
- uses: Kuestenlogik/bowire-action@v1
with:
target: http://localhost:8080
base-snapshot: base.snapshot.json
fail-on-schema: breaking # a removed method / signature change fails the check
Drop base-snapshot and the API-schema section is simply skipped — the Tests
and Security sections still run against target.
Inputs
| Input | Default | Notes |
|---|---|---|
target |
— (required) | URL of the running head service. |
protocol |
(guessed) | Discovery plugin id (rest, grpc, graphql, …). |
base-snapshot |
(none) | Base-branch schema snapshot; empty skips the API section. |
test |
(none) | Recording / flow JSON for bowire test; empty skips Tests. |
scan |
true |
Run bowire scan against the target. |
scan-templates |
(none) | Vulnerability-template directory. |
scan-baseline |
(none) | Base scan SARIF, for new/fixed findings. |
test-baseline |
(none) | Base-branch JUnit XML, for the per-test latency delta; empty skips Perf. |
perf-threshold-pct |
20 |
Only report a test whose latency moved more than this percentage. |
perf-threshold-ms |
5 |
Absolute floor a move must also clear — keeps runner noise on very fast tests out. |
fail-on-schema |
none |
none | breaking | any. |
fail-on-tests |
any |
any | never. |
fail-on-scan |
never |
never | any. |
fail-on-perf |
never |
never | any. |
tool-version |
(latest) | Pin a specific Kuestenlogik.Bowire.Tool. |
When the workflow is not a pull_request (e.g. workflow_dispatch), the report
is written to the run summary instead of posted — handy for a dry run.
Related
bowire diff— the schema-delta command the API section uses.- Security scanning — the
bowire scanlane. - CI setup — running
bowire testas a CI gate.