Stateful CI
Stateful CI tracks benchmark performance over time. Each run merges with historical data, creating a progressive visualization that shows how performance changes across releases.
How It Works
Section titled “How It Works”- Each release run tags benchmarks with the version
- Previous benchmark data is downloaded from artifacts
- Vizb merges old and new data with tag-based deep merge
- The merged result is uploaded as an artifact for the next run
- HTML report shows all versions in a single chart
Tutorial
Section titled “Tutorial”-
Create the workflow
Create
.github/workflows/bench.yml:name: Benchmark Trackingon:push:tags: ['v*']jobs:bench:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- uses: actions/setup-go@v6with:go-version-file: go.mod- name: Download previous benchmark datauses: dawidd6/action-download-artifact@v21continue-on-error: truewith:workflow: bench.ymlname: merged.jsonpath: prev- uses: goptics/vizb@v0with:bench-cmd: "go test -bench=."tag: ${{ github.ref_name }}merge-dir: prevtag-axis: xoutput-json: merged.jsonoutput-html: pages/index.html- uses: actions/upload-artifact@v4with:name: merged.jsonpath: merged.json- uses: peaceiris/actions-gh-pages@v4with:github_token: ${{ secrets.GITHUB_TOKEN }}publish_dir: pages -
Tag a release
Terminal window git tag -s v1.0.0 -m "Release v1.0.0"git push origin v1.0.0This triggers the workflow. The first run creates the initial benchmark. Subsequent tags add to the history.
-
View the results
After the workflow completes:
- The HTML report is deployed to GitHub Pages
- The merged JSON is stored as an artifact
- Next release will download and merge with this data
Key Configuration
Section titled “Key Configuration”| Setting | Value | Why |
|---|---|---|
tag | ${{ github.ref_name }} | Tags each run with the release version |
merge-dir | prev | Merges with previously downloaded data |
tag-axis | x | Shows versions on the X-axis for progressive comparison |
continue-on-error | true | First run has no previous data — that’s OK |
output-json | merged.json | Stores the merged result as an artifact |
The Merge Cycle
Section titled “The Merge Cycle”Release v1.0 → run benchmarks → tag v1.0 → upload merged.json ↓Release v1.1 → download prev → merge v1.0+v1.1 → upload merged.json ↓Release v1.2 → download prev → merge v1.0+v1.1+v1.2 → upload + deployEach run:
- Downloads the previous
merged.jsonartifact - Runs benchmarks with the new tag
- Merges old data with new data (inner merge by tag)
- Uploads the new merged result for the next run