From 461fc365822ccec47e21aede667c4795e7a6fe88 Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 20 Feb 2026 11:21:39 +0200 Subject: [PATCH 01/12] ci(repo): improve CI/CD pipeline performance Re-enable turbo remote cache that was accidentally left disabled since Dec 2025 during the Verdaccio migration debugging. Compute affected integration suites once in a pre-job instead of spawning 20+ runners that each discover "no work" after setup. Unblock static-analysis, unit-tests, and pkg-pr-new from the build-packages gate so they start immediately with cache hits. Use turbo build in pkg-pr-new instead of plain pnpm build. --- .github/workflows/ci.yml | 260 +++++++++++++++++++++++---------------- 1 file changed, 151 insertions(+), 109 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e0b0e25a5f4..c6ba2befd52 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -69,10 +69,10 @@ jobs: - name: Setup id: config uses: ./.github/actions/init-blacksmith - # with: - # turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} - # turbo-team: ${{ vars.TURBO_TEAM }} - # turbo-token: ${{ secrets.TURBO_TOKEN }} + with: + turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} + turbo-team: ${{ vars.TURBO_TEAM }} + turbo-token: ${{ secrets.TURBO_TOKEN }} - name: Verify lockfile is deduped run: pnpm dedupe --check @@ -117,11 +117,11 @@ jobs: - name: Setup id: config uses: ./.github/actions/init-blacksmith - # with: - # turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} - # turbo-summarize: ${{ env.TURBO_SUMMARIZE }} - # turbo-team: ${{ vars.TURBO_TEAM }} - # turbo-token: ${{ secrets.TURBO_TOKEN }} + with: + turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} + turbo-summarize: ${{ env.TURBO_SUMMARIZE }} + turbo-team: ${{ vars.TURBO_TEAM }} + turbo-token: ${{ secrets.TURBO_TOKEN }} - name: Turbo Build run: pnpm turbo build $TURBO_ARGS --only @@ -136,7 +136,7 @@ jobs: retention-days: 5 static-analysis: - needs: [check-permissions, build-packages] + needs: [check-permissions] if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }} name: Static analysis permissions: @@ -163,11 +163,11 @@ jobs: - name: Setup id: config uses: ./.github/actions/init-blacksmith - # with: - # turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} - # turbo-summarize: ${{ env.TURBO_SUMMARIZE }} - # turbo-team: ${{ vars.TURBO_TEAM }} - # turbo-token: ${{ secrets.TURBO_TOKEN }} + with: + turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} + turbo-summarize: ${{ env.TURBO_SUMMARIZE }} + turbo-team: ${{ vars.TURBO_TEAM }} + turbo-token: ${{ secrets.TURBO_TOKEN }} - name: Check size using bundlewatch continue-on-error: true @@ -199,7 +199,7 @@ jobs: retention-days: 5 unit-tests: - needs: [check-permissions, build-packages] + needs: [check-permissions] if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }} name: Unit Tests (${{ matrix.filter-label }}) permissions: @@ -237,10 +237,10 @@ jobs: with: # Ensures that all builds are cached appropriately with a consistent run name `Unit Tests (20)`. node-version: ${{ matrix.node-version }} - # turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} - # turbo-summarize: ${{ env.TURBO_SUMMARIZE }} - # turbo-team: ${{ vars.TURBO_TEAM }} - # turbo-token: ${{ secrets.TURBO_TOKEN }} + turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} + turbo-summarize: ${{ env.TURBO_SUMMARIZE }} + turbo-team: ${{ vars.TURBO_TEAM }} + turbo-token: ${{ secrets.TURBO_TOKEN }} - name: Run tests in packages run: | @@ -272,61 +272,18 @@ jobs: path: .turbo/runs retention-days: 5 - integration-tests: - # needs: [check-permissions, build-packages] + compute-integration-matrix: needs: [check-permissions] if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }} - name: Integration Tests (${{ matrix.test-name }}, ${{ matrix.test-project }}${{ matrix.next-version && format(', {0}', matrix.next-version) || '' }}) - permissions: - contents: read - actions: write # needed for actions/upload-artifact + name: Compute Integration Matrix runs-on: "blacksmith-8vcpu-ubuntu-2204" defaults: run: shell: bash - timeout-minutes: ${{ vars.TIMEOUT_MINUTES_LONG && fromJSON(vars.TIMEOUT_MINUTES_LONG) || 15 }} - - strategy: - fail-fast: false - matrix: - test-name: - [ - "generic", - "express", - "ap-flows", - "localhost", - "sessions", - "sessions:staging", - "handshake", - "handshake:staging", - "astro", - "tanstack-react-start", - "vue", - "nuxt", - "react-router", - "custom", - ] - test-project: ["chrome"] - include: - - test-name: "billing" - test-project: "chrome" - - test-name: "machine" - test-project: "chrome" - - test-name: "nextjs" - test-project: "chrome" - next-version: "15" - - test-name: "nextjs" - test-project: "chrome" - next-version: "16" - - test-name: "quickstart" - test-project: "chrome" - next-version: "15" - - test-name: "quickstart" - test-project: "chrome" - next-version: "16" - - test-name: "cache-components" - test-project: "chrome" - next-version: "16" + timeout-minutes: ${{ vars.TIMEOUT_MINUTES_NORMAL && fromJSON(vars.TIMEOUT_MINUTES_NORMAL) || 10 }} + outputs: + matrix: ${{ steps.compute.outputs.matrix }} + has-affected: ${{ steps.compute.outputs.has-affected }} steps: - name: Checkout Repo @@ -341,50 +298,141 @@ jobs: id: config uses: ./.github/actions/init-blacksmith with: - # turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} - # turbo-team: ${{ vars.TURBO_TEAM }} - # turbo-token: ${{ secrets.TURBO_TOKEN }} - playwright-enabled: true + turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} + turbo-team: ${{ vars.TURBO_TEAM }} + turbo-token: ${{ secrets.TURBO_TOKEN }} - - name: Verify jq is installed - shell: bash - run: | - if ! command -v jq &> /dev/null; then - echo "jq not found, installing..." - sudo apt-get update && sudo apt-get install -y jq - fi - jq --version + - name: Build packages + run: pnpm turbo build $TURBO_ARGS --only - - name: Task Status - id: task-status + - name: Compute affected integration suites + id: compute env: E2E_APP_CLERK_JS_DIR: ${{runner.temp}} E2E_APP_CLERK_UI_DIR: ${{runner.temp}} E2E_CLERK_JS_VERSION: "latest" E2E_CLERK_UI_VERSION: "latest" - E2E_NEXTJS_VERSION: ${{ matrix.next-version }} - E2E_PROJECT: ${{ matrix.test-project }} + E2E_PROJECT: "chrome" INTEGRATION_INSTANCE_KEYS: ${{ secrets.INTEGRATION_INSTANCE_KEYS }} run: | - # Use turbo's built-in --affected flag to detect changes - # This automatically uses GITHUB_BASE_REF in GitHub Actions - TASK_COUNT=$(pnpm turbo run test:integration:${{ matrix.test-name }} --affected --dry=json 2>/dev/null | jq '.tasks | length' 2>/dev/null || echo "0") - - if [ "$TASK_COUNT" -gt 0 ]; then - AFFECTED=1 - else - AFFECTED=0 + # All possible test-name values from the static matrix + TEST_NAMES=( + "generic" + "express" + "ap-flows" + "localhost" + "sessions" + "sessions:staging" + "handshake" + "handshake:staging" + "astro" + "tanstack-react-start" + "vue" + "nuxt" + "react-router" + "custom" + "billing" + "machine" + "nextjs" + "quickstart" + "cache-components" + ) + + AFFECTED_NAMES=() + for name in "${TEST_NAMES[@]}"; do + TASK_COUNT=$(pnpm turbo run "test:integration:${name}" --affected --dry=json 2>/dev/null | jq '.tasks | length' 2>/dev/null || echo "0") + if [ "$TASK_COUNT" -gt 0 ]; then + AFFECTED_NAMES+=("$name") + echo " affected: $name" + else + echo " skipped: $name" + fi + done + + if [ ${#AFFECTED_NAMES[@]} -eq 0 ]; then + echo "has-affected=false" >> $GITHUB_OUTPUT + echo 'matrix={"include":[]}' >> $GITHUB_OUTPUT + echo "No integration suites affected." + exit 0 fi - echo "affected=${AFFECTED}" - echo "affected=${AFFECTED}" >> $GITHUB_OUTPUT + echo "has-affected=true" >> $GITHUB_OUTPUT + + # Build the matrix JSON, expanding entries that have extra fields (next-version) + MATRIX='{"include":[' + FIRST=true + for name in "${AFFECTED_NAMES[@]}"; do + case "$name" in + nextjs) + for ver in "15" "16"; do + $FIRST || MATRIX+=',' + MATRIX+="{\"test-name\":\"nextjs\",\"test-project\":\"chrome\",\"next-version\":\"${ver}\"}" + FIRST=false + done + ;; + quickstart) + for ver in "15" "16"; do + $FIRST || MATRIX+=',' + MATRIX+="{\"test-name\":\"quickstart\",\"test-project\":\"chrome\",\"next-version\":\"${ver}\"}" + FIRST=false + done + ;; + cache-components) + $FIRST || MATRIX+=',' + MATRIX+="{\"test-name\":\"cache-components\",\"test-project\":\"chrome\",\"next-version\":\"16\"}" + FIRST=false + ;; + *) + $FIRST || MATRIX+=',' + MATRIX+="{\"test-name\":\"${name}\",\"test-project\":\"chrome\"}" + FIRST=false + ;; + esac + done + MATRIX+=']}' + + echo "matrix=${MATRIX}" >> $GITHUB_OUTPUT + echo "Matrix: ${MATRIX}" + + integration-tests: + needs: [compute-integration-matrix] + if: ${{ needs.compute-integration-matrix.outputs.has-affected == 'true' }} + name: Integration Tests (${{ matrix.test-name }}, ${{ matrix.test-project }}${{ matrix.next-version && format(', {0}', matrix.next-version) || '' }}) + permissions: + contents: read + actions: write # needed for actions/upload-artifact + runs-on: "blacksmith-8vcpu-ubuntu-2204" + defaults: + run: + shell: bash + timeout-minutes: ${{ vars.TIMEOUT_MINUTES_LONG && fromJSON(vars.TIMEOUT_MINUTES_LONG) || 15 }} + + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.compute-integration-matrix.outputs.matrix) }} + + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + with: + fetch-depth: 1 + fetch-tags: false + filter: "blob:none" + show-progress: false + + - name: Setup + id: config + uses: ./.github/actions/init-blacksmith + with: + turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} + turbo-team: ${{ vars.TURBO_TEAM }} + turbo-token: ${{ secrets.TURBO_TOKEN }} + playwright-enabled: true - name: Version packages for snapshot - if: ${{ steps.task-status.outputs.affected == '1' }} run: npm run version-packages:snapshot ci - name: Verdaccio - if: ${{ steps.task-status.outputs.affected == '1' }} uses: ./.github/actions/verdaccio with: publish-cmd: | @@ -394,7 +442,6 @@ jobs: run: sed -i -E 's/link-workspace-packages=(deep|true)/link-workspace-packages=false/' .npmrc - name: Install @clerk/backend in /integration - if: ${{ steps.task-status.outputs.affected == '1' }} working-directory: ./integration run: | pnpm init @@ -404,7 +451,6 @@ jobs: # Install published packages from Verdaccio to test against real npm install scenarios # rather than local monorepo builds. Validates package structure, dependencies, and entry points. - name: Install @clerk/clerk-js in os temp - if: ${{ steps.task-status.outputs.affected == '1' }} working-directory: ${{runner.temp}} run: | mkdir clerk-js && cd clerk-js @@ -413,7 +459,6 @@ jobs: pnpm add @clerk/clerk-js - name: Install @clerk/ui in os temp - if: ${{ steps.task-status.outputs.affected == '1' }} working-directory: ${{runner.temp}} run: | mkdir clerk-ui && cd clerk-ui @@ -426,7 +471,6 @@ jobs: run: cd packages/astro && pnpm copy:components - name: Write all ENV certificates to files in integration/certs - if: ${{ steps.task-status.outputs.affected == '1' }} uses: actions/github-script@v7 env: INTEGRATION_CERTS: "${{secrets.INTEGRATION_CERTS}}" @@ -444,12 +488,10 @@ jobs: } - name: LS certs - if: ${{ steps.task-status.outputs.affected == '1' }} working-directory: ./integration/certs run: ls -la && pwd - name: Run Integration Tests - if: ${{ steps.task-status.outputs.affected == '1' }} id: integration-tests timeout-minutes: 25 run: pnpm turbo test:integration:${{ matrix.test-name }} $TURBO_ARGS @@ -477,7 +519,7 @@ jobs: pkg-pr-new: name: Publish with pkg-pr-new if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }} - needs: [check-permissions, build-packages] + needs: [check-permissions] runs-on: "blacksmith-8vcpu-ubuntu-2204" defaults: run: @@ -500,10 +542,10 @@ jobs: with: turbo-enabled: true node-version: 22 - # turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} - # turbo-summarize: ${{ env.TURBO_SUMMARIZE }} - # turbo-team: ${{ vars.TURBO_TEAM }} - # turbo-token: ${{ secrets.TURBO_TOKEN }} + turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} + turbo-summarize: ${{ env.TURBO_SUMMARIZE }} + turbo-team: ${{ vars.TURBO_TEAM }} + turbo-token: ${{ secrets.TURBO_TOKEN }} - name: Publish with pkg-pr-new - run: pnpm run build && pnpx pkg-pr-new@${{ vars.PKG_PR_NEW_VERSION || '0.0.49' }} publish --compact --pnpm './packages/*' + run: pnpm turbo build $TURBO_ARGS && pnpx pkg-pr-new@${{ vars.PKG_PR_NEW_VERSION || '0.0.49' }} publish --compact --pnpm './packages/*' From 50b7c28b8cedd053f5c6242712a0e349c0d5c2a5 Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 20 Feb 2026 11:35:18 +0200 Subject: [PATCH 02/12] fix(ci): use static matrix with per-job affected check for integration tests Dynamic matrix breaks required status checks because GitHub expects specific job names to be reported. Switch to: compute affected list in a pre-job, keep the static matrix so all job names are reported, but skip expensive steps (checkout, setup, build, test) for non-affected entries using the shared affected output. --- .github/workflows/ci.yml | 158 ++++++++++++++++++++------------------- 1 file changed, 81 insertions(+), 77 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c6ba2befd52..d61f660700e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -272,18 +272,17 @@ jobs: path: .turbo/runs retention-days: 5 - compute-integration-matrix: + compute-affected-integration: needs: [check-permissions] if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }} - name: Compute Integration Matrix + name: Compute Affected Integration Suites runs-on: "blacksmith-8vcpu-ubuntu-2204" defaults: run: shell: bash timeout-minutes: ${{ vars.TIMEOUT_MINUTES_NORMAL && fromJSON(vars.TIMEOUT_MINUTES_NORMAL) || 10 }} outputs: - matrix: ${{ steps.compute.outputs.matrix }} - has-affected: ${{ steps.compute.outputs.has-affected }} + affected: ${{ steps.compute.outputs.affected }} steps: - name: Checkout Repo @@ -315,88 +314,36 @@ jobs: E2E_PROJECT: "chrome" INTEGRATION_INSTANCE_KEYS: ${{ secrets.INTEGRATION_INSTANCE_KEYS }} run: | - # All possible test-name values from the static matrix TEST_NAMES=( - "generic" - "express" - "ap-flows" - "localhost" - "sessions" - "sessions:staging" - "handshake" - "handshake:staging" - "astro" - "tanstack-react-start" - "vue" - "nuxt" - "react-router" - "custom" - "billing" - "machine" - "nextjs" - "quickstart" - "cache-components" + "generic" "express" "ap-flows" "localhost" + "sessions" "sessions:staging" "handshake" "handshake:staging" + "astro" "tanstack-react-start" "vue" "nuxt" + "react-router" "custom" "billing" "machine" + "nextjs" "quickstart" "cache-components" ) - AFFECTED_NAMES=() + AFFECTED_JSON="{" + FIRST=true for name in "${TEST_NAMES[@]}"; do TASK_COUNT=$(pnpm turbo run "test:integration:${name}" --affected --dry=json 2>/dev/null | jq '.tasks | length' 2>/dev/null || echo "0") + $FIRST || AFFECTED_JSON+="," if [ "$TASK_COUNT" -gt 0 ]; then - AFFECTED_NAMES+=("$name") + AFFECTED_JSON+="\"${name}\":true" echo " affected: $name" else + AFFECTED_JSON+="\"${name}\":false" echo " skipped: $name" fi + FIRST=false done + AFFECTED_JSON+="}" - if [ ${#AFFECTED_NAMES[@]} -eq 0 ]; then - echo "has-affected=false" >> $GITHUB_OUTPUT - echo 'matrix={"include":[]}' >> $GITHUB_OUTPUT - echo "No integration suites affected." - exit 0 - fi - - echo "has-affected=true" >> $GITHUB_OUTPUT - - # Build the matrix JSON, expanding entries that have extra fields (next-version) - MATRIX='{"include":[' - FIRST=true - for name in "${AFFECTED_NAMES[@]}"; do - case "$name" in - nextjs) - for ver in "15" "16"; do - $FIRST || MATRIX+=',' - MATRIX+="{\"test-name\":\"nextjs\",\"test-project\":\"chrome\",\"next-version\":\"${ver}\"}" - FIRST=false - done - ;; - quickstart) - for ver in "15" "16"; do - $FIRST || MATRIX+=',' - MATRIX+="{\"test-name\":\"quickstart\",\"test-project\":\"chrome\",\"next-version\":\"${ver}\"}" - FIRST=false - done - ;; - cache-components) - $FIRST || MATRIX+=',' - MATRIX+="{\"test-name\":\"cache-components\",\"test-project\":\"chrome\",\"next-version\":\"16\"}" - FIRST=false - ;; - *) - $FIRST || MATRIX+=',' - MATRIX+="{\"test-name\":\"${name}\",\"test-project\":\"chrome\"}" - FIRST=false - ;; - esac - done - MATRIX+=']}' - - echo "matrix=${MATRIX}" >> $GITHUB_OUTPUT - echo "Matrix: ${MATRIX}" + echo "affected=${AFFECTED_JSON}" >> $GITHUB_OUTPUT + echo "Affected: ${AFFECTED_JSON}" integration-tests: - needs: [compute-integration-matrix] - if: ${{ needs.compute-integration-matrix.outputs.has-affected == 'true' }} + needs: [compute-affected-integration] + if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }} name: Integration Tests (${{ matrix.test-name }}, ${{ matrix.test-project }}${{ matrix.next-version && format(', {0}', matrix.next-version) || '' }}) permissions: contents: read @@ -409,10 +356,59 @@ jobs: strategy: fail-fast: false - matrix: ${{ fromJSON(needs.compute-integration-matrix.outputs.matrix) }} + matrix: + test-name: + [ + "generic", + "express", + "ap-flows", + "localhost", + "sessions", + "sessions:staging", + "handshake", + "handshake:staging", + "astro", + "tanstack-react-start", + "vue", + "nuxt", + "react-router", + "custom", + ] + test-project: ["chrome"] + include: + - test-name: "billing" + test-project: "chrome" + - test-name: "machine" + test-project: "chrome" + - test-name: "nextjs" + test-project: "chrome" + next-version: "15" + - test-name: "nextjs" + test-project: "chrome" + next-version: "16" + - test-name: "quickstart" + test-project: "chrome" + next-version: "15" + - test-name: "quickstart" + test-project: "chrome" + next-version: "16" + - test-name: "cache-components" + test-project: "chrome" + next-version: "16" steps: + - name: Check if affected + id: affected + run: | + AFFECTED_JSON='${{ needs.compute-affected-integration.outputs.affected }}' + IS_AFFECTED=$(echo "$AFFECTED_JSON" | jq -r '.["${{ matrix.test-name }}"] // false') + echo "skip=$([ "$IS_AFFECTED" = "true" ] && echo "false" || echo "true")" >> $GITHUB_OUTPUT + if [ "$IS_AFFECTED" != "true" ]; then + echo "Skipping ${{ matrix.test-name }} - not affected by changes" + fi + - name: Checkout Repo + if: ${{ steps.affected.outputs.skip != 'true' }} uses: actions/checkout@v4 with: fetch-depth: 1 @@ -421,6 +417,7 @@ jobs: show-progress: false - name: Setup + if: ${{ steps.affected.outputs.skip != 'true' }} id: config uses: ./.github/actions/init-blacksmith with: @@ -430,27 +427,30 @@ jobs: playwright-enabled: true - name: Version packages for snapshot + if: ${{ steps.affected.outputs.skip != 'true' }} run: npm run version-packages:snapshot ci - name: Verdaccio + if: ${{ steps.affected.outputs.skip != 'true' }} uses: ./.github/actions/verdaccio with: publish-cmd: | if [ "$(pnpm config get registry)" = "https://registry.npmjs.org/" ]; then echo 'Error: Using default registry' && exit 1; else pnpm turbo build $TURBO_ARGS --only && pnpm changeset publish --no-git-tag --tag latest; fi - name: Edit .npmrc [link-workspace-packages=false] + if: ${{ steps.affected.outputs.skip != 'true' }} run: sed -i -E 's/link-workspace-packages=(deep|true)/link-workspace-packages=false/' .npmrc - name: Install @clerk/backend in /integration + if: ${{ steps.affected.outputs.skip != 'true' }} working-directory: ./integration run: | pnpm init pnpm config set minimum-release-age-exclude @clerk/* pnpm add @clerk/backend - # Install published packages from Verdaccio to test against real npm install scenarios - # rather than local monorepo builds. Validates package structure, dependencies, and entry points. - name: Install @clerk/clerk-js in os temp + if: ${{ steps.affected.outputs.skip != 'true' }} working-directory: ${{runner.temp}} run: | mkdir clerk-js && cd clerk-js @@ -459,6 +459,7 @@ jobs: pnpm add @clerk/clerk-js - name: Install @clerk/ui in os temp + if: ${{ steps.affected.outputs.skip != 'true' }} working-directory: ${{runner.temp}} run: | mkdir clerk-ui && cd clerk-ui @@ -467,10 +468,11 @@ jobs: pnpm add @clerk/ui - name: Copy components @clerk/astro - if: ${{ matrix.test-name == 'astro' }} + if: ${{ steps.affected.outputs.skip != 'true' && matrix.test-name == 'astro' }} run: cd packages/astro && pnpm copy:components - name: Write all ENV certificates to files in integration/certs + if: ${{ steps.affected.outputs.skip != 'true' }} uses: actions/github-script@v7 env: INTEGRATION_CERTS: "${{secrets.INTEGRATION_CERTS}}" @@ -488,10 +490,12 @@ jobs: } - name: LS certs + if: ${{ steps.affected.outputs.skip != 'true' }} working-directory: ./integration/certs run: ls -la && pwd - name: Run Integration Tests + if: ${{ steps.affected.outputs.skip != 'true' }} id: integration-tests timeout-minutes: 25 run: pnpm turbo test:integration:${{ matrix.test-name }} $TURBO_ARGS @@ -509,7 +513,7 @@ jobs: VERCEL_AUTOMATION_BYPASS_SECRET: ${{ secrets.VERCEL_AUTOMATION_BYPASS_SECRET }} - name: Upload test-results - if: ${{ cancelled() || failure() }} + if: ${{ !steps.affected.outputs.skip && (cancelled() || failure()) }} uses: actions/upload-artifact@v4 with: name: playwright-traces-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.test-name }}${{ matrix.next-version && format('-next{0}', matrix.next-version) || '' }} From 1a8c2a79e1de3732462d5a807d65563e5a7ee30c Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 20 Feb 2026 12:00:48 +0200 Subject: [PATCH 03/12] test(ci): trigger integration tests to verify CI pipeline changes Add trailing newline to force turbo affected detection for integration suites. This verifies turbo remote cache, affected computation, and the full E2E pipeline work end-to-end. Revert after verification. --- integration/presets/generic.ts | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 integration/presets/generic.ts diff --git a/integration/presets/generic.ts b/integration/presets/generic.ts new file mode 100644 index 00000000000..e69de29bb2d From c064b44d919b6f92acfc9c06981215400be9b977 Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 20 Feb 2026 12:13:30 +0200 Subject: [PATCH 04/12] test(ci): trigger integration affected detection with real file change --- integration/presets/envs.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/integration/presets/envs.ts b/integration/presets/envs.ts index 413cff07792..67988f5349f 100644 --- a/integration/presets/envs.ts +++ b/integration/presets/envs.ts @@ -1,3 +1,4 @@ +// CI perf verification trigger - revert after confirming pipeline works import { resolve } from 'node:path'; import fs from 'fs-extra'; From 755487d790c1dd0d921c812955526d9091220268 Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 20 Feb 2026 12:16:52 +0200 Subject: [PATCH 05/12] fix(ci): remove secret from affected compute env to prevent output masking GitHub Actions was suppressing the affected JSON output because INTEGRATION_INSTANCE_KEYS was in the env, causing the secret masker to redact the output. The dry-run check doesn't need the secret. --- .github/workflows/ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d61f660700e..4edf7577c64 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -312,7 +312,6 @@ jobs: E2E_CLERK_JS_VERSION: "latest" E2E_CLERK_UI_VERSION: "latest" E2E_PROJECT: "chrome" - INTEGRATION_INSTANCE_KEYS: ${{ secrets.INTEGRATION_INSTANCE_KEYS }} run: | TEST_NAMES=( "generic" "express" "ap-flows" "localhost" From c030ca6e04322a24ceec1534656a1fa7c5e6c544 Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 20 Feb 2026 12:27:26 +0200 Subject: [PATCH 06/12] chore: revert test trigger file changes --- integration/presets/envs.ts | 1 - integration/presets/generic.ts | 0 2 files changed, 1 deletion(-) delete mode 100644 integration/presets/generic.ts diff --git a/integration/presets/envs.ts b/integration/presets/envs.ts index 67988f5349f..413cff07792 100644 --- a/integration/presets/envs.ts +++ b/integration/presets/envs.ts @@ -1,4 +1,3 @@ -// CI perf verification trigger - revert after confirming pipeline works import { resolve } from 'node:path'; import fs from 'fs-extra'; diff --git a/integration/presets/generic.ts b/integration/presets/generic.ts deleted file mode 100644 index e69de29bb2d..00000000000 From 83c31f1b2a0393b5415014a67fd51814bdd2296e Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 20 Feb 2026 13:03:36 +0200 Subject: [PATCH 07/12] ci(repo): detect package source changes for integration test affected check Turbo integration tasks only track integration/** as inputs, so changes in packages/clerk-js, packages/ui, packages/react etc. don't trigger them via turbo --affected. Add a git diff check against the base branch to detect source changes in SDK packages and force all integration suites to run when they're found. --- .github/workflows/ci.yml | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4edf7577c64..298e88810cc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -321,16 +321,33 @@ jobs: "nextjs" "quickstart" "cache-components" ) + # Check if frontend packages changed. Turbo integration tasks only + # track integration/** as inputs, so they miss changes in packages + # that all E2E tests depend on. When these packages change, force + # all suites to run. + FORCE_ALL=false + BASE_REF="${{ github.event.pull_request.base.ref || 'main' }}" + git fetch origin "${BASE_REF}" --depth=1 2>/dev/null || true + CHANGED_FILES=$(git diff --name-only "origin/${BASE_REF}...HEAD" 2>/dev/null || true) + if echo "$CHANGED_FILES" | grep -qE '^packages/(clerk-js|ui|react|shared|nextjs|remix|tanstack-react-start|vue|nuxt|astro|express|react-router|backend|types)/src/'; then + echo "Frontend/SDK package source changes detected, forcing all suites" + FORCE_ALL=true + fi + AFFECTED_JSON="{" FIRST=true for name in "${TEST_NAMES[@]}"; do - TASK_COUNT=$(pnpm turbo run "test:integration:${name}" --affected --dry=json 2>/dev/null | jq '.tasks | length' 2>/dev/null || echo "0") + if [ "$FORCE_ALL" = "true" ]; then + IS_AFFECTED=true + else + TASK_COUNT=$(pnpm turbo run "test:integration:${name}" --affected --dry=json 2>/dev/null | jq '.tasks | length' 2>/dev/null || echo "0") + [ "$TASK_COUNT" -gt 0 ] && IS_AFFECTED=true || IS_AFFECTED=false + fi $FIRST || AFFECTED_JSON+="," - if [ "$TASK_COUNT" -gt 0 ]; then - AFFECTED_JSON+="\"${name}\":true" + AFFECTED_JSON+="\"${name}\":${IS_AFFECTED}" + if [ "$IS_AFFECTED" = "true" ]; then echo " affected: $name" else - AFFECTED_JSON+="\"${name}\":false" echo " skipped: $name" fi FIRST=false From bcaf79d815cf2001f3543319892a0eaf4ca458ed Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 20 Feb 2026 13:26:14 +0200 Subject: [PATCH 08/12] ci(repo): use turbo dependsOn for integration test affected detection Replace the git diff hack with proper turbo.json dependsOn declarations. Each integration task now declares its framework SDK + clerk-js as dependencies, so turbo --affected naturally detects package source changes through the build task graph (^build cascading). For example, changing packages/shared/src/ triggers: @clerk/shared#build affected -> @clerk/nextjs#build affected (via ^build) -> //#test:integration:nextjs affected (via dependsOn) This gives precise per-suite detection instead of the previous approach which forced ALL suites on ANY package change. --- .github/workflows/ci.yml | 25 ++++--------------------- turbo.json | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 298e88810cc..4edf7577c64 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -321,33 +321,16 @@ jobs: "nextjs" "quickstart" "cache-components" ) - # Check if frontend packages changed. Turbo integration tasks only - # track integration/** as inputs, so they miss changes in packages - # that all E2E tests depend on. When these packages change, force - # all suites to run. - FORCE_ALL=false - BASE_REF="${{ github.event.pull_request.base.ref || 'main' }}" - git fetch origin "${BASE_REF}" --depth=1 2>/dev/null || true - CHANGED_FILES=$(git diff --name-only "origin/${BASE_REF}...HEAD" 2>/dev/null || true) - if echo "$CHANGED_FILES" | grep -qE '^packages/(clerk-js|ui|react|shared|nextjs|remix|tanstack-react-start|vue|nuxt|astro|express|react-router|backend|types)/src/'; then - echo "Frontend/SDK package source changes detected, forcing all suites" - FORCE_ALL=true - fi - AFFECTED_JSON="{" FIRST=true for name in "${TEST_NAMES[@]}"; do - if [ "$FORCE_ALL" = "true" ]; then - IS_AFFECTED=true - else - TASK_COUNT=$(pnpm turbo run "test:integration:${name}" --affected --dry=json 2>/dev/null | jq '.tasks | length' 2>/dev/null || echo "0") - [ "$TASK_COUNT" -gt 0 ] && IS_AFFECTED=true || IS_AFFECTED=false - fi + TASK_COUNT=$(pnpm turbo run "test:integration:${name}" --affected --dry=json 2>/dev/null | jq '.tasks | length' 2>/dev/null || echo "0") $FIRST || AFFECTED_JSON+="," - AFFECTED_JSON+="\"${name}\":${IS_AFFECTED}" - if [ "$IS_AFFECTED" = "true" ]; then + if [ "$TASK_COUNT" -gt 0 ]; then + AFFECTED_JSON+="\"${name}\":true" echo " affected: $name" else + AFFECTED_JSON+="\"${name}\":false" echo " skipped: $name" fi FIRST=false diff --git a/turbo.json b/turbo.json index f589f49d7a2..f898a1ba96d 100644 --- a/turbo.json +++ b/turbo.json @@ -202,101 +202,121 @@ "outputs": [] }, "//#test:integration:ap-flows": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:generic": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build", "@clerk/react#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:express": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/express#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:nextjs": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:nextjs:canary": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:quickstart": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS", "VERCEL_AUTOMATION_BYPASS_SECRET"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:astro": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/astro#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:localhost": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS", "NODE_EXTRA_CA_CERTS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:sessions": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "DISABLE_WEB_SECURITY", "E2E_*", "INTEGRATION_INSTANCE_KEYS", "NODE_EXTRA_CA_CERTS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:sessions:staging": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "DISABLE_WEB_SECURITY", "E2E_*", "INTEGRATION_INSTANCE_KEYS", "NODE_EXTRA_CA_CERTS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:handshake": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "DISABLE_WEB_SECURITY", "E2E_*", "INTEGRATION_INSTANCE_KEYS", "NODE_EXTRA_CA_CERTS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:handshake:staging": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "DISABLE_WEB_SECURITY", "E2E_*", "INTEGRATION_INSTANCE_KEYS", "NODE_EXTRA_CA_CERTS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:expo-web": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/expo#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:tanstack-react-start": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/tanstack-react-start#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:vue": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/vue#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:nuxt": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/nuxt#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:react-router": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/react-router#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:billing": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build", "@clerk/vue#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:machine": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build", "@clerk/astro#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:custom": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/react#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" From 2d9edd8f7e94e8fe54d2b4378a17121012b4a4d2 Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 20 Feb 2026 15:04:59 +0200 Subject: [PATCH 09/12] ci(repo): add safe default and validation for integration suite turbo config Two safeguards against drift between integration presets and turbo.json: 1. Safe default in compute step: if a suite has no dependsOn in turbo.json, it's forced to run (with a warning). Failure mode is "runs too much" not "silently never runs." 2. Validation in pre-checks: cross-references package.json test:integration:* scripts against turbo.json entries. Fails CI if any suite is missing dependsOn, catching the problem at PR time. --- .github/workflows/ci.yml | 55 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4edf7577c64..703243432fa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -90,6 +90,39 @@ jobs: pnpm changeset status --since=origin/main; fi + - name: Validate integration suite turbo config + run: | + # Every test:integration:* script in package.json must have a + # matching turbo.json task with dependsOn so that turbo --affected + # can detect SDK package changes. Without dependsOn, the suite + # would only react to integration/** file changes. + # Scripts that aren't test suites (utilities, disabled, base runner) + SKIP_SCRIPTS="test:integration:base test:integration:cleanup test:integration:deployment:nextjs test:integration:expo-web:disabled" + MISSING=() + SUITES=$(jq -r '.scripts | keys[] | select(startswith("test:integration:"))' package.json) + for script in $SUITES; do + if echo "$SKIP_SCRIPTS" | grep -qw "$script"; then + continue + fi + TASK_KEY="//#${script}" + DEPS=$(jq -r --arg k "$TASK_KEY" '(.tasks[$k].dependsOn // []) | length' turbo.json 2>/dev/null || echo "0") + if [ "$DEPS" = "0" ]; then + MISSING+=("$script") + fi + done + if [ ${#MISSING[@]} -gt 0 ]; then + echo "ERROR: The following integration suites are missing dependsOn in turbo.json:" + for s in "${MISSING[@]}"; do + echo " - $s" + done + echo "" + echo "Add dependsOn with the framework SDK build task(s) the suite uses," + echo "e.g.: \"dependsOn\": [\"@clerk/clerk-js#build\", \"@clerk/nextjs#build\"]" + echo "See existing entries in turbo.json for examples." + exit 1 + fi + echo "All integration suites have dependsOn configured" + build-packages: needs: [check-permissions] if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }} @@ -324,13 +357,25 @@ jobs: AFFECTED_JSON="{" FIRST=true for name in "${TEST_NAMES[@]}"; do - TASK_COUNT=$(pnpm turbo run "test:integration:${name}" --affected --dry=json 2>/dev/null | jq '.tasks | length' 2>/dev/null || echo "0") + TASK_KEY="//#test:integration:${name}" + HAS_DEPS=$(jq -r --arg k "$TASK_KEY" '(.tasks[$k].dependsOn // []) | length' turbo.json 2>/dev/null || echo "0") + + if [ "$HAS_DEPS" = "0" ]; then + # Safe default: suites without dependsOn always run. + # This prevents silent skipping when someone adds a suite + # but forgets to add dependsOn in turbo.json. + IS_AFFECTED=true + echo " WARNING: $name has no dependsOn in turbo.json, forcing affected" + else + TASK_COUNT=$(pnpm turbo run "test:integration:${name}" --affected --dry=json 2>/dev/null | jq '.tasks | length' 2>/dev/null || echo "0") + [ "$TASK_COUNT" -gt 0 ] && IS_AFFECTED=true || IS_AFFECTED=false + fi + $FIRST || AFFECTED_JSON+="," - if [ "$TASK_COUNT" -gt 0 ]; then - AFFECTED_JSON+="\"${name}\":true" + AFFECTED_JSON+="\"${name}\":${IS_AFFECTED}" + if [ "$IS_AFFECTED" = "true" ] && [ "$HAS_DEPS" != "0" ]; then echo " affected: $name" - else - AFFECTED_JSON+="\"${name}\":false" + elif [ "$IS_AFFECTED" != "true" ]; then echo " skipped: $name" fi FIRST=false From 0e5ca9367e8b39bb949736a5fa98d6f3255bd976 Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 20 Feb 2026 15:05:35 +0200 Subject: [PATCH 10/12] docs: add integration CLAUDE.md for test suite turbo config guidance --- integration/CLAUDE.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 integration/CLAUDE.md diff --git a/integration/CLAUDE.md b/integration/CLAUDE.md new file mode 100644 index 00000000000..229392c2ef4 --- /dev/null +++ b/integration/CLAUDE.md @@ -0,0 +1,32 @@ +# Integration Tests + +## Adding a new integration test suite + +When you add a new `test:integration:` script to `package.json`, you must also add a matching turbo.json task with `dependsOn` listing the Clerk packages the suite exercises. + +Example for a suite that tests a Next.js app: + +```json +"//#test:integration:my-new-suite": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], + "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], + "inputs": ["integration/**"], + "outputLogs": "new-only" +} +``` + +Why this matters: + +- The CI `compute-affected-integration` job uses `turbo --affected` to skip suites unaffected by a PR's changes +- Without `dependsOn`, turbo only tracks `integration/**` file changes and misses SDK package changes +- A suite without `dependsOn` will always run (safe default), but CI validation in pre-checks will fail until it's added +- `@clerk/clerk-js#build` should be included in every suite since all E2E tests load clerk-js in the browser + +How to pick the right dependencies: + +- Check which template your suite's apps use (see `integration/presets/` and `integration/templates/`) +- Each template installs a specific Clerk SDK (e.g. `next-app-router` uses `@clerk/nextjs`) +- Add that SDK's build task plus `@clerk/clerk-js#build` +- Turbo handles transitive deps through `^build`, so you only need direct framework SDKs + +The mapping from suite to framework SDK is also visible in `integration/presets/longRunningApps.ts` which maps app IDs to templates, and `package.json` scripts which map suite names to app IDs via `E2E_APP_ID`. From 0ff83bab1116e36a58f36efbf18f036c693c6c0c Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 20 Feb 2026 15:11:31 +0200 Subject: [PATCH 11/12] ci(repo): add @clerk/testing to dependsOn and derive suites from turbo.json Address Codex review findings: - Add @clerk/testing#build to all integration task dependsOn (the integration harness imports @clerk/testing directly) - Derive TEST_NAMES from turbo.json instead of hardcoding, eliminating one source of drift between the matrix, compute step, and turbo config --- .github/workflows/ci.yml | 9 ++------- turbo.json | 40 ++++++++++++++++++++-------------------- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 703243432fa..25e979de4ba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -346,13 +346,8 @@ jobs: E2E_CLERK_UI_VERSION: "latest" E2E_PROJECT: "chrome" run: | - TEST_NAMES=( - "generic" "express" "ap-flows" "localhost" - "sessions" "sessions:staging" "handshake" "handshake:staging" - "astro" "tanstack-react-start" "vue" "nuxt" - "react-router" "custom" "billing" "machine" - "nextjs" "quickstart" "cache-components" - ) + # Derive suite names from turbo.json (single source of truth) + readarray -t TEST_NAMES < <(jq -r '.tasks | keys[] | select(startswith("//#test:integration:")) | sub("^//#test:integration:"; "")' turbo.json) AFFECTED_JSON="{" FIRST=true diff --git a/turbo.json b/turbo.json index f898a1ba96d..fccb6f93fd0 100644 --- a/turbo.json +++ b/turbo.json @@ -202,121 +202,121 @@ "outputs": [] }, "//#test:integration:ap-flows": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:generic": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build", "@clerk/react#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/nextjs#build", "@clerk/react#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:express": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/express#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/express#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:nextjs": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:nextjs:canary": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:quickstart": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS", "VERCEL_AUTOMATION_BYPASS_SECRET"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:astro": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/astro#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/astro#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:localhost": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS", "NODE_EXTRA_CA_CERTS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:sessions": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "DISABLE_WEB_SECURITY", "E2E_*", "INTEGRATION_INSTANCE_KEYS", "NODE_EXTRA_CA_CERTS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:sessions:staging": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "DISABLE_WEB_SECURITY", "E2E_*", "INTEGRATION_INSTANCE_KEYS", "NODE_EXTRA_CA_CERTS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:handshake": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "DISABLE_WEB_SECURITY", "E2E_*", "INTEGRATION_INSTANCE_KEYS", "NODE_EXTRA_CA_CERTS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:handshake:staging": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/nextjs#build"], "env": ["CLEANUP", "DEBUG", "DISABLE_WEB_SECURITY", "E2E_*", "INTEGRATION_INSTANCE_KEYS", "NODE_EXTRA_CA_CERTS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:expo-web": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/expo#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/expo#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:tanstack-react-start": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/tanstack-react-start#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/tanstack-react-start#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:vue": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/vue#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/vue#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:nuxt": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/nuxt#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/nuxt#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:react-router": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/react-router#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/react-router#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:billing": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build", "@clerk/vue#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/nextjs#build", "@clerk/vue#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:machine": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/nextjs#build", "@clerk/astro#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/nextjs#build", "@clerk/astro#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" }, "//#test:integration:custom": { - "dependsOn": ["@clerk/clerk-js#build", "@clerk/react#build"], + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/react#build"], "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], "inputs": ["integration/**"], "outputLogs": "new-only" From d132529063e49e926fa31da2f9ffdb21ea9c9bdd Mon Sep 17 00:00:00 2001 From: Nikos Douvlis Date: Fri, 20 Feb 2026 16:15:18 +0200 Subject: [PATCH 12/12] ci(repo): add missing cache-components turbo task The CI validation correctly caught that test:integration:cache-components had no turbo.json task entry. Add it with the right dependsOn for its Next.js template. --- turbo.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/turbo.json b/turbo.json index fccb6f93fd0..64103c2cb9c 100644 --- a/turbo.json +++ b/turbo.json @@ -321,6 +321,12 @@ "inputs": ["integration/**"], "outputLogs": "new-only" }, + "//#test:integration:cache-components": { + "dependsOn": ["@clerk/clerk-js#build", "@clerk/testing#build", "@clerk/nextjs#build"], + "env": ["CLEANUP", "DEBUG", "E2E_*", "INTEGRATION_INSTANCE_KEYS"], + "inputs": ["integration/**"], + "outputLogs": "new-only" + }, "//#typedoc:generate": { "dependsOn": ["@clerk/nextjs#build", "@clerk/react#build", "@clerk/shared#build"], "inputs": ["tsconfig.typedoc.json", "typedoc.config.mjs"],