Skip to content

Commit 2c7c336

Browse files
yokosznclaude
andcommitted
improvement(ci): affected-only build, typecheck, and unit tests on PRs
On pull requests, Turbo now scopes build, typecheck, and test tasks to only packages that changed relative to the base branch — plus their transitive dependents. On pushes to main/develop, the full suite runs. Implementation details: - Fetch the base branch at depth=1 before running Turbo so git can compute the diff (shallow clone cannot reach origin/main otherwise) - Use --filter=[origin/<base_ref>]... to scope to affected packages - Add --filter='!./apps/*' to exclude apps from the package build steps: Turbo's multiple --filter flags use union semantics, so without the negation, apps are included as dependents of changed packages and fail because generated files don't exist at that point in the job - generate and build:app always run fully — generate is global module discovery; build:app is required for integration tests downstream Expected impact on a PR touching 1 module: build:packages 2m30s → ~5s (17 cache hits + 1 rebuild) typecheck 2m04s → ~5s (only affected packages) unit tests 1m17s → ~5s (only affected packages) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent f5d5d7d commit 2c7c336

1 file changed

Lines changed: 50 additions & 4 deletions

File tree

.github/workflows/ci.yml

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ jobs:
2929
- name: Checkout repository
3030
uses: actions/checkout@v4
3131

32+
- name: Fetch base branch for change detection
33+
# Only needed on PRs — gives Turbo enough history to compute
34+
# which packages changed relative to the target branch.
35+
if: github.event_name == 'pull_request'
36+
run: git fetch origin ${{ github.base_ref }} --depth=1
37+
3238
- name: Setup Node.js
3339
uses: actions/setup-node@v4
3440
with:
@@ -51,16 +57,37 @@ jobs:
5157
run: yarn install --immutable
5258

5359
- name: Build packages
54-
run: yarn build:packages
60+
# On PRs: turbo run build scoped to affected packages only, apps excluded.
61+
# Multiple --filter flags use union semantics, so we must exclude apps
62+
# explicitly — they would otherwise be included as dependents of changed
63+
# packages, and they fail here because generated files don't exist yet.
64+
# On pushes to protected branches: full build, no filter.
65+
run: |
66+
if [ "${{ github.event_name }}" = "pull_request" ]; then
67+
yarn turbo run build \
68+
--filter=[origin/${{ github.base_ref }}]... \
69+
--filter='!./apps/*'
70+
else
71+
yarn build:packages
72+
fi
5573
env:
5674
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
5775
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
5876

5977
- name: Prepare generated modules
78+
# Always run fully — generator discovers all modules regardless of
79+
# what changed, and its output is consumed by the app, not packages.
6080
run: yarn generate
6181

6282
- name: Rebuild packages with generated files
63-
run: yarn build:packages
83+
run: |
84+
if [ "${{ github.event_name }}" = "pull_request" ]; then
85+
yarn turbo run build \
86+
--filter=[origin/${{ github.base_ref }}]... \
87+
--filter='!./apps/*'
88+
else
89+
yarn build:packages
90+
fi
6491
env:
6592
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
6693
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
@@ -108,6 +135,10 @@ jobs:
108135
- name: Checkout repository
109136
uses: actions/checkout@v4
110137

138+
- name: Fetch base branch for change detection
139+
if: github.event_name == 'pull_request'
140+
run: git fetch origin ${{ github.base_ref }} --depth=1
141+
111142
- name: Setup Node.js
112143
uses: actions/setup-node@v4
113144
with:
@@ -155,15 +186,30 @@ jobs:
155186
continue-on-error: true
156187

157188
- name: Checking types
158-
run: yarn typecheck
189+
run: |
190+
if [ "${{ github.event_name }}" = "pull_request" ]; then
191+
yarn turbo run typecheck \
192+
--filter=[origin/${{ github.base_ref }}]... \
193+
--filter='!./apps/*'
194+
else
195+
yarn typecheck
196+
fi
159197
env:
160198
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
161199
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
162200

163201
- name: Test
164-
run: yarn test
202+
run: |
203+
if [ "${{ github.event_name }}" = "pull_request" ]; then
204+
yarn turbo run test \
205+
--filter=[origin/${{ github.base_ref }}]... \
206+
--filter='!./apps/*'
207+
else
208+
yarn test
209+
fi
165210
166211
- name: Build
212+
# Always build the full app — integration tests need a complete build.
167213
run: yarn build:app
168214

169215
# ── Integration tests ───────────────────────────────────────────────────────

0 commit comments

Comments
 (0)