9090 run : pnpm lint
9191 - name : Check types
9292 run : pnpm check-types
93+ - name : Validate Code QA workflow
94+ run : pnpm test:code-qa-ci
9395 - name : Model-check task lifecycle protocols
9496 run : pnpm lifecycle:model-check
9597 - name : Validate MCP OAuth integration
@@ -125,17 +127,21 @@ jobs:
125127 unit-test :
126128 name : platform-unit-test (${{ matrix.name }})
127129 runs-on : ${{ matrix.os }}
130+ concurrency :
131+ # Duplicate runs for one commit must not race the OS-specific Turbo cache save.
132+ group : unit-test-${{ github.repository }}-${{ github.sha }}-${{ matrix.name }}
133+ cancel-in-progress : false
128134 strategy :
129135 matrix :
130136 include :
131137 - os : ubuntu-latest
132138 name : ubuntu-latest
133139 codecov-flag : ubuntu
134- upload -coverage : true
140+ collect -coverage : true
135141 - os : windows-latest
136142 name : windows-latest
137143 codecov-flag : windows
138- upload -coverage : false
144+ collect -coverage : false
139145 steps :
140146 - name : Checkout code
141147 uses : actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -150,20 +156,56 @@ jobs:
150156 restore-keys : |
151157 ${{ runner.os }}-turbo-${{ hashFiles('**/pnpm-lock.yaml') }}-
152158 ${{ runner.os }}-turbo-
159+ # Windows never uploads coverage, so Windows runs the same test
160+ # suites through the uninstrumented Turbo tasks. Ubuntu stays the
161+ # authoritative coverage lane.
153162 - name : Run non-extension package coverage
163+ if : matrix.collect-coverage
154164 run : pnpm turbo run test:coverage --filter="!@roo-code/core" --filter="!zoo-code" --log-order grouped --output-logs new-only
155- - name : Run extension unit coverage
156- run : pnpm turbo run test:coverage:unit --filter="zoo-code" --log-order grouped --output-logs new-only
165+ - name : Run non-extension package tests
166+ if : ${{ !matrix.collect-coverage }}
167+ run : pnpm turbo run test --filter="!@roo-code/core" --filter="!zoo-code" --log-order grouped --output-logs new-only
168+ - name : Run extension coverage lanes
169+ if : matrix.collect-coverage
170+ run : pnpm turbo run test:coverage:api test:coverage:core test:coverage:services test:coverage:misc test:coverage:tree-sitter --filter="zoo-code" --concurrency=2 --log-order grouped --output-logs new-only
171+ - name : Run extension test lanes
172+ if : ${{ !matrix.collect-coverage }}
173+ run : pnpm turbo run test:api test:core test:services test:misc test:tree-sitter --filter="zoo-code" --concurrency=2 --log-order grouped --output-logs new-only
157174 - name : Verify extension coverage contract
175+ if : matrix.collect-coverage
158176 run : pnpm --dir src run verify:coverage-contract
159177 - name : Run extension dist smoke test
160178 run : pnpm turbo run test:dist --filter="zoo-code" --log-order grouped --output-logs new-only
161179 - name : Run core unit coverage
180+ if : matrix.collect-coverage
162181 run : pnpm turbo run test:coverage:unit --filter="@roo-code/core" --log-order grouped --output-logs new-only
182+ - name : Run core unit tests
183+ if : ${{ !matrix.collect-coverage }}
184+ run : pnpm turbo run test:unit --filter="@roo-code/core" --log-order grouped --output-logs new-only
163185 - name : Run core integration coverage
186+ if : matrix.collect-coverage
164187 run : pnpm turbo run test:coverage:integration --filter="@roo-code/core" --log-order grouped --output-logs new-only
165- - name : Verify extension unit coverage report
166- run : node src/scripts/verify-lcov.mjs src/coverage/unit/lcov.info
188+ - name : Run core integration tests
189+ if : ${{ !matrix.collect-coverage }}
190+ run : pnpm turbo run test:integration --filter="@roo-code/core" --log-order grouped --output-logs new-only
191+ - name : Verify extension coverage reports
192+ if : matrix.collect-coverage
193+ run : |
194+ node src/scripts/verify-lcov.mjs src/coverage/api/lcov.info
195+ node src/scripts/verify-lcov.mjs src/coverage/core/lcov.info
196+ node src/scripts/verify-lcov.mjs src/coverage/services/lcov.info
197+ node src/scripts/verify-lcov.mjs src/coverage/misc/lcov.info
198+ node src/scripts/verify-lcov.mjs src/coverage/tree-sitter/lcov.info
199+ - name : Merge extension coverage reports
200+ if : matrix.collect-coverage
201+ run : |
202+ mkdir -p src/coverage/merged
203+ pnpm --dir src run merge:coverage
204+ node src/scripts/verify-lcov.mjs src/coverage/merged/lcov.info
205+ # Validate cache boundaries before publishing any new Turbo entries.
206+ - name : Verify coverage cache inputs
207+ if : matrix.collect-coverage
208+ run : pnpm --dir src run verify:coverage-cache-inputs
167209 - name : Save Turbo cache
168210 if : steps.turbo-cache.outputs.cache-hit != 'true'
169211 uses : actions/cache/save@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
@@ -175,54 +217,58 @@ jobs:
175217 # there mostly adds Codecov overhead without changing pass/fail
176218 # behavior.
177219 # Coverage is uploaded in separate steps so each LCOV gets the
178- # correct flag set. Codecov double-counts overlapping lines when a
179- # single upload carries multiple flags whose paths overlap, so the
180- # core lanes and webview lane must be uploaded individually with
181- # their own flag.
220+ # correct flag set. Extension lanes instrument the same sources, so
221+ # union them before upload; a line is covered when any lane executes
222+ # it. Core and webview reports retain their independent flags.
182223 # See https://docs.codecov.com/docs/flags
183224 - name : Upload non-core coverage to Codecov
184- if : matrix.upload -coverage
225+ if : matrix.collect -coverage
185226 uses : codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
186227 with :
187228 files : >-
188- src/coverage/unit /lcov.info,
229+ src/coverage/merged /lcov.info,
189230 packages/cloud/coverage/lcov.info,
190231 packages/telemetry/coverage/lcov.info,
191232 apps/cli/coverage/lcov.info
192233 disable_search : true
193234 flags : ${{ matrix.codecov-flag }}
194235 token : ${{ secrets.CODECOV_TOKEN }}
195236 - name : Upload webview JSDOM coverage to Codecov
196- if : matrix.upload -coverage
237+ if : matrix.collect -coverage
197238 uses : codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
198239 with :
199240 files : webview-ui/coverage/lcov.info
200241 disable_search : true
201242 flags : webview-ui
202243 token : ${{ secrets.CODECOV_TOKEN }}
203244 - name : Upload core unit coverage to Codecov
204- if : matrix.upload -coverage
245+ if : matrix.collect -coverage
205246 uses : codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
206247 with :
207248 files : packages/core/coverage/unit/lcov.info
208249 disable_search : true
209250 flags : ${{ matrix.codecov-flag }},core-unit
210251 token : ${{ secrets.CODECOV_TOKEN }}
211252 - name : Upload core integration coverage to Codecov
212- if : matrix.upload -coverage
253+ if : matrix.collect -coverage
213254 uses : codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
214255 with :
215256 files : packages/core/coverage/integration/lcov.info
216257 disable_search : true
217258 flags : ${{ matrix.codecov-flag }},core-integration
218259 token : ${{ secrets.CODECOV_TOKEN }}
219260 - name : Upload coverage reports to GitHub
220- if : matrix.upload -coverage
261+ if : matrix.collect -coverage
221262 uses : actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
222263 with :
223264 name : coverage-reports-${{ matrix.name }}
224265 path : |
225- src/coverage/unit/lcov.info
266+ src/coverage/api/lcov.info
267+ src/coverage/core/lcov.info
268+ src/coverage/services/lcov.info
269+ src/coverage/misc/lcov.info
270+ src/coverage/tree-sitter/lcov.info
271+ src/coverage/merged/lcov.info
226272 webview-ui/coverage/lcov.info
227273 packages/cloud/coverage/lcov.info
228274 packages/telemetry/coverage/lcov.info
0 commit comments