@@ -44,15 +44,18 @@ Here are different approaches teams use, from most to least restrictive:
4444### Strategy 1: Label-Based (CURRENT - RECOMMENDED) 🏷️
4545
4646** When it runs:**
47+
4748- Only when PR has ` performance ` label
4849- Manual trigger via GitHub UI
4950
5051** Pros:**
52+
5153- ✅ Saves tons of CI time
5254- ✅ Developers control when tests run
5355- ✅ No noise on small PRs
5456
5557** Cons:**
58+
5659- ❌ Developers might forget to add label
5760- ❌ Regressions could slip through
5861
@@ -63,6 +66,7 @@ Here are different approaches teams use, from most to least restrictive:
6366### Strategy 2: Path-Based (Original Design) 📁
6467
6568** When it runs:**
69+
6670``` yaml
6771on :
6872 pull_request :
7377` ` `
7478
7579**Pros:**
80+
7681- ✅ Automatic - no manual intervention
7782- ✅ Catches regressions early
7883
7984**Cons:**
85+
8086- ❌ Runs too often (most PRs touch these paths)
8187- ❌ High CI cost
8288- ❌ Slows down development
8894### Strategy 3: Scheduled + Manual Only ⏰
8995
9096**When it runs:**
97+
9198` ` ` yaml
9299on :
93100 schedule :
96103` ` `
97104
98105**Pros:**
106+
99107- ✅ Minimal CI cost
100108- ✅ No PR delays
101109- ✅ Nightly baseline still updates
102110
103111**Cons:**
112+
104113- ❌ Regressions found after merge (too late!)
105114- ❌ Developers must manually trigger
106115
111120### Strategy 4: Hybrid - Critical Paths Only 🎯
112121
113122**When it runs:**
123+
114124` ` ` yaml
115125on :
116126 pull_request :
@@ -122,11 +132,13 @@ on:
122132```
123133
124134** Pros:**
135+
125136- ✅ Automatic for critical code
126137- ✅ Reduced CI usage vs path-based
127138- ✅ Catches most important regressions
128139
129140** Cons:**
141+
130142- ❌ Still runs frequently
131143- ❌ Can miss indirect performance impacts
132144
@@ -137,16 +149,19 @@ on:
137149### Strategy 5: PR Size Based 📏
138150
139151** When it runs:**
152+
140153``` yaml
141154# Run only on large PRs (>500 lines changed)
142155if : github.event.pull_request.additions + github.event.pull_request.deletions > 500
143156` ` `
144157
145158**Pros:**
159+
146160- ✅ Small PRs skip expensive tests
147161- ✅ Large risky changes get tested
148162
149163**Cons:**
164+
150165- ❌ Single-line change can cause regression
151166- ❌ Complex logic to maintain
152167
@@ -157,6 +172,7 @@ if: github.event.pull_request.additions + github.event.pull_request.deletions >
157172### Strategy 6: Pre-merge Only (Protected Branch) 🔒
158173
159174**When it runs:**
175+
160176` ` ` yaml
161177on :
162178 pull_request :
@@ -167,10 +183,12 @@ on:
167183` ` `
168184
169185**Pros:**
186+
170187- ✅ Tests final code before/after merge
171188- ✅ Doesn't slow down draft PRs
172189
173190**Cons:**
191+
174192- ❌ Late feedback for developers
175193- ❌ Might catch issues post-merge
176194
@@ -181,27 +199,31 @@ on:
181199## Recommended Setup by Project Stage
182200
183201### 🌱 Early Stage Project
202+
184203` ` ` yaml
185204Strategy : Scheduled + Manual
186205Performance Tests : Nightly only
187206Reason : Save CI budget, iterate fast
188207` ` `
189208
190209### 🌿 Growing Project
210+
191211` ` ` yaml
192212Strategy : Label-Based (CURRENT)
193213Performance Tests : On 'performance' label
194214Reason : Balance cost vs safety
195215` ` `
196216
197217### 🌳 Mature Project
218+
198219` ` ` yaml
199220Strategy : Hybrid Critical Paths
200221Performance Tests : Auto on critical code
201222Reason : High confidence, catch regressions
202223` ` `
203224
204225### 🏢 Enterprise Project
226+
205227` ` ` yaml
206228Strategy : Every PR (Path-Based)
207229Performance Tests : Always
@@ -251,6 +273,7 @@ No changes needed! Current setup is optimized.
251273## Cost Analysis
252274
253275Assuming:
276+
254277- 10 PRs per day
255278- 20 minutes per performance test
256279- $0.008 per minute (GitHub Actions pricing)
@@ -271,6 +294,7 @@ Assuming:
271294### For Developers
272295
273296** When to add ` performance ` label:**
297+
274298- ✅ Changing classification, cache, or decision engine
275299- ✅ Modifying CGO bindings
276300- ✅ Optimizing algorithms
@@ -282,6 +306,7 @@ Assuming:
282306### For Reviewers
283307
284308** Check for performance label:**
309+
285310``` markdown
286311## Performance Checklist
287312- [ ] Does this PR touch classification/cache/decision code?
@@ -292,6 +317,7 @@ Assuming:
292317### For CI
293318
294319** Monitor false negatives:**
320+
295321- Track regressions found in nightly but missed in PRs
296322- If >5% slip through, consider tightening strategy
297323
@@ -302,26 +328,30 @@ Assuming:
302328### Q: What if a regression slips through?
303329
304330** A:** Nightly workflow will catch it and create an issue. You can:
331+
3053321 . Revert the problematic PR
3063332 . Fix forward with a new PR
3073343 . Update baseline if intentional
308335
309336### Q: Can I force performance tests on a PR without label?
310337
311338** A:** Yes! Two ways:
339+
3123401 . Add ` performance ` label to PR
3133412 . Go to Actions tab → Performance Tests → Run workflow → Select your branch
314342
315343### Q: What about main branch protection?
316344
317345** A:** Performance tests are NOT required checks. They're:
346+
318347- Advisory (warn but don't block)
319348- Opt-in (run when needed)
320349- Nightly will catch issues anyway
321350
322351### Q: Should I run tests locally before PR?
323352
324353** A:** Recommended for performance-critical changes:
354+
325355``` bash
326356make perf-bench-quick # Takes 3-5 min
327357make perf-compare # Compare vs baseline
@@ -339,11 +369,13 @@ make perf-compare # Compare vs baseline
339369- Nightly workflow ensures baselines stay current
340370
341371** To run performance tests on your PR:**
372+
3423731 . Add label: ` performance `
3433742 . Wait for tests to complete (~ 15 min)
3443753 . Review results in PR comment
345376
346377** Why nightly is still needed:**
378+
347379- Updates baselines automatically
348380- Catches anything that slipped through
349381- Runs comprehensive 30s benchmarks
0 commit comments