aws-samples / aws-samples/sample-autonomous-cloud-coding-agents

perf(ci): build.yml optimization plan — parallelism, caching, and redundancy removal

Đang mở
#201 3 bình luận 0 reaction 0 người được giao Xem trên GitHub
ci-cd
Ngôn ngữ chính
TypeScript
Star
143
Fork
46
Merge trung bình
3 ngày 10 giờ
Pull request đã merge (30 ngày)
24

Mô tả

## Problem

The CI build (`build.yml`) averages **~14.5 minutes** wall time. All steps run sequentially in a single job despite many being independent. No artifact caching is used beyond mise tool binaries.

## Measured step timings (5 recent successful runs)

| Step | Run 1 | Run 2 | Run 3 | Run 4 | Run 5 | **Avg** |
|------|:---:|:---:|:---:|:---:|:---:|:---:|
| Free Disk Space | 66s | 79s | 23s | 35s | 35s | **48s** |
| Install mise | 3s | 13s | 8s | 3s | 3s | **6s** |
| Setup Node.js | 4s | 4s | 5s | 4s | 4s | **4s** |
| Install dependencies | 77s | 78s | 66s | 76s | 76s | **75s** |
| **build** | **635s** | **761s** | **751s** | **738s** | **738s** | **725s** |
| Upload artifact | 15s | 15s | 15s | 14s | 14s | **15s** |

The `build` step (avg 725s / 12min) is the overwhelming bottleneck.

## What runs inside `mise run build` (all sequential)

```
1. //agent:quality (~30-40s: ruff lint, ruff format, ty typecheck, pytest)
2. //cdk:build (~500-600s total)
├── :compile (~30-40s: tsc --build)
├── :test (~90-370s: jest, 99 suites, 1789 tests)
├── :eslint (~30-60s: eslint --fix)
└── :synth:quiet (~120-180s: cdk synth with esbuild bundling per Lambda)
3. //cli:build (~20-30s: compile + test + eslint)
4. //docs:build (~30-60s: sync-starlight + astro build)
5. //docs:sync (~5s: DUPLICATE — already runs as dep of //docs:build)
```

### Dependency graph (what actually depends on what)

```
┌── agent:quality ──────────────┐
├── cdk:eslint ─────────────────┤
install ────┼── cdk:test ───────────────────┼── (all pass) ── upload
├── cli:build ──────────────────┤
├── docs:build ─────────────────┤
└── cdk:compile → cdk:synth ────┘
```

Only `cdk:synth` depends on `cdk:compile`. Everything else is independent.

## Optimization priorities (ranked by impact)

### P0: Cache `node_modules` and `.venv` (~60-70s saved)

```yaml
- uses: actions/cache@v4
with:
path: |
node_modules
agent/.venv
key: deps-${{ runner.os }}-${{ hashFiles('yarn.lock', 'agent/uv.lock') }}
restore-keys: deps-${{ runner.os }}-
```

Turns 75s cold install into ~5s cache restore. First run after lockfile change is still cold.

### P1: Parallelize independent jobs (~5-7min wall time saved)

Split the single `build` job into parallel GHA jobs:

```yaml
jobs:
install:
# checkout + install + cache

agent-quality:
needs: install
# ruff, ty, pytest

cdk-compile-synth:
needs: install
# tsc → cdk synth → upload artifact

cdk-test:
needs: install
# jest (the heaviest step)

cdk-eslint:
needs: install
# eslint

cli-build:
needs: install
# compile + test + eslint

docs-build:
needs: install
# sync + astro build
```

Critical path drops from ~14.5min to: `install (5s cached) → cdk:compile (40s) → cdk:synth (150s) → upload (15s)` = **~3.5min**

### P2: Cache Jest transform output (~30-60s saved on test step)

Add `cacheDirectory` to jest config:
```json
"cacheDirectory": "/.jest-cache"
```

Then in CI:
```yaml
- uses: actions/cache@v4
with:
path: cdk/.jest-cache
key: jest-${{ runner.os }}-${{ hashFiles('cdk/yarn.lock') }}-${{ github.sha }}
restore-keys: |
jest-${{ runner.os }}-${{ hashFiles('cdk/yarn.lock') }}-
jest-${{ runner.os }}-
```

Cross-branch reuse works because Jest keys by file content hash — unchanged files hit cache regardless of branch.

### P3: Cache TypeScript incremental build (~10-20s saved)

```yaml
- uses: actions/cache@v4
with:
path: |
cdk/tsconfig.tsbuildinfo
cli/tsconfig.tsbuildinfo
key: tsc-${{ runner.os }}-${{ hashFiles('cdk/src/**', 'cli/src/**') }}
restore-keys: tsc-${{ runner.os }}-
```

### P4: Remove duplicate `//docs:sync` (~5s saved, trivial)

`mise.toml` root `tasks.build` calls `//docs:sync` explicitly after `//docs:build`, but `//docs:build` already depends on `:sync`. Remove the duplicate.

### P5 (future): Jest sharding for test parallelism

Only needed if tests remain the critical path after P0-P2. With our `beforeAll` optimization (PR #195) tests are already ~90s. Sharding would bring that to ~30-40s but adds matrix complexity.

## Projected improvement

| Scenario | Current | Cache only (P0+P2+P3) | Full parallel + cache (P0-P4) |
|----------|:---:|:---:|:---:|
| CI wall time | ~14.5min | ~10-11min | **~4-5min** |
| Critical path | 14.5min (serial) | 10-11min (serial) | compile→synth→upload (~3.5min) |
| Billed minutes | ~14.5 | ~10-11 | ~20 (more jobs but each shorter) |

## Acceptance criteria

- [ ] P0: `node_modules` + `.venv` cached via `actions/cache`
- [ ] P1: Build split into parallel jobs with proper `needs:` graph
- [ ] P2: Jest `cacheDirectory` set + cached in CI
- [ ] P3: TSC `.tsbuildinfo` cached
- [ ] P4: Duplicate `//docs:sync` removed
- [ ] Verify: mutation detection still works (self_mutation check)
- [ ] Verify: `cdk.out/` artifact upload still produces correct output
- [ ] Total CI wall time < 6 minutes for cache-warm runs

## Notes

- P1 (parallelism) requires careful handling of the `self_mutation` / patch detection — currently it runs `git diff --staged` at the end of the single job. With multiple jobs, each job could mutate files independently (e.g., eslint `--fix`, docs sync). Need a final "check mutations" job that either re-checks or collects patches.
- The `compute_type` matrix currently only has `[agentcore]`. If more types are added later, each gets its own parallel run — this architecture scales well.
- `Free Disk Space` step (avg 48s) is required because CDK synth + Docker image bundling can exhaust the default runner disk. With parallelism, only the `cdk-compile-synth` job needs this step.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Trước tiên, hãy đọc build.yml và mise.toml ở thư mục gốc, lần theo build job hiện tại, dependency //docs:build, kiểm tra self_mutation và việc tải lên artifact cdk.out. Sử dụng các mốc thời gian đã đo và acceptance checklist để xác thực caching cùng needs graph, sau đó chạy một CI build với cache đã được làm nóng để kiểm tra khả năng phát hiện mutation, đầu ra của artifact và mục tiêu dưới sáu phút.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
aws, github-actions, typescript
Lĩnh vực
build-system, ci-cd, devops
Loại issue
Tái cấu trúc
Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
35/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.