|
| 1 | +# CI Speed Investigation - October 2025 |
| 2 | + |
| 3 | +## Current State |
| 4 | + |
| 5 | +### Integration Tests: 3m59s |
| 6 | +``` |
| 7 | +Set up job: 1s |
| 8 | +Checkout: 5s |
| 9 | +setup-cmux: 10s |
| 10 | +Test execution: 193s ← PRIMARY TARGET |
| 11 | +Upload coverage: 4s |
| 12 | +Post actions: 5s |
| 13 | +--- |
| 14 | +Total: 218s |
| 15 | +``` |
| 16 | + |
| 17 | +### macOS Build: 3m50s |
| 18 | +``` |
| 19 | +Set up job: 2s |
| 20 | +Checkout: 1s |
| 21 | +setup-cmux: 87s ← MAJOR BOTTLENECK (ImageMagick ~45-70s) |
| 22 | +Build app: 28s |
| 23 | +Package (signing): 93s ← MAJOR BOTTLENECK |
| 24 | +Upload artifacts: 10s |
| 25 | +Post actions: 7s |
| 26 | +--- |
| 27 | +Total: 228s |
| 28 | +``` |
| 29 | + |
| 30 | +## Optimization Opportunities |
| 31 | + |
| 32 | +### 1. Integration Tests (193s execution) |
| 33 | + |
| 34 | +#### Current Configuration |
| 35 | +- Runner: depot-ubuntu-24.04-32 (32 cores) |
| 36 | +- Jest config: `maxWorkers=200%` (64 parallel workers) |
| 37 | +- Test files: 17 files in `tests/ipcMain/` + `tests/runtime/` |
| 38 | +- Flags: `--coverage --maxWorkers=200% --silent` |
| 39 | + |
| 40 | +#### Potential Issues |
| 41 | +1. **Over-parallelization**: 64 workers on 32 cores may cause contention |
| 42 | + - Each test spawns child processes, file I/O, git operations |
| 43 | + - May be better to use fewer workers (100% or 150%) |
| 44 | + |
| 45 | +2. **Silent mode hides timing data**: Can't see which tests are slow |
| 46 | + - Remove `--silent` temporarily to profile |
| 47 | + - Add `--verbose` to see timing per test |
| 48 | + |
| 49 | +3. **Coverage overhead**: Jest coverage adds significant overhead |
| 50 | + - Consider running coverage only on specific files |
| 51 | + - Or separate coverage runs from speed-critical PRs |
| 52 | + |
| 53 | +4. **Test setup duplication**: Each test file creates full test environments |
| 54 | + - May benefit from shared setup/teardown |
| 55 | + - Check if any tests can be simplified |
| 56 | + |
| 57 | +#### Action Items |
| 58 | +- [ ] Profile tests without `--silent` to identify slow tests |
| 59 | +- [ ] Experiment with `maxWorkers=100%` vs `200%` vs `150%` |
| 60 | +- [ ] Measure overhead of `--coverage` flag |
| 61 | +- [ ] Review slowest test files for optimization opportunities |
| 62 | +- [ ] Check if test files can share more setup code |
| 63 | + |
| 64 | +### 2. macOS setup-cmux (87s) |
| 65 | + |
| 66 | +#### Current Breakdown |
| 67 | +- Setup Bun: ~5s |
| 68 | +- Cache operations: ~5s |
| 69 | +- bun install: ~5-10s (usually cached) |
| 70 | +- **ImageMagick install: ~45-70s** ← Unavoidable on ephemeral runners |
| 71 | + |
| 72 | +#### Homebrew ImageMagick Install |
| 73 | +Current command: |
| 74 | +```bash |
| 75 | +HOMEBREW_NO_AUTO_UPDATE=1 brew install imagemagick |
| 76 | +``` |
| 77 | + |
| 78 | +Takes 45-70s on depot-macos-15 runners. |
| 79 | + |
| 80 | +#### Potential Optimizations |
| 81 | +1. **Skip brew cleanup**: Add `HOMEBREW_NO_INSTALL_CLEANUP=1` |
| 82 | + - May save 5-10s by skipping post-install cleanup |
| 83 | + |
| 84 | +2. **Use pre-compiled bottles**: Brew should already use bottles, but verify |
| 85 | + - Check logs to ensure not building from source |
| 86 | + |
| 87 | +3. **Investigate alternative ImageMagick sources**: |
| 88 | + - Could we use a pre-built binary from GitHub releases? |
| 89 | + - Would need to be compatible with electron-builder expectations |
| 90 | + |
| 91 | +#### Action Items |
| 92 | +- [ ] Add `HOMEBREW_NO_INSTALL_CLEANUP=1` and measure impact |
| 93 | +- [ ] Verify ImageMagick is using bottles (not building from source) |
| 94 | +- [ ] Research if electron-builder can use a simpler ImageMagick setup |
| 95 | +- [ ] Consider if we can cache ImageMagick binary itself (risky with dependencies) |
| 96 | + |
| 97 | +### 3. macOS Packaging (93s) |
| 98 | + |
| 99 | +#### Current Process |
| 100 | +electron-builder creates: |
| 101 | +- x64 DMG (~45s) |
| 102 | +- arm64 DMG (~45s) |
| 103 | +- Both are signed and notarized |
| 104 | + |
| 105 | +#### Current Makefile Target |
| 106 | +```make |
| 107 | +dist-mac: |
| 108 | + bun run dist:mac |
| 109 | +``` |
| 110 | + |
| 111 | +Which runs electron-builder with platform-specific config. |
| 112 | + |
| 113 | +#### Potential Optimizations |
| 114 | +1. **Parallel architecture builds**: electron-builder may build sequentially |
| 115 | + - Check if `--arm64 --x64` can build in parallel |
| 116 | + - May need to split into separate CI jobs |
| 117 | + |
| 118 | +2. **Skip notarization on PRs**: Notarization takes time |
| 119 | + - Already configured via `CSC_FOR_PULL_REQUEST` |
| 120 | + - Verify this is working correctly |
| 121 | + |
| 122 | +3. **Optimize electron-builder config**: |
| 123 | + - Check compression settings (can trade size for speed) |
| 124 | + - Review if all build steps are necessary for CI |
| 125 | + |
| 126 | +4. **Code signing optimization**: |
| 127 | + - Verify signing doesn't happen twice |
| 128 | + - Check if there's redundant identity verification |
| 129 | + |
| 130 | +#### Action Items |
| 131 | +- [ ] Profile electron-builder to see x64 vs arm64 timing |
| 132 | +- [ ] Investigate parallel architecture builds |
| 133 | +- [ ] Verify notarization is actually skipped on PRs |
| 134 | +- [ ] Review electron-builder config for speed optimizations |
| 135 | +- [ ] Consider if we need both architectures on every PR (vs just merge/release) |
| 136 | + |
| 137 | +### 4. Quick Wins (Already Implemented) |
| 138 | + |
| 139 | +✅ **Removed ImageMagick from test workflows** (PR #434) |
| 140 | +- Saved ~30s per test workflow |
| 141 | +- Total savings: ~150s per CI run |
| 142 | + |
| 143 | +## Testing Strategy |
| 144 | + |
| 145 | +### Baseline Measurements |
| 146 | +Need to run controlled tests to measure current performance: |
| 147 | + |
| 148 | +1. Integration tests with different worker counts |
| 149 | +2. macOS build with brew optimizations |
| 150 | +3. Packaging with different electron-builder settings |
| 151 | + |
| 152 | +### Experimental Branches |
| 153 | +For each optimization, create a test branch and measure: |
| 154 | +- Run the same workflow 3 times |
| 155 | +- Take average timing |
| 156 | +- Compare against baseline |
| 157 | + |
| 158 | +### Measurement Commands |
| 159 | +```bash |
| 160 | +# Check recent run timings |
| 161 | +gh run list --workflow=ci.yml --limit 5 --json number,conclusion,displayTitle,createdAt |
| 162 | + |
| 163 | +# Get detailed step timings for a run |
| 164 | +gh api repos/coder/cmux/actions/runs/<RUN_ID>/jobs | \ |
| 165 | + jq -r '.jobs[] | select(.name == "Integration Tests") | .steps[] | "\(.name): \(((.completed_at | fromdateiso8601) - (.started_at | fromdateiso8601)))s"' |
| 166 | + |
| 167 | +# Run integration tests locally with timing |
| 168 | +time TEST_INTEGRATION=1 bun x jest --maxWorkers=100% tests |
| 169 | +``` |
| 170 | + |
| 171 | +## Priority Order |
| 172 | + |
| 173 | +1. **HIGH PRIORITY - Integration Tests Parallelization** |
| 174 | + - Quick to test locally |
| 175 | + - Could yield 20-30% improvement (38-58s savings) |
| 176 | + - No infrastructure risk |
| 177 | + |
| 178 | +2. **MEDIUM PRIORITY - Homebrew Cleanup Optimization** |
| 179 | + - Small change, low risk |
| 180 | + - Potential 5-10s savings on macOS |
| 181 | + - Easy to test and revert |
| 182 | + |
| 183 | +3. **LOW PRIORITY - Packaging Optimization** |
| 184 | + - Complex changes required |
| 185 | + - Need to understand electron-builder deeply |
| 186 | + - Risk of breaking packaging |
| 187 | + - But largest potential savings (20-40s possible) |
| 188 | + |
| 189 | +4. **RESEARCH - Coverage Overhead** |
| 190 | + - May be significant (10-20% of test time) |
| 191 | + - But losing coverage visibility has cost |
| 192 | + - Consider selective coverage or separate runs |
| 193 | + |
| 194 | +## Next Steps |
| 195 | + |
| 196 | +1. Profile integration tests without --silent |
| 197 | +2. Test different maxWorkers settings locally |
| 198 | +3. Implement brew cleanup optimization for macOS |
| 199 | +4. Measure and iterate |
| 200 | + |
| 201 | +--- |
| 202 | + |
| 203 | +**Branch**: `investigate-speed-2` |
| 204 | +**Created**: October 2025 |
| 205 | +**Status**: Investigation phase |
0 commit comments