Skip to content

Performance Monitoring #412

Performance Monitoring

Performance Monitoring #412

# file: .github/workflows/performance-monitoring.yml
# version: 1.1.4
# guid: performance-monitoring-workflow-2025
name: Performance Monitoring
on:
schedule:
- cron: '0 3 * * *'
workflow_dispatch:
push:
branches: [main]
paths:
- 'benchmarks/**'
- 'scripts/**'
- '.github/workflows/performance-monitoring.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
rust-benchmarks:
name: Rust Benchmarks
runs-on: ubuntu-latest
outputs:
average: ${{ steps.capture.outputs.average }}
best: ${{ steps.capture.outputs.best }}
worst: ${{ steps.capture.outputs.worst }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
submodules: recursive
- name: Install toolchain
uses: dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772 # stable
- name: Restore cache
uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
- name: Build benchmark target
run: cargo build --manifest-path testdata/rust/Cargo.toml --release
- name: Prepare benchmark directories
run: |
mkdir -p benchmarks
mkdir -p .github/benchmark-data
- name: Measure Rust benchmark
run: |
python3 scripts/benchmarks/measure_command.py \
--label "Rust Fixture Execution" \
--command "cargo run --release --quiet" \
--workdir testdata/rust \
--iterations 10 \
--output benchmarks/rust.json \
--metadata "command: cargo run --release --quiet"
- name: Capture benchmark metrics
id: capture
run: python3 .github/workflows/scripts/capture_benchmark_metrics.py benchmarks/rust.json
- name: Publish benchmark result
uses: benchmark-action/github-action-benchmark@52576c92bccf6ac60c8223ec7eb2565637cae9ba # v1.22.1
with:
name: Rust Fixture Execution
tool: 'customSmallerIsBetter'
output-file-path: benchmarks/rust.json
summary-always: true
github-token: ${{ secrets.GITHUB_TOKEN }}
external-data-json-path: .github/benchmark-data/rust.json
- name: Upload rust benchmark artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: rust-benchmarks
path: |
benchmarks/rust.json
.github/benchmark-data/rust.json
node-benchmarks:
name: Node.js Benchmarks
runs-on: ubuntu-latest
outputs:
average: ${{ steps.capture.outputs.average }}
best: ${{ steps.capture.outputs.best }}
worst: ${{ steps.capture.outputs.worst }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
submodules: recursive
- name: Install dependencies
working-directory: testdata/node
run: npm install
- name: Prepare benchmark directories
run: |
mkdir -p benchmarks
mkdir -p .github/benchmark-data
- name: Measure Node.js benchmark
run: |
python3 scripts/benchmarks/measure_command.py \
--label "Node Fixture Execution" \
--command "node index.js" \
--workdir testdata/node \
--iterations 10 \
--output benchmarks/node.json \
--metadata "command: node index.js"
- name: Capture benchmark metrics
id: capture
run: python3 .github/workflows/scripts/capture_benchmark_metrics.py benchmarks/node.json
- name: Publish benchmark result
uses: benchmark-action/github-action-benchmark@52576c92bccf6ac60c8223ec7eb2565637cae9ba # v1.22.1
with:
name: Node Fixture Execution
tool: 'customSmallerIsBetter'
output-file-path: benchmarks/node.json
summary-always: true
github-token: ${{ secrets.GITHUB_TOKEN }}
external-data-json-path: .github/benchmark-data/node.json
- name: Upload node benchmark artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: node-benchmarks
path: |
benchmarks/node.json
.github/benchmark-data/node.json
python-benchmarks:
name: Python Benchmarks
runs-on: ubuntu-latest
outputs:
average: ${{ steps.capture.outputs.average }}
best: ${{ steps.capture.outputs.best }}
worst: ${{ steps.capture.outputs.worst }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
submodules: recursive
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97
with:
python-version: '3.11'
- name: Prepare benchmark directories
run: |
mkdir -p benchmarks
mkdir -p .github/benchmark-data
- name: Measure Python benchmark
run: |
python3 scripts/benchmarks/measure_command.py \
--label "Python Fixture Execution" \
--command "python hello_world.py" \
--workdir testdata/python \
--iterations 10 \
--output benchmarks/python.json \
--metadata "command: python hello_world.py"
- name: Capture benchmark metrics
id: capture
run: python3 .github/workflows/scripts/capture_benchmark_metrics.py benchmarks/python.json
- name: Publish benchmark result
uses: benchmark-action/github-action-benchmark@52576c92bccf6ac60c8223ec7eb2565637cae9ba # v1.22.1
with:
name: Python Fixture Execution
tool: 'customSmallerIsBetter'
output-file-path: benchmarks/python.json
summary-always: true
github-token: ${{ secrets.GITHUB_TOKEN }}
external-data-json-path: .github/benchmark-data/python.json
- name: Upload Python benchmark results
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: python-benchmarks
path: |
benchmarks/python.json
.github/benchmark-data/python.json
if-no-files-found: ignore
benchmark-summary:
name: Benchmark Summary
needs: [rust-benchmarks, node-benchmarks, python-benchmarks]
if: always()
runs-on: ubuntu-latest
steps:
- name: Summarize results
env:
RUST_AVG: ${{ needs.rust-benchmarks.outputs.average }}
RUST_BEST: ${{ needs.rust-benchmarks.outputs.best }}
RUST_WORST: ${{ needs.rust-benchmarks.outputs.worst }}
NODE_AVG: ${{ needs.node-benchmarks.outputs.average }}
NODE_BEST: ${{ needs.node-benchmarks.outputs.best }}
NODE_WORST: ${{ needs.node-benchmarks.outputs.worst }}
PYTHON_AVG: ${{ needs.python-benchmarks.outputs.average }}
PYTHON_BEST: ${{ needs.python-benchmarks.outputs.best }}
PYTHON_WORST: ${{ needs.python-benchmarks.outputs.worst }}
run: |
{
printf '## Benchmark Summary\n\n'
printf '| Suite | Average (s) | Best (s) | Worst (s) |\n'
printf '|-------|-------------|----------|-----------|\n'
printf '| Rust | %s | %s | %s |\n' "${RUST_AVG:-n/a}" "${RUST_BEST:-n/a}" "${RUST_WORST:-n/a}"
printf '| Node.js | %s | %s | %s |\n' "${NODE_AVG:-n/a}" "${NODE_BEST:-n/a}" "${NODE_WORST:-n/a}"
printf '| Python | %s | %s | %s |\n' "${PYTHON_AVG:-n/a}" "${PYTHON_BEST:-n/a}" "${PYTHON_WORST:-n/a}"
printf '\n_View individual suite logs for regression alerts and charts._\n'
} >> "$GITHUB_STEP_SUMMARY"