New Feature·Pushed May 1, 2026·M
Parallel commit analysis speeds up GitPulse workflows
GitPulse can now analyze multiple commits at the same time instead of one-by-one, with a configurable concurrency limit that defaults to 10 parallel workers.
Repositories with long commit histories take a long time to analyze sequentially. GitPulse's action now processes commits in parallel — fetching file changes, querying GitHub for PR data, running LLM summarization, assessing PR size, and writing stories all happen concurrently for up to N commits at once.
The concurrency level is configurable via the workflow's new [[code]]concurrency[[/code]] input (defaulting to 10) and passes through the [[code]]GITPULSE_CONCURRENCY[[/code]] environment variable. Results are streamed to the console as commits complete, and a final summary reports processed, total, and failed counts.
Alongside the parallelization, the size assessment schema is now deduplicated — the same Zod types used by gitsky are imported directly rather than re-declared in the action. The [[code]]size-thresholds[[/code]] workflow input was removed since the default thresholds work for v1, with customization deferred to a future phase that supports custom formulas beyond simple JSON overrides.
This change is in the [[code]].github/workflows/analyze.yml[[/code]] GitHub Action.
Technical description
This PR introduces parallel commit analysis to the GitPulse action, along with schema deduplication from gitsky.
**Parallel Processing with [[code ref=1]]pMap[[/code]]**
A new [[code]]action/src/pmap.ts[[/code]] implements a bounded-concurrency ordered map. Unlike a simple [[code]]Promise.all[[/code]], this limits how many async operations run simultaneously and preserves input order in the result array — critical for maintaining commit chronology in the output. The implementation uses a worker pool pattern: N workers pull tasks from a shared index until all items are processed.
**Refactored Analysis Loop**
The main loop in [[code]]action/src/index.ts[[/code]] was restructured. The commit processing logic is now encapsulated in a separate [[code ref=2]]processCommit[[/code]] function that returns a typed result object ([[code]]{ ok: true, tag }[[/code]] or [[code]]{ ok: false, error }[[/code]]). The main loop uses [[code ref=1]]pMap[[/code]] with the configured concurrency limit:
````typescript
file=action/src/index.ts
await pMap(commits, cfg.concurrency, async (baseCommit) => {
const result = await processCommit({ baseCommit, cfg, summarize, gh, owner, repo });
// ... output logged immediately on completion
});
````
The [[code]]computeStatTotals[[/code]] helper was also simplified to accept files directly rather than a commit object, reducing unnecessary spread operations.
**Concurrency Configuration**
The workflow's new [[code]]concurrency[[/code]] input (default 10) is passed as [[code]]GITPULSE_CONCURRENCY[[/code]] to the action. The config loader enforces a minimum of 1:
````typescript
file=action/src/config.ts
concurrency: Math.max(1, Number(env.GITPULSE_CONCURRENCY ?? 10)),
````
**Schema Deduplication**
The [[code ref=3]]SizeAssessmentSchema[[/code]] and [[code ref=4]]SizeAssessmentOutputSchema[[/code]] were added to [[code]]action/src/schemas.ts[[/code]] verbatim from gitsky. The action's [[code ref=5]]assessPRSize[[/code]] in [[code]]action/src/size.ts[[/code]] now imports from there instead of defining its own types. This eliminates the maintenance burden of keeping duplicate definitions in sync.
The [[code]]size-thresholds[[/code]] workflow input was removed. The function now accepts an optional [[code]]weightedLines[[/code]] property for future extensibility but falls back to [[code]]additions + deletions[[/code]] when absent.
**Output Changes**
Console output is now interleaved — each commit prints its result immediately upon completion rather than waiting for all preceding commits. The final summary includes a [[code]]failed[[/code]] count in addition to [[code]]processed[[/code]] and total.
````mermaid
graph LR
A[commits] --> B[pMap concurrency=10]
B --> C1[processCommit]
B --> C2[processCommit]
B --> C3[processCommit]
B --> C10[processCommit]
C1 --> D1[fetch + LLM + write]
C2 --> D2[fetch + LLM + write]
C3 --> D3[fetch + LLM + write]
C10 --> D10[fetch + LLM + write]
D1 --> E[results array]
D2 --> E
D3 --> E
D10 --> E
````
**Files at a Glance**
- [[code]].github/workflows/analyze.yml[[/code]] — Added concurrency input, removed size-thresholds
- [[code]]action/src/config.ts[[/code]] — Added concurrency config, removed sizeThresholds
- [[code]]action/src/index.ts[[/code]] — Parallel processing with pMap, extracted processCommit
- [[code]]action/src/pmap.ts[[/code]] — New bounded-concurrency ordered map
- [[code]]action/src/schemas.ts[[/code]] — Added SizeAssessmentSchema and SizeAssessmentOutputSchema
- [[code]]action/src/size.ts[[/code]] — Import from schemas, simplified, removed parseThresholds
- [[code]]action/src/render.ts[[/code]] — Import type from schemas instead of size.ts
- [[code]]action/src/types.ts[[/code]] — Import SizeAssessment from schemas
Categories
- New Feature (50%) — Primary deliverable is parallel commit analysis - commits are now processed concurrently instead of sequentially
- Performance (35%) — Bounded-concurrency processing enables multiple commits to be analyzed simultaneously, reducing total analysis time
- Maintenance (15%) — Size schemas are now deduplicated by importing from gitsky instead of having duplicate definitions in two places