Merge pull request #416 from morluto/codex/ci-test-shards

ci: shard coverage tests and skip docs-only suites
This commit is contained in:
morluto 2026-07-23 01:55:37 +08:00 committed by GitHub
commit c7363178e7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 87 additions and 11 deletions

View File

@ -34,6 +34,7 @@ jobs:
name: Classify changes
runs-on: ubuntu-latest
outputs:
code: ${{ steps.package.outputs.required }}
package: ${{ steps.package.outputs.required }}
steps:
- uses: actions/checkout@v4
@ -60,7 +61,34 @@ jobs:
static:
name: Static checks
needs: changes
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
- name: Require successful change classification
env:
CHANGES_RESULT: ${{ needs.changes.result }}
run: test "${CHANGES_RESULT}" = "success"
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: npm
- run: npm ci
- if: github.event_name == 'push' || needs.changes.outputs.code == 'true'
run: npm run check:ci
- if: github.event_name == 'pull_request' && needs.changes.outputs.code != 'true'
run: npm run format:check
test-shard:
name: Test shard (${{ matrix.shard }})
needs: changes
if: github.event_name == 'push' || needs.changes.outputs.code == 'true'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shard: [1/2, 2/2]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
@ -68,24 +96,54 @@ jobs:
node-version-file: .nvmrc
cache: npm
- run: npm ci
- run: npm run check:ci
- run: npm run test:ci:shard -- --shard=${{ matrix.shard }}
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: vitest-report-${{ strategy.job-index }}
path: .vitest-reports/*
include-hidden-files: true
if-no-files-found: error
overwrite: true
retention-days: 1
test:
name: Test (coverage + timing)
needs: [changes, test-shard]
if: ${{ always() }}
runs-on: ubuntu-latest
steps:
- name: Require successful test shards
env:
CHANGES_RESULT: ${{ needs.changes.result }}
CODE_REQUIRED: ${{ needs.changes.outputs.code }}
SHARD_RESULT: ${{ needs.test-shard.result }}
run: |
test "${CHANGES_RESULT}" = "success"
test "${CODE_REQUIRED}" != "true" || test "${SHARD_RESULT}" = "success"
- uses: actions/checkout@v4
if: needs.changes.outputs.code == 'true' && success()
- uses: actions/setup-node@v4
if: needs.changes.outputs.code == 'true' && success()
with:
node-version-file: .nvmrc
cache: npm
- run: npm ci
- run: npm run test:ci
- if: needs.changes.outputs.code == 'true' && success()
run: npm ci
- uses: actions/download-artifact@v4
if: needs.changes.outputs.code == 'true' && success()
with:
path: .vitest-reports
pattern: vitest-report-*
merge-multiple: true
- if: needs.changes.outputs.code == 'true' && success()
run: npm run test:ci:merge
- uses: actions/upload-artifact@v4
if: always()
if: needs.changes.outputs.code == 'true' && always()
with:
name: test-results
path: test-results.xml
if-no-files-found: error
retention-days: 30
package-e2e:

2
.gitignore vendored
View File

@ -34,6 +34,8 @@ codedb.snapshot
htmlcov/
.coverage
coverage/
.vitest-reports/
test-results.xml
.turbo/
# OS

View File

@ -57,7 +57,7 @@ See [docs/architecture.mermaid](docs/architecture.mermaid) for a visual architec
- `npm run test:fast`: run the parallel test project without the serial integration group.
- `npm run test:integration`: run the serial filesystem, process, and CLI integration group.
- `npm run test:watch`: watch tests affected by working-tree changes in the parallel project, without coverage.
- `npm run test:coverage`: run the complete suite with coverage; CI owns verbose and JUnit reporting.
- `npm run test:coverage`: run the complete suite with coverage; CI shards the suite and owns JUnit reporting.
- `npm run typecheck`: run strict TypeScript checks without emitting files.
- `npm run lint`: apply oxlint rules (complexity, max-lines, unused vars, and TypeScript-specific checks).
- `npm run lint:fix`: auto-fix oxlint violations where possible.

View File

@ -40,14 +40,15 @@ artifact; the generated HTML is not committed.
Local `npm test` runs without coverage, retries, or verbose output. Use `npm run
test:fast` for the parallel group, `npm run test:integration` for serial
filesystem/process/CLI cases, and `npm run test:watch` to watch tests affected by
working-tree changes. CI runs `npm run test:ci`, which adds coverage, retries,
verbose output, and JUnit results. Coverage thresholds remain in
working-tree changes. CI splits the complete suite across two native Vitest
shards, then merges their coverage and JUnit reports. `npm run test:ci` runs the
equivalent unsharded gate locally. Coverage thresholds remain in
`vitest.config.ts`.
CI installs dependencies once for all static checks, cancels superseded PR
runs, and skips package and Windows lanes when a PR changes only files outside
the package/runtime/test boundary. TypeDoc renders only in pull-request CI; it
does not run in local commit or pre-push hooks, or in post-merge `main` CI.
runs, and skips package, Windows, and full test lanes for documentation-only
pull requests. TypeDoc renders only in pull-request CI; it does not run in local
commit or pre-push hooks, or in post-merge `main` CI.
Tests that need a temporary directory must use
`createTestTempDirectory` from `tests/fixtures/temporaryDirectory.ts`. The

View File

@ -84,7 +84,10 @@
"test:integration": "vitest run --project serial-integration",
"pretest:coverage": "npm run build:cached",
"test:coverage": "vitest run --coverage.enabled --coverage.provider=v8",
"test:ci": "npm run test:coverage -- --reporter=verbose --reporter=junit --outputFile.junit=test-results.xml",
"test:ci": "npm run test:coverage -- --reporter=default --reporter=junit --outputFile.junit=test-results.xml",
"pretest:ci:shard": "npm run build:cached",
"test:ci:shard": "vitest run --coverage.enabled --coverage.provider=v8 --coverage.thresholds.lines=0 --coverage.thresholds.functions=0 --coverage.thresholds.branches=0 --coverage.thresholds.statements=0 --reporter=default --reporter=blob",
"test:ci:merge": "vitest --merge-reports --coverage.enabled --coverage.provider=v8 --reporter=default --reporter=junit --outputFile.junit=test-results.xml",
"pretest:verbose": "npm run build:cached",
"test:verbose": "vitest run --reporter=verbose",
"pretest:watch": "npm run build:cached",

View File

@ -20,6 +20,18 @@ describe("package installation workflows", () => {
expect(continuousIntegration).toContain("npm run verify:package");
expect(continuousIntegration).toContain("name: Static checks");
expect(continuousIntegration).toContain("npm run check:ci");
expect(continuousIntegration).toContain("shard: [1/2, 2/2]");
expect(continuousIntegration).toContain("needs: [changes, test-shard]");
expect(continuousIntegration).toContain("if-no-files-found: error");
expect(continuousIntegration).toContain("overwrite: true");
expect(continuousIntegration).toContain(
"code: ${{ steps.package.outputs.required }}",
);
expect(continuousIntegration).toContain("CODE_REQUIRED:");
expect(continuousIntegration).toContain(
'test "${CODE_REQUIRED}" != "true" || test "${SHARD_RESULT}" = "success"',
);
expect(continuousIntegration).toContain("npm run test:ci:merge");
expect(continuousIntegration).toContain("needs: changes");
expect(continuousIntegration).toContain(
"cancel-in-progress: ${{ github.event_name == 'pull_request' }}",