Back to buildstats

DOCS

GitHub Action

Every input and output of the buildstats GitHub Action with defaults, the metric line and JSON formats, matrix variants, max-regression gates, strict mode and when the step fails.

Updated October 7, 2026

01

Usage

buildstats-io/action@v1 needs id-token: write to sign the push with the workflow's OIDC token, or a token. push runs record on the branch, pull_request runs on the pull request, and merge_group runs are not recorded.

.github/workflows/build.yml
permissions:  contents: read  id-token: write       # sign in with GitHub OIDC  pull-requests: write  # comment on pull requests steps:  - uses: buildstats-io/action@v1    id: buildstats    with:      metrics: |        bundle_size=${{ env.size }} bytes lower        coverage=87.2 % higher  - run: echo "Charts at ${{ steps.buildstats.outputs.url }}"
02

Inputs

Every input is optional, but a push needs at least one metric from metrics or file.

metrics
Metrics as lines, name=value [unit] [higher|lower], or as JSON.
file
Path to a JSON file with metrics in either JSON shape. Combines with metrics.
variant
Stores every metric of this push as name/variant, for matrix builds: variant: ${{ matrix.os }}.
comment
Comment the results on the pull request. Default true.
summary
Write the results to the job summary. Default true.
max-regression
Fail the step when a metric with a direction got worse than its base by more than this percentage, like 5 or 5%.
claim
One-time claim code (bsc_...) that links the project to your account. Pass it from a secret.
token
Project API key (bs_...) to push without OIDC. Pass it from a secret.
sha
Commit to record, for workflow_run and pull_request_target runs.
ref
Ref to record, for workflow_run and pull_request_target runs.
pr
Pull request number, for workflow_run and pull_request_target runs.
base-ref
Branch to compare against. Defaults to the pull request base, else the default branch.
api
API URL. Default https://buildstats.io.
strict
Fail the step on rate limits and on metrics that were not stored, instead of warning. Default false.
github-token
Token for the pull request comment. Default ${{ github.token }}.
03

Outputs

Give the step an id to read them, like ${{ steps.buildstats.outputs.url }}.

url
Project page on buildstats.io.
results
JSON array with one entry per metric: name, value, stored, error, previous, base, delta, delta_pct, verdict, chart_url and badge_url. Needs jq on the runner.
04

Metric format

One metric per line:

Format
name=value [unit] [higher|lower]
  • name: letters, digits, _, . and -, up to 64 characters, not starting with . or -. Names can't end in .svg or .json, and badge and points are taken.
  • value: a number like 1832, 87.2, -3 or 1e6. A unit right after the number works too: 87.2%, 120ms.
  • unit: optional, up to 16 characters.
  • higher or lower: which direction is better, needed for verdicts and max-regression.

Blank lines and lines starting with # are skipped. JSON works as well, inline in metrics or as a file passed to file:

buildstats.json
{ "coverage": 87.2, "bundle": { "value": 12.4, "unit": "kB", "better": "lower" } }
buildstats.json
[{ "name": "tests", "value": 1832, "better": "higher" }]

metrics and file combine. A push carries up to 50 metrics, and a project holds up to 100.

05

Matrix builds

Legs that measure the same thing on different runners push the same names with a variant. Each leg is stored as name/variant, here build_time/ubuntu-latest and build_time/macos-latest, and the chart for build_time draws every variant as its own line.

.github/workflows/build.yml
jobs:  build:    strategy:      matrix:        os: [ubuntu-latest, macos-latest]    runs-on: ${{ matrix.os }}    steps:      - uses: actions/checkout@v7      - run: ./build.sh      - uses: buildstats-io/action@v1        with:          variant: ${{ matrix.os }}          metrics: build_time=${{ env.seconds }} s lower

All legs of a pull request run share one comment.

06

Failing on regressions

max-regression: 5 fails the step when a metric marked higher or lower got worse than its base by more than 5%. The comment and the job summary are written first, so the numbers are there when you look. Metrics without a base yet never fail the step, and a metric whose base is 0 fails on any change for the worse.

07

When the step fails

  • Bad input, like a metric line that does not parse or a missing id-token: write permission.
  • An API error, after retrying server errors and network failures 3 times.
  • A regression beyond max-regression.

Rate limits and metrics the server did not store, like a full series, a locked project or a matrix leg pushing a different value for the same metric, are warnings. Set strict: true to fail on them. Merge queue runs are never stored and only get a notice, even with strict. Pull requests from forks are skipped with a notice, see fork pull requests.

08

Self-hosted runners

The push only needs bash and curl, and jq when JSON metrics are an object instead of an array. With jq installed you also get the results output, the job summary, the pull request comment and max-regression, and the comment also needs gh. Works with the bash 3.2 that ships with macOS.

Still have a question?Talk to us