From 5e9cbec038ac6462d4891adabdff446e8cf8fc87 Mon Sep 17 00:00:00 2001 From: Raphael Manke Date: Thu, 27 Aug 2026 14:23:49 +0200 Subject: [PATCH] ci: split integration tests into groups for isolated reruns Groups tests by failure domain (node/python/java/db/tracing/sls-plugin/ other) using vitest projects, and fans the integration-test CI job out into a fail-fast:false matrix over those groups. A flake in one group no longer cancels or blocks the others, and GitHub's rerun-failed-jobs only reruns the group that actually failed instead of all 25 test files. --- .github/workflows/ci.yml | 10 ++++-- integration-tests/tests/vitest.config.ts | 27 +++++++++++----- integration-tests/tests/vitest.groups.ts | 40 ++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 9 deletions(-) create mode 100644 integration-tests/tests/vitest.groups.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b8a908fb..8d29c983 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -197,11 +197,17 @@ jobs: TEST_MYSQL_PASSWORD: ${{ secrets.TEST_MYSQL_PASSWORD }} integration-test: - name: Integration Test + name: Integration Test (${{ matrix.group }}) if: github.event.pull_request.head.repo.full_name == github.repository needs: [deploy-cdk, deploy-sls] runs-on: ubuntu-latest environment: staging + strategy: + # One group flaking must not cancel or block the others. + fail-fast: false + matrix: + # Keep in sync with the group names in integration-tests/tests/vitest.groups.ts + group: [node, python, java, db, tracing, sls-plugin, other] steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -218,7 +224,7 @@ jobs: run: npm ci - name: Run integration tests working-directory: integration-tests/tests - run: npm run test + run: npm run test -- --project ${{ matrix.group }} env: DASH0_DEV_API_TOKEN: ${{ secrets.DASH0_DEV_API_TOKEN }} diff --git a/integration-tests/tests/vitest.config.ts b/integration-tests/tests/vitest.config.ts index 94d41143..fd331fec 100644 --- a/integration-tests/tests/vitest.config.ts +++ b/integration-tests/tests/vitest.config.ts @@ -1,13 +1,26 @@ import { defineConfig } from 'vitest/config'; +import { groups } from './vitest.groups'; + +const sharedTestConfig = { + exclude: ['**/test-sanity*'], + globals: true, + // Allow more in-file tests to run at once (default is 5) + maxConcurrency: 12, + pool: 'threads' as const, + maxWorkers: 12, +}; export default defineConfig({ test: { - include: ['**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], - exclude: ['**/test-sanity*'], - globals: true, - // Allow more in-file tests to run at once (default is 5) - maxConcurrency: 12, - pool: 'threads', - maxWorkers: 12, + ...sharedTestConfig, + // Running `vitest run` with no --project runs every group, same as before the split. + projects: groups.map(({ name, include, exclude }) => ({ + test: { + ...sharedTestConfig, + name, + include, + exclude: [...sharedTestConfig.exclude, ...(exclude ?? [])], + }, + })), }, }); diff --git a/integration-tests/tests/vitest.groups.ts b/integration-tests/tests/vitest.groups.ts new file mode 100644 index 00000000..7bf7f98d --- /dev/null +++ b/integration-tests/tests/vitest.groups.ts @@ -0,0 +1,40 @@ +// Single source of truth for how integration test files are split into +// CI groups. vitest.config.ts builds its `projects` from this list. +// ci.yml's matrix.group list must be kept in sync with these names by hand. +export const groups = [ + { + name: 'node', + include: ['**/test-node-*.test.ts', '**/test-manual-node.test.ts', '**/test-commonjs-bundle.test.ts'], + // test-node-single-traced.test.ts belongs to the `tracing` group instead — see below. + exclude: ['**/test-node-single-traced.test.ts'], + }, + { + name: 'python', + include: ['**/test-python-*.test.ts'], + }, + { + name: 'java', + include: ['**/test-java-*.test.ts'], + }, + { + name: 'db', + include: ['**/test-db.test.ts'], + }, + { + name: 'tracing', + include: ['**/test-tracing-scenarios-*.test.ts', '**/test-node-single-traced.test.ts'], + }, + { + name: 'sls-plugin', + include: ['**/test-serverless-plugin.test.ts'], + }, + { + name: 'other', + include: [ + '**/test-00-retries.test.ts', + '**/test-500-error.test.ts', + '**/test-payload-truncation.test.ts', + '**/test-dockerized-lambda.test.ts', + ], + }, +];