44 push :
55 branches : [ main ]
66 paths :
7- - ' crates/rust-hsm-cli/src/pkcs11/benchmark.rs'
7+ - ' crates/rust-hsm-cli/src/**'
8+ - ' crates/rust-hsm-core/src/**'
89 - ' .github/workflows/benchmark.yml'
910 schedule :
1011 # Run weekly on Sunday at 2am UTC
1718 runs-on : ubuntu-latest
1819 steps :
1920 - uses : actions/checkout@v4
21+ with :
22+ fetch-depth : 0 # Fetch full history for gh-pages branch creation
2023
2124 - name : Set up Docker Buildx
2225 uses : docker/setup-buildx-action@v3
@@ -27,61 +30,126 @@ jobs:
2730 - name : Start container
2831 run : docker compose up -d
2932
30- - name : Wait for container
31- run : sleep 5
33+ - name : Wait for container to be ready
34+ run : sleep 10
3235
33- - name : Initialize test token
36+ - name : Initialize test token using rust-hsm-cli
3437 run : |
35- docker exec rust-hsm-app softhsm2-util --init-token \
36- --slot 0 --label BENCH_TOKEN \
37- --so-pin 12345678 --pin 123456
38+ docker exec rust-hsm-app rust-hsm-cli init-token \
39+ --label BENCH_TOKEN --so-pin 12345678
40+ docker exec rust-hsm-app rust-hsm-cli init-pin \
41+ --label BENCH_TOKEN --so-pin 12345678 --user-pin 123456
3842
39- - name : Run benchmark
43+ - name : Run benchmark with rust-hsm-cli
4044 run : |
4145 docker exec rust-hsm-app rust-hsm-cli benchmark \
4246 --label BENCH_TOKEN --user-pin 123456 \
43- --iterations 1000 --warmup 50 \
44- --format json --output /app/benchmark-results.json
47+ --iterations 50 --warmup 5 \
48+ --format json --output /app/benchmark-results.json \
49+ --data-sizes
4550
46- - name : Copy results
51+ - name : Copy benchmark results
4752 run : |
53+ # Copy the main results file
4854 docker cp rust-hsm-app:/app/benchmark-results.json ./benchmark-results.json
55+
56+ # Copy GitHub Actions format file (automatically generated by rust-hsm-cli)
4957 docker cp rust-hsm-app:/app/benchmark-results-gh.json ./benchmark-results-gh.json
58+
59+ # Verify files exist and show samples
60+ echo "=== Main benchmark results ==="
61+ head -20 benchmark-results.json
62+
63+ echo "=== GitHub Actions format ==="
64+ head -20 benchmark-results-gh.json
65+
66+ - name : Setup gh-pages branch if needed
67+ run : |
68+ git config --global user.name 'github-action-benchmark'
69+ git config --global user.email 'github@users.noreply.github.com'
70+
71+ # Check if gh-pages exists remotely
72+ if ! git ls-remote --exit-code --heads origin gh-pages > /dev/null 2>&1; then
73+ echo "Creating gh-pages branch..."
74+ git checkout --orphan gh-pages
75+ git rm -rf .
76+ echo "# HSM Performance Benchmarks" > README.md
77+ echo "" >> README.md
78+ echo "Automated benchmark results for rust-hsm PKCS#11 operations." >> README.md
79+ echo "" >> README.md
80+ echo "Generated by [github-action-benchmark](https://github.com/benchmark-action/github-action-benchmark)." >> README.md
81+ git add README.md
82+ git commit -m "Initialize gh-pages branch for benchmarks"
83+ git push origin gh-pages
84+ git checkout main
85+ echo "✓ Created gh-pages branch"
86+ else
87+ echo "✓ gh-pages branch already exists"
88+ fi
5089
5190 - name : Store benchmark result
5291 uses : benchmark-action/github-action-benchmark@v1
5392 with :
54- tool : ' customBiggerIsBetter'
93+ name : ' HSM Performance Benchmarks'
94+ tool : ' customBiggerIsBetter' # ops/sec - higher is better
5595 output-file-path : benchmark-results-gh.json
5696 github-token : ${{ secrets.GITHUB_TOKEN }}
5797 auto-push : true
5898 # Show alert with commit comment on detecting possible performance regression
59- alert-threshold : ' 110% '
99+ alert-threshold : ' 150% ' # Alert if performance degrades by 50%
60100 comment-on-alert : true
61101 fail-on-alert : false
62102 alert-comment-cc-users : ' @testingapisname'
63103
64- - name : Upload benchmark results
104+ - name : Upload benchmark results as artifacts
65105 uses : actions/upload-artifact@v4
66106 with :
67107 name : benchmark-results
68- path : benchmark-results.json
108+ path : |
109+ benchmark-results.json
110+ benchmark-results-gh.json
111+
112+ - name : Display benchmark summary
113+ run : |
114+ echo "=== Benchmark Summary ==="
115+ if [ -f benchmark-results.json ]; then
116+ jq -r '.results[]? | "\(.result.name): \(.ops_per_sec | round) ops/sec"' benchmark-results.json || echo "Could not parse results"
117+ else
118+ echo "No benchmark results file found"
119+ fi
69120
70121 - name : Comment PR with results
71122 if : github.event_name == 'pull_request'
72123 uses : actions/github-script@v7
73124 with :
74125 script : |
75126 const fs = require('fs');
127+
128+ if (!fs.existsSync('benchmark-results.json')) {
129+ console.log('No benchmark results file found');
130+ return;
131+ }
132+
76133 const results = JSON.parse(fs.readFileSync('benchmark-results.json', 'utf8'));
77134
78135 let comment = '## 📊 Benchmark Results\n\n';
79- comment += '| Operation | Ops/sec | Avg (ms) | P95 (ms) |\n';
80- comment += '|-----------|---------|----------|----------|\n';
136+ comment += '| Operation | Ops/sec | Avg (ms) | P95 (ms) | P99 (ms) | \n';
137+ comment += '|-----------|---------|----------|----------|----------| \n';
81138
82- results.results.forEach(r => {
83- comment += `| ${r.name} | ${r.ops_per_sec.toFixed(1)} | ${r.avg_latency_ms.toFixed(2)} | ${r.p95_ms.toFixed(2)} |\n`;
84- });
139+ if (results.results) {
140+ results.results.forEach(r => {
141+ const name = r.result?.name || 'Unknown';
142+ const ops = (r.ops_per_sec || 0).toFixed(1);
143+ const avg = (r.avg_latency_ms || 0).toFixed(2);
144+ const p95 = (r.p95_ms || 0).toFixed(2);
145+ const p99 = (r.p99_ms || 0).toFixed(2);
146+ comment += `| ${name} | ${ops} | ${avg} | ${p95} | ${p99} |\n`;
147+ });
148+ } else {
149+ comment += '| No results available | - | - | - | - |\n';
150+ }
151+
152+ comment += '\n📈 [View historical results](https://testingapisname.github.io/rust-hsm/dev/bench/)\n';
85153
86154 github.rest.issues.createComment({
87155 issue_number: context.issue.number,
92160
93161 - name : Stop container
94162 if : always()
95- run : docker compose down
163+ run : |
164+ docker compose down
165+ docker volume prune -f
0 commit comments