Skip to content

Commit 34bdc84

Browse files
authored
Initial PR for performance test on integration test that running on CI (#778)
* Initial PR for performance test on integration test that running on CI Signed-off-by: Senan Zedan <[email protected]> * Initial PR for performance test on integration test that running on CI Signed-off-by: Senan Zedan <[email protected]> * fix: make PR comment step optional in performance workflow The PR comment step can fail when running on pull requests from forks due to GitHub's security restrictions. Even with write permissions specified, GITHUB_TOKEN is read-only for fork PRs to prevent malicious code from writing to the base repository. Added 'continue-on-error: true' to make this step optional. The performance results will still be available in the workflow artifacts even if commenting fails. Fixes the '403 Resource not accessible by integration' error on fork PRs. Signed-off-by: Senan Zedan <[email protected]> --------- Signed-off-by: Senan Zedan <[email protected]>
1 parent a6e1910 commit 34bdc84

32 files changed

+5837
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
name: Nightly Performance Baseline
2+
3+
on:
4+
schedule:
5+
# Run at 3:00 AM UTC daily
6+
- cron: "0 3 * * *"
7+
workflow_dispatch: # Allow manual triggering
8+
9+
jobs:
10+
update-baseline:
11+
runs-on: ubuntu-latest
12+
timeout-minutes: 60
13+
14+
steps:
15+
- name: Check out the repo
16+
uses: actions/checkout@v4
17+
with:
18+
token: ${{ secrets.GITHUB_TOKEN }}
19+
fetch-depth: 0
20+
21+
- name: Set up Go
22+
uses: actions/setup-go@v5
23+
with:
24+
go-version: "1.24"
25+
26+
- name: Set up Rust
27+
uses: dtolnay/rust-toolchain@stable
28+
with:
29+
toolchain: 1.90
30+
31+
- name: Cache Rust dependencies
32+
uses: actions/cache@v4
33+
with:
34+
path: |
35+
~/.cargo/bin/
36+
~/.cargo/registry/index/
37+
~/.cargo/registry/cache/
38+
~/.cargo/git/db/
39+
candle-binding/target/
40+
key: ${{ runner.os }}-nightly-cargo-${{ hashFiles('**/Cargo.lock') }}
41+
restore-keys: |
42+
${{ runner.os }}-nightly-cargo-
43+
44+
- name: Cache Go dependencies
45+
uses: actions/cache@v4
46+
with:
47+
path: |
48+
~/go/pkg/mod
49+
key: ${{ runner.os }}-nightly-go-${{ hashFiles('**/go.sum') }}
50+
restore-keys: |
51+
${{ runner.os }}-nightly-go-
52+
53+
- name: Cache Models
54+
uses: actions/cache@v4
55+
with:
56+
path: |
57+
models/
58+
key: ${{ runner.os }}-models-v1-${{ hashFiles('tools/make/models.mk') }}
59+
restore-keys: |
60+
${{ runner.os }}-models-v1-
61+
62+
- name: Build Rust library (CPU-only)
63+
run: make rust-ci
64+
65+
- name: Install HuggingFace CLI
66+
run: |
67+
pip install -U "huggingface_hub[cli]" hf_transfer
68+
69+
- name: Download models (full set for nightly)
70+
env:
71+
CI_MINIMAL_MODELS: false
72+
HF_HUB_ENABLE_HF_TRANSFER: 1
73+
HF_HUB_DISABLE_TELEMETRY: 1
74+
run: make download-models
75+
76+
- name: Run comprehensive benchmarks
77+
run: |
78+
export LD_LIBRARY_PATH=${PWD}/candle-binding/target/release
79+
cd perf
80+
go test -bench=. -benchmem -benchtime=30s ./benchmarks/... | tee ../reports/nightly-bench.txt
81+
82+
- name: Update baselines
83+
run: |
84+
make perf-baseline-update
85+
86+
- name: Check for baseline changes
87+
id: check_changes
88+
run: |
89+
git add perf/testdata/baselines/
90+
if git diff --cached --quiet; then
91+
echo "changes=false" >> $GITHUB_OUTPUT
92+
echo "No baseline changes detected"
93+
else
94+
echo "changes=true" >> $GITHUB_OUTPUT
95+
echo "Baseline changes detected"
96+
fi
97+
98+
- name: Commit updated baselines
99+
if: steps.check_changes.outputs.changes == 'true'
100+
run: |
101+
git config user.name "GitHub Actions Bot"
102+
git config user.email "[email protected]"
103+
git commit -m "chore: update performance baselines (nightly run)"
104+
git push
105+
106+
- name: Upload nightly results
107+
uses: actions/upload-artifact@v4
108+
with:
109+
name: nightly-baseline-${{ github.run_number }}
110+
path: |
111+
reports/
112+
perf/testdata/baselines/
113+
retention-days: 90
114+
115+
- name: Create issue on failure
116+
if: failure()
117+
uses: actions/github-script@v7
118+
with:
119+
script: |
120+
const title = '🔥 Nightly Performance Baseline Update Failed';
121+
const body = `
122+
The nightly performance baseline update failed.
123+
124+
**Run:** ${{ github.run_id }}
125+
**Time:** ${new Date().toISOString()}
126+
127+
Please investigate the failure in the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}).
128+
`;
129+
130+
await github.rest.issues.create({
131+
owner: context.repo.owner,
132+
repo: context.repo.repo,
133+
title: title,
134+
body: body,
135+
labels: ['performance', 'ci-failure']
136+
});
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
name: Performance Tests
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
paths:
8+
- 'src/semantic-router/**'
9+
- 'candle-binding/**'
10+
- 'perf/**'
11+
- '.github/workflows/performance-test.yml'
12+
workflow_dispatch:
13+
14+
permissions:
15+
contents: read
16+
pull-requests: write # Required to comment on PRs
17+
issues: write # Required to comment on PRs (PRs are issues)
18+
19+
jobs:
20+
component-benchmarks:
21+
runs-on: ubuntu-latest
22+
timeout-minutes: 45
23+
24+
steps:
25+
- name: Check out the repo
26+
uses: actions/checkout@v4
27+
with:
28+
fetch-depth: 0 # Need full history for baseline comparison
29+
30+
- name: Set up Go
31+
uses: actions/setup-go@v5
32+
with:
33+
go-version: "1.24"
34+
35+
- name: Set up Rust
36+
uses: dtolnay/rust-toolchain@stable
37+
with:
38+
toolchain: 1.90
39+
40+
- name: Cache Rust dependencies
41+
uses: actions/cache@v4
42+
with:
43+
path: |
44+
~/.cargo/bin/
45+
~/.cargo/registry/index/
46+
~/.cargo/registry/cache/
47+
~/.cargo/git/db/
48+
candle-binding/target/
49+
key: ${{ runner.os }}-perf-cargo-${{ hashFiles('**/Cargo.lock') }}
50+
restore-keys: |
51+
${{ runner.os }}-perf-cargo-
52+
53+
- name: Cache Go dependencies
54+
uses: actions/cache@v4
55+
with:
56+
path: |
57+
~/go/pkg/mod
58+
key: ${{ runner.os }}-perf-go-${{ hashFiles('**/go.sum') }}
59+
restore-keys: |
60+
${{ runner.os }}-perf-go-
61+
62+
- name: Cache Models
63+
uses: actions/cache@v4
64+
with:
65+
path: |
66+
models/
67+
key: ${{ runner.os }}-models-v1-${{ hashFiles('tools/make/models.mk') }}
68+
restore-keys: |
69+
${{ runner.os }}-models-v1-
70+
continue-on-error: true
71+
72+
- name: Build Rust library (CPU-only)
73+
run: make rust-ci
74+
75+
- name: Install HuggingFace CLI
76+
run: |
77+
pip install -U "huggingface_hub[cli]" hf_transfer
78+
79+
- name: Download models (minimal)
80+
env:
81+
CI_MINIMAL_MODELS: true
82+
HF_HUB_ENABLE_HF_TRANSFER: 1
83+
HF_HUB_DISABLE_TELEMETRY: 1
84+
run: make download-models
85+
86+
- name: Download performance baselines
87+
continue-on-error: true
88+
run: |
89+
mkdir -p perf/testdata/baselines
90+
git show main:perf/testdata/baselines/classification.json > perf/testdata/baselines/classification.json 2>/dev/null || echo '{"version":"v1.0.0","benchmarks":{}}' > perf/testdata/baselines/classification.json
91+
git show main:perf/testdata/baselines/decision.json > perf/testdata/baselines/decision.json 2>/dev/null || echo '{"version":"v1.0.0","benchmarks":{}}' > perf/testdata/baselines/decision.json
92+
git show main:perf/testdata/baselines/cache.json > perf/testdata/baselines/cache.json 2>/dev/null || echo '{"version":"v1.0.0","benchmarks":{}}' > perf/testdata/baselines/cache.json
93+
94+
- name: Run component benchmarks
95+
run: |
96+
mkdir -p reports
97+
export LD_LIBRARY_PATH=${PWD}/candle-binding/target/release
98+
make perf-bench-quick 2>&1 | tee reports/bench-output.txt
99+
100+
- name: Parse benchmark results
101+
id: parse
102+
continue-on-error: true
103+
run: |
104+
# Extract benchmark results
105+
# This is a simplified parser - a real implementation would be more robust
106+
echo "benchmarks_completed=true" >> $GITHUB_OUTPUT
107+
108+
- name: Generate performance summary
109+
id: summary
110+
run: |
111+
cat > reports/summary.md <<'EOF'
112+
## Performance Benchmark Results
113+
114+
Component benchmarks completed successfully.
115+
116+
### Summary
117+
- Classification benchmarks: ✅
118+
- Decision engine benchmarks: ✅
119+
- Cache benchmarks: ✅
120+
121+
### Details
122+
See attached benchmark artifacts for detailed results and profiles.
123+
124+
---
125+
_Performance testing powered by [vLLM Semantic Router](https://github.com/vllm-project/semantic-router)_
126+
EOF
127+
128+
- name: Comment PR with results
129+
if: github.event_name == 'pull_request'
130+
continue-on-error: true # May fail for PRs from forks due to GitHub security restrictions
131+
uses: actions/github-script@v7
132+
with:
133+
script: |
134+
const fs = require('fs');
135+
let summary = '## Performance Benchmark Results\n\n';
136+
137+
try {
138+
summary = fs.readFileSync('reports/summary.md', 'utf8');
139+
} catch (err) {
140+
summary += '✅ Component benchmarks completed\n\n';
141+
summary += '_Detailed results available in workflow artifacts_\n';
142+
}
143+
144+
// Find existing comment
145+
const {data: comments} = await github.rest.issues.listComments({
146+
owner: context.repo.owner,
147+
repo: context.repo.repo,
148+
issue_number: context.issue.number,
149+
});
150+
151+
const botComment = comments.find(comment =>
152+
comment.user.type === 'Bot' &&
153+
comment.body.includes('Performance Benchmark Results')
154+
);
155+
156+
if (botComment) {
157+
await github.rest.issues.updateComment({
158+
owner: context.repo.owner,
159+
repo: context.repo.repo,
160+
comment_id: botComment.id,
161+
body: summary
162+
});
163+
} else {
164+
await github.rest.issues.createComment({
165+
owner: context.repo.owner,
166+
repo: context.repo.repo,
167+
issue_number: context.issue.number,
168+
body: summary
169+
});
170+
}
171+
172+
- name: Upload performance artifacts
173+
if: always()
174+
uses: actions/upload-artifact@v4
175+
with:
176+
name: performance-results-${{ github.run_number }}
177+
path: |
178+
reports/
179+
retention-days: 30
180+
181+
- name: Check for regressions (placeholder)
182+
id: regression_check
183+
continue-on-error: true
184+
run: |
185+
# In a real implementation, this would:
186+
# 1. Parse benchmark output
187+
# 2. Compare against baselines
188+
# 3. Calculate % changes
189+
# 4. Exit 1 if regressions exceed thresholds
190+
echo "No regressions detected (placeholder check)"
191+
192+
- name: Fail on regression
193+
if: steps.regression_check.outcome == 'failure'
194+
run: |
195+
echo "❌ Performance regressions detected!"
196+
echo "See benchmark results in artifacts for details"
197+
exit 1

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ _run:
2121
-f tools/make/observability.mk \
2222
-f tools/make/openshift.mk \
2323
-f tools/make/e2e.mk \
24+
-f tools/make/performance.mk \
2425
$(MAKECMDGOALS)
2526

2627
.PHONY: _run

0 commit comments

Comments
 (0)