From 741ad85854d051953b592d7a2a9fc8880c9c1f01 Mon Sep 17 00:00:00 2001 From: Jacek Date: Thu, 21 May 2026 16:23:01 -0500 Subject: [PATCH 1/3] ci(repo): dogfood snapi api checks --- .changeset/dogfood-snapi.md | 2 + .github/workflows/api-changes.yml | 100 ++++++++++++++++++++++++++++++ snapi.config.json | 7 +++ 3 files changed, 109 insertions(+) create mode 100644 .changeset/dogfood-snapi.md create mode 100644 .github/workflows/api-changes.yml create mode 100644 snapi.config.json diff --git a/.changeset/dogfood-snapi.md b/.changeset/dogfood-snapi.md new file mode 100644 index 00000000000..a845151cc84 --- /dev/null +++ b/.changeset/dogfood-snapi.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/.github/workflows/api-changes.yml b/.github/workflows/api-changes.yml new file mode 100644 index 00000000000..8edc16f7126 --- /dev/null +++ b/.github/workflows/api-changes.yml @@ -0,0 +1,100 @@ +name: API Changes + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + branches: + - main + - release/v4 + - release/core-2 + paths: + - 'packages/clerk-js/**' + - 'packages/react/**' + - 'packages/shared/**' + - 'snapi.config.json' + - '.github/workflows/api-changes.yml' + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} + cancel-in-progress: true + +jobs: + check-api: + if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }} + name: API Changes + runs-on: 'blacksmith-8vcpu-ubuntu-2204' + continue-on-error: true + defaults: + run: + shell: bash + timeout-minutes: ${{ vars.TIMEOUT_MINUTES_NORMAL && fromJSON(vars.TIMEOUT_MINUTES_NORMAL) || 10 }} + + env: + SNAPI_PACKAGE: github:clerk/snapi#8c021a2796b313cdefa945a715df8f02e4f99867 + SNAPI_FILTERS: >- + --filter=@clerk/clerk-js + --filter=@clerk/react + --filter=@clerk/shared + + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + with: + fetch-depth: 100 + fetch-tags: false + filter: 'blob:none' + show-progress: false + + - name: Fetch base branch + run: git fetch origin "${GITHUB_BASE_REF}:refs/remotes/origin/${GITHUB_BASE_REF}" --depth=100 + + - name: Setup + id: config + uses: ./.github/actions/init-blacksmith + with: + cache-enabled: true + turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} + turbo-team: ${{ vars.TURBO_TEAM }} + turbo-token: ${{ secrets.TURBO_TOKEN }} + + - name: Build current declarations + run: pnpm turbo build:declarations $TURBO_ARGS $SNAPI_FILTERS + + - name: Generate current API snapshots + run: pnpm dlx --package "$SNAPI_PACKAGE" snapi snapshot --output .api-snapshots-current + + - name: Create baseline worktree + run: | + mkdir -p .worktrees + git worktree add .worktrees/snapi-baseline "origin/${GITHUB_BASE_REF}" + cp snapi.config.json .worktrees/snapi-baseline/snapi.config.json + + - name: Install baseline dependencies + run: pnpm --dir .worktrees/snapi-baseline install --frozen-lockfile + + - name: Build baseline declarations + run: pnpm --dir .worktrees/snapi-baseline turbo build:declarations $TURBO_ARGS $SNAPI_FILTERS + + - name: Generate baseline API snapshots + run: | + pnpm --dir .worktrees/snapi-baseline dlx --package "$SNAPI_PACKAGE" snapi snapshot \ + --output "$GITHUB_WORKSPACE/.api-snapshots-baseline" + + - name: Detect API changes + run: | + pnpm dlx --package "$SNAPI_PACKAGE" snapi detect \ + --baseline .api-snapshots-baseline \ + --output api-changes-report.md \ + --fail-on-breaking + + - name: Upload API changes report + uses: actions/upload-artifact@v4 + if: always() + with: + name: api-changes-report + path: api-changes-report.md + if-no-files-found: ignore + retention-days: 5 diff --git a/snapi.config.json b/snapi.config.json new file mode 100644 index 00000000000..070a39e8d86 --- /dev/null +++ b/snapi.config.json @@ -0,0 +1,7 @@ +{ + "packages": ["packages/clerk-js", "packages/react", "packages/shared"], + "snapshotDir": ".api-snapshots", + "mainBranch": "main", + "checkVersionBump": true, + "outputFormat": "markdown" +} From dd6e88606240aa2e2951c841357f98e9c527bf44 Mon Sep 17 00:00:00 2001 From: Jacek Date: Thu, 21 May 2026 20:30:37 -0500 Subject: [PATCH 2/3] ci(repo): drop redundant snapi current-snapshot step --- .github/workflows/api-changes.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/api-changes.yml b/.github/workflows/api-changes.yml index 8edc16f7126..aab4ce91a66 100644 --- a/.github/workflows/api-changes.yml +++ b/.github/workflows/api-changes.yml @@ -63,9 +63,6 @@ jobs: - name: Build current declarations run: pnpm turbo build:declarations $TURBO_ARGS $SNAPI_FILTERS - - name: Generate current API snapshots - run: pnpm dlx --package "$SNAPI_PACKAGE" snapi snapshot --output .api-snapshots-current - - name: Create baseline worktree run: | mkdir -p .worktrees From 7b226d2987b04d698cef789c23f3d52a5c9fbcbb Mon Sep 17 00:00:00 2001 From: Jacek Date: Thu, 21 May 2026 22:35:31 -0500 Subject: [PATCH 3/3] ci(repo): cache snapi baselines and watch @clerk/ui Publish the API baseline to a GHA cache on push to main and the release branches, keyed by commit sha. PR runs restore from that cache with a prefix-match fallback, and only rebuild the baseline via worktree on a full miss. Add @clerk/ui to the watched package set with a tsc-based build:declarations task matching @clerk/shared's pattern. --- .github/workflows/api-changes.yml | 92 ++++++++++++++++++++++---- packages/ui/package.json | 1 + packages/ui/tsconfig.declarations.json | 21 ++++++ snapi.config.json | 2 +- 4 files changed, 102 insertions(+), 14 deletions(-) create mode 100644 packages/ui/tsconfig.declarations.json diff --git a/.github/workflows/api-changes.yml b/.github/workflows/api-changes.yml index aab4ce91a66..e054b6f4981 100644 --- a/.github/workflows/api-changes.yml +++ b/.github/workflows/api-changes.yml @@ -1,6 +1,18 @@ name: API Changes on: + push: + branches: + - main + - release/v4 + - release/core-2 + paths: + - 'packages/clerk-js/**' + - 'packages/react/**' + - 'packages/shared/**' + - 'packages/ui/**' + - 'snapi.config.json' + - '.github/workflows/api-changes.yml' pull_request: types: [opened, synchronize, reopened, ready_for_review] branches: @@ -11,6 +23,7 @@ on: - 'packages/clerk-js/**' - 'packages/react/**' - 'packages/shared/**' + - 'packages/ui/**' - 'snapi.config.json' - '.github/workflows/api-changes.yml' @@ -19,11 +32,58 @@ permissions: concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} - cancel-in-progress: true + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +env: + SNAPI_PACKAGE: github:clerk/snapi#8c021a2796b313cdefa945a715df8f02e4f99867 + SNAPI_FILTERS: >- + --filter=@clerk/clerk-js + --filter=@clerk/react + --filter=@clerk/shared + --filter=@clerk/ui jobs: + publish-baseline: + if: github.event_name == 'push' + name: Publish API Baseline + runs-on: 'blacksmith-8vcpu-ubuntu-2204' + continue-on-error: true + defaults: + run: + shell: bash + timeout-minutes: ${{ vars.TIMEOUT_MINUTES_NORMAL && fromJSON(vars.TIMEOUT_MINUTES_NORMAL) || 10 }} + + steps: + - name: Checkout Repo + uses: actions/checkout@v4 + with: + filter: 'blob:none' + show-progress: false + + - name: Setup + uses: ./.github/actions/init-blacksmith + with: + cache-enabled: true + turbo-signature: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }} + turbo-team: ${{ vars.TURBO_TEAM }} + turbo-token: ${{ secrets.TURBO_TOKEN }} + + - name: Build declarations + run: pnpm turbo build:declarations $TURBO_ARGS $SNAPI_FILTERS + + - name: Generate API snapshot + run: | + pnpm dlx --package "$SNAPI_PACKAGE" snapi snapshot \ + --output "$GITHUB_WORKSPACE/.api-snapshots-baseline" + + - name: Save baseline to cache + uses: actions/cache/save@v4 + with: + path: .api-snapshots-baseline + key: snapi-baseline-${{ github.sha }} + check-api: - if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }} + if: ${{ github.event_name == 'pull_request' && github.event.pull_request.draft == false }} name: API Changes runs-on: 'blacksmith-8vcpu-ubuntu-2204' continue-on-error: true @@ -32,13 +92,6 @@ jobs: shell: bash timeout-minutes: ${{ vars.TIMEOUT_MINUTES_NORMAL && fromJSON(vars.TIMEOUT_MINUTES_NORMAL) || 10 }} - env: - SNAPI_PACKAGE: github:clerk/snapi#8c021a2796b313cdefa945a715df8f02e4f99867 - SNAPI_FILTERS: >- - --filter=@clerk/clerk-js - --filter=@clerk/react - --filter=@clerk/shared - steps: - name: Checkout Repo uses: actions/checkout@v4 @@ -48,11 +101,7 @@ jobs: filter: 'blob:none' show-progress: false - - name: Fetch base branch - run: git fetch origin "${GITHUB_BASE_REF}:refs/remotes/origin/${GITHUB_BASE_REF}" --depth=100 - - name: Setup - id: config uses: ./.github/actions/init-blacksmith with: cache-enabled: true @@ -60,22 +109,39 @@ jobs: turbo-team: ${{ vars.TURBO_TEAM }} turbo-token: ${{ secrets.TURBO_TOKEN }} + - name: Restore baseline from cache + id: baseline-cache + uses: actions/cache/restore@v4 + with: + path: .api-snapshots-baseline + key: snapi-baseline-${{ github.event.pull_request.base.sha }} + restore-keys: | + snapi-baseline- + - name: Build current declarations run: pnpm turbo build:declarations $TURBO_ARGS $SNAPI_FILTERS + - name: Fetch base branch + if: steps.baseline-cache.outputs.cache-matched-key == '' + run: git fetch origin "${GITHUB_BASE_REF}:refs/remotes/origin/${GITHUB_BASE_REF}" --depth=100 + - name: Create baseline worktree + if: steps.baseline-cache.outputs.cache-matched-key == '' run: | mkdir -p .worktrees git worktree add .worktrees/snapi-baseline "origin/${GITHUB_BASE_REF}" cp snapi.config.json .worktrees/snapi-baseline/snapi.config.json - name: Install baseline dependencies + if: steps.baseline-cache.outputs.cache-matched-key == '' run: pnpm --dir .worktrees/snapi-baseline install --frozen-lockfile - name: Build baseline declarations + if: steps.baseline-cache.outputs.cache-matched-key == '' run: pnpm --dir .worktrees/snapi-baseline turbo build:declarations $TURBO_ARGS $SNAPI_FILTERS - name: Generate baseline API snapshots + if: steps.baseline-cache.outputs.cache-matched-key == '' run: | pnpm --dir .worktrees/snapi-baseline dlx --package "$SNAPI_PACKAGE" snapi snapshot \ --output "$GITHUB_WORKSPACE/.api-snapshots-baseline" diff --git a/packages/ui/package.json b/packages/ui/package.json index 256b30f6bfa..70945f0288d 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -71,6 +71,7 @@ "scripts": { "build": "pnpm build:umd && pnpm build:esm && pnpm check:no-rhc && pnpm type-check", "build:analyze": "rspack build --config rspack.config.js --env production --env analyze --analyze", + "build:declarations": "tsc -p tsconfig.declarations.json", "build:esm": "tsdown", "build:rsdoctor": "RSDOCTOR=true rspack build --config rspack.config.js --env production", "build:umd": "rspack build --config rspack.config.js --env production", diff --git a/packages/ui/tsconfig.declarations.json b/packages/ui/tsconfig.declarations.json new file mode 100644 index 00000000000..a1fc0a91dee --- /dev/null +++ b/packages/ui/tsconfig.declarations.json @@ -0,0 +1,21 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "declaration": true, + "declarationDir": "./dist", + "declarationMap": true, + "emitDeclarationOnly": true, + "skipLibCheck": true + }, + "exclude": [ + "node_modules", + "**/*.test.ts", + "**/*.test.tsx", + "**/*.spec.ts", + "**/*.spec.tsx", + "**/__tests__/**", + "**/__mocks__/**", + "**/test/**", + "**/tests/**" + ] +} diff --git a/snapi.config.json b/snapi.config.json index 070a39e8d86..cd6455ef9da 100644 --- a/snapi.config.json +++ b/snapi.config.json @@ -1,5 +1,5 @@ { - "packages": ["packages/clerk-js", "packages/react", "packages/shared"], + "packages": ["packages/clerk-js", "packages/react", "packages/shared", "packages/ui"], "snapshotDir": ".api-snapshots", "mainBranch": "main", "checkVersionBump": true,