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 diff landed after the v2.4.0 tag, so no published Kuestenlogik.Bowire.Tool carries it yet. Until the next release, that section only works with build-from-source: true and a checked-out Bowire tree; leave base-snapshot unset 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.