[PR #722] [MERGED] perf: hot-path optimizations, streaming pagination, and benchmark CI #741

Closed
opened 2026-02-26 22:32:21 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/rudrankriyam/App-Store-Connect-CLI/pull/722
Author: @rudrankriyam
Created: 2/21/2026
Status: Merged
Merged: 2/22/2026
Merged by: @rudrankriyam

Base: mainHead: perf/hot-path-optimizations-and-bench-suite


📝 Commits (6)

  • b4b0937 perf: hot-path optimizations, streaming pagination, and benchmark CI
  • 192493f fix: create .perf directory before writing baseline in bench-compare
  • 1494a75 fix: skip benchmark comment when no baseline exists to compare against
  • 1f921fd feat: glanceable benchmark PR comment with icons and verdict table
  • 4a75ca3 Fix benchstat parser for modern p-value output
  • 49faca3 Merge pull request #723 from rudrankriyam/cursor/benchstat-output-regex-7293

📊 Changes

28 files changed (+1205 additions, -98 deletions)

View changed files

.github/workflows/bench-compare.yml (+96 -0)
📝 .github/workflows/main-branch.yml (+36 -3)
📝 .github/workflows/pr-checks.yml (+36 -4)
📝 .github/workflows/release.yml (+1 -0)
📝 Makefile (+46 -0)
📝 cmd/root.go (+11 -4)
📝 cmd/run.go (+26 -3)
cmd/run_bench_test.go (+38 -0)
📝 internal/asc/assets_upload.go (+9 -1)
📝 internal/asc/client_core.go (+32 -4)
internal/asc/client_core_transport_test.go (+48 -0)
📝 internal/asc/client_http.go (+17 -1)
internal/asc/client_http_cache_test.go (+37 -0)
📝 internal/asc/client_pagination.go (+49 -0)
internal/asc/client_pagination_bench_test.go (+60 -0)
internal/asc/client_pagination_each_test.go (+66 -0)
internal/asc/perf_bench_test.go (+41 -0)
📝 internal/cli/builds/builds_latest.go (+56 -32)
📝 internal/cli/migrate/screenshots.go (+8 -13)
internal/cli/migrate/screenshots_bench_test.go (+21 -0)

...and 8 more files

📄 Description

Summary

  • Add JWT token caching with expiry-aware refresh, tuned HTTP transport (idle conn pooling), and signal-aware root context
  • Introduce PaginateEach for streaming pagination without full-memory aggregation; convert builds latest --next to use it
  • Cache Koubou version checks, shell path resolution, and env-merge index to eliminate repeated subprocess/PATH lookups
  • Split CI into parallel jobs (format+lint / tests / build) with Go module and tool caching
  • Add automated benchmark comparison workflow (bench-compare.yml) that posts benchstat diffs as PR comments
  • Add reproducible benchmark suite (make bench-perf, scripts/bench-ci.sh) covering API path, pagination, and local tooling

Benchmark deltas (median, Apple M5)

Hot Path Before After Impact
PaginateEach vs PaginateAll (5000 items) 3,872,783 B/op 895,745 B/op 4.3x less memory — prevents GC pressure on large paginated commands
Koubou version check (cached vs uncached) 2,633,980 ns/op 5,874 ns/op 448x — avoids subprocess spawn per frame when framing multiple screenshots
Client.newRequest (JWT cached) 16,116 ns/op 431 ns/op 37x — eliminates ECDSA signing on every API request within token lifetime
CI wall-clock serial (format→lint→test→build) parallel jobs + Go/tool caching ~2-3x faster PR feedback loop (estimated)

The remaining changes (version fast-path, env merge, shell cache) are technically correct micro-optimizations but don't materially affect wall-clock time for real commands.

What actually matters here

  • Pagination memory: builds latest --next paginating hundreds of build uploads no longer accumulates all pages in memory
  • Koubou framing batches: framing 10 screenshots no longer spawns kou --version 10 times
  • JWT per-request signing: a 25-page paginated list no longer signs 25 JWTs (reuses one for the full token lifetime)
  • CI parallelism: format/lint, tests, and build run as independent jobs instead of a single serial pipeline
  • Ctrl+C: signal-aware context cleanly cancels in-flight API requests instead of orphaning connections
  • Benchmark CI: every future PR gets an automated benchstat comparison comment

Test plan

  • make format-check
  • make lint
  • ASC_BYPASS_KEYCHAIN=1 make test (full suite, all packages pass)
  • make bench-perf (benchmark snapshot runs clean)
  • Pre-commit hook passed (format + lint + short tests)
  • Verify bench-compare.yml posts comment on this PR (first run will show PR-only results since base branch doesn't have the bench script yet)

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/rudrankriyam/App-Store-Connect-CLI/pull/722 **Author:** [@rudrankriyam](https://github.com/rudrankriyam) **Created:** 2/21/2026 **Status:** ✅ Merged **Merged:** 2/22/2026 **Merged by:** [@rudrankriyam](https://github.com/rudrankriyam) **Base:** `main` ← **Head:** `perf/hot-path-optimizations-and-bench-suite` --- ### 📝 Commits (6) - [`b4b0937`](https://github.com/rudrankriyam/App-Store-Connect-CLI/commit/b4b0937311e6d4a083f0fa566568d3390519f742) perf: hot-path optimizations, streaming pagination, and benchmark CI - [`192493f`](https://github.com/rudrankriyam/App-Store-Connect-CLI/commit/192493fee6de255f419d36cecd03ad1b8d22866d) fix: create .perf directory before writing baseline in bench-compare - [`1494a75`](https://github.com/rudrankriyam/App-Store-Connect-CLI/commit/1494a75ce6503e6c424910cd22379ec48cb79238) fix: skip benchmark comment when no baseline exists to compare against - [`1f921fd`](https://github.com/rudrankriyam/App-Store-Connect-CLI/commit/1f921fd6d6141563c0c489935555c3b6579b69bb) feat: glanceable benchmark PR comment with icons and verdict table - [`4a75ca3`](https://github.com/rudrankriyam/App-Store-Connect-CLI/commit/4a75ca3cc7a12e4be3e5b864c4b89377ed12ac18) Fix benchstat parser for modern p-value output - [`49faca3`](https://github.com/rudrankriyam/App-Store-Connect-CLI/commit/49faca37369d2a736ad346863f7eafd6df17643b) Merge pull request #723 from rudrankriyam/cursor/benchstat-output-regex-7293 ### 📊 Changes **28 files changed** (+1205 additions, -98 deletions) <details> <summary>View changed files</summary> ➕ `.github/workflows/bench-compare.yml` (+96 -0) 📝 `.github/workflows/main-branch.yml` (+36 -3) 📝 `.github/workflows/pr-checks.yml` (+36 -4) 📝 `.github/workflows/release.yml` (+1 -0) 📝 `Makefile` (+46 -0) 📝 `cmd/root.go` (+11 -4) 📝 `cmd/run.go` (+26 -3) ➕ `cmd/run_bench_test.go` (+38 -0) 📝 `internal/asc/assets_upload.go` (+9 -1) 📝 `internal/asc/client_core.go` (+32 -4) ➕ `internal/asc/client_core_transport_test.go` (+48 -0) 📝 `internal/asc/client_http.go` (+17 -1) ➕ `internal/asc/client_http_cache_test.go` (+37 -0) 📝 `internal/asc/client_pagination.go` (+49 -0) ➕ `internal/asc/client_pagination_bench_test.go` (+60 -0) ➕ `internal/asc/client_pagination_each_test.go` (+66 -0) ➕ `internal/asc/perf_bench_test.go` (+41 -0) 📝 `internal/cli/builds/builds_latest.go` (+56 -32) 📝 `internal/cli/migrate/screenshots.go` (+8 -13) ➕ `internal/cli/migrate/screenshots_bench_test.go` (+21 -0) _...and 8 more files_ </details> ### 📄 Description ## Summary - Add JWT token caching with expiry-aware refresh, tuned HTTP transport (idle conn pooling), and signal-aware root context - Introduce `PaginateEach` for streaming pagination without full-memory aggregation; convert `builds latest --next` to use it - Cache Koubou version checks, shell path resolution, and env-merge index to eliminate repeated subprocess/PATH lookups - Split CI into parallel jobs (format+lint / tests / build) with Go module and tool caching - Add automated benchmark comparison workflow (`bench-compare.yml`) that posts `benchstat` diffs as PR comments - Add reproducible benchmark suite (`make bench-perf`, `scripts/bench-ci.sh`) covering API path, pagination, and local tooling ### Benchmark deltas (median, Apple M5) | Hot Path | Before | After | Impact | |---|---:|---:|:---| | `PaginateEach` vs `PaginateAll` (5000 items) | 3,872,783 B/op | 895,745 B/op | **4.3x less memory** — prevents GC pressure on large paginated commands | | Koubou version check (cached vs uncached) | 2,633,980 ns/op | 5,874 ns/op | **448x** — avoids subprocess spawn per frame when framing multiple screenshots | | `Client.newRequest` (JWT cached) | 16,116 ns/op | 431 ns/op | **37x** — eliminates ECDSA signing on every API request within token lifetime | | CI wall-clock | serial (format→lint→test→build) | parallel jobs + Go/tool caching | **~2-3x faster** PR feedback loop (estimated) | The remaining changes (version fast-path, env merge, shell cache) are technically correct micro-optimizations but don't materially affect wall-clock time for real commands. ### What actually matters here - **Pagination memory**: `builds latest --next` paginating hundreds of build uploads no longer accumulates all pages in memory - **Koubou framing batches**: framing 10 screenshots no longer spawns `kou --version` 10 times - **JWT per-request signing**: a 25-page paginated list no longer signs 25 JWTs (reuses one for the full token lifetime) - **CI parallelism**: format/lint, tests, and build run as independent jobs instead of a single serial pipeline - **Ctrl+C**: signal-aware context cleanly cancels in-flight API requests instead of orphaning connections - **Benchmark CI**: every future PR gets an automated `benchstat` comparison comment ## Test plan - [x] `make format-check` - [x] `make lint` - [x] `ASC_BYPASS_KEYCHAIN=1 make test` (full suite, all packages pass) - [x] `make bench-perf` (benchmark snapshot runs clean) - [x] Pre-commit hook passed (format + lint + short tests) - [ ] Verify `bench-compare.yml` posts comment on this PR (first run will show PR-only results since base branch doesn't have the bench script yet) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-02-26 22:32:21 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/App-Store-Connect-CLI#741
No description provided.