-
Notifications
You must be signed in to change notification settings - Fork 450
ci(repo): dogfood snapi api checks #8621
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| --- | ||
| --- |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,163 @@ | ||
| 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: | ||
| - main | ||
| - release/v4 | ||
| - release/core-2 | ||
| paths: | ||
| - 'packages/clerk-js/**' | ||
| - 'packages/react/**' | ||
| - 'packages/shared/**' | ||
| - 'packages/ui/**' | ||
| - 'snapi.config.json' | ||
| - '.github/workflows/api-changes.yml' | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} | ||
| 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 }} | ||
| 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 }} | ||
|
|
||
| steps: | ||
| - name: Checkout Repo | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 100 | ||
| fetch-tags: false | ||
| 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: 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- | ||
|
|
||
|
Comment on lines
+112
to
+120
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: For actions/cache/restore@v4, the output variables cache-hit and cache-matched-key function as follows: (1) Exact Key Hit - cache-hit: Set to 'true' [1][2][3]. - cache-matched-key: Set to the exact key that was used [4]. (2) Restore-Keys Partial Hit - cache-hit: Set to 'false' [1][2][3]. - cache-matched-key: Set to the specific key that was found and restored (i.e., the partial match) [4]. (3) Full Miss - cache-hit: Set to an empty string [1][2][3]. - cache-matched-key: Set to an empty string (or not present/undefined, as no cache was found) [5]. Important Semantics - The cache-hit output is a string value, not a boolean, despite its name; it is typically 'true', 'false', or an empty string [1][2][3]. - Relying on cache-hit to determine if any cache was restored can be misleading in scenarios involving partial hits. Because cache-hit is 'false' during a partial hit, developers often use cache-matched-key to verify if any cache was restored [4]. - When checking cache-hit in conditional expressions (if:), ensure you compare against the string value (e.g., if: steps.cache.outputs.cache-hit!= 'true') rather than a boolean [1][4]. Citations:
🏁 Script executed: #!/bin/bash
set -euo pipefail
FILE=".github/workflows/api-changes.yml"
echo "== File: $FILE =="
stat "$FILE" || true
python3 - <<'PY'
import itertools,sys
path=".github/workflows/api-changes.yml"
start=80
end=180
with open(path,'r',encoding='utf-8') as f:
for i,line in enumerate(f,1):
if start<=i<=end:
print(f"{i:4d}: {line.rstrip()}")
PYRepository: clerk/javascript Length of output: 3726 🏁 Script executed: #!/bin/bash
set -euo pipefail
FILE=".github/workflows/api-changes.yml"
echo "== File: $FILE =="
python3 - <<'PY'
path=".github/workflows/api-changes.yml"
ranges=[(1,90),(90,170)]
with open(path,'r',encoding='utf-8') as f:
lines=f.readlines()
for a,b in ranges:
for i in range(a,b+1):
if i<=0 or i>len(lines):
continue
print(f"{i:4d}: {lines[i-1].rstrip()}")
PYRepository: clerk/javascript Length of output: 6252 🏁 Script executed: #!/bin/bash
set -euo pipefail
FILE=".github/workflows/api-changes.yml"
echo "== Grep: persist-credentials =="
rg -n "persist-credentials" "$FILE" || true
echo
echo "== Grep: actions/checkout =="
rg -n "uses:\s*actions/checkout@" "$FILE" || true
echo
echo "== Grep: actions/cache/restore/save =="
rg -n "uses:\s*actions/cache/(restore|save)@" "$FILE" || true
echo
echo "== Show checkout blocks (approx) =="
python3 - <<'PY'
import re
path=".github/workflows/api-changes.yml"
lines=open(path,'r',encoding='utf-8').read().splitlines()
for i,l in enumerate(lines,1):
if "uses: actions/checkout@" in l:
start=max(1,i-3); end=min(len(lines), i+8)
print(f"\n-- lines {start}-{end} around checkout at {i} --")
for j in range(start,end+1):
print(f"{j:4d}: {lines[j-1]}")
PYRepository: clerk/javascript Length of output: 1117 Fix baseline cache gating + ensure rebuild uses the PR base SHA in api-changes workflow
Proposed fix - name: Fetch base branch
- if: steps.baseline-cache.outputs.cache-matched-key == ''
+ if: steps.baseline-cache.outputs.cache-hit != 'true'
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 == ''
+ if: steps.baseline-cache.outputs.cache-hit != 'true'
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 == ''
+ if: steps.baseline-cache.outputs.cache-hit != 'true'
run: pnpm --dir .worktrees/snapi-baseline install --frozen-lockfile
- name: Build baseline declarations
- if: steps.baseline-cache.outputs.cache-matched-key == ''
+ if: steps.baseline-cache.outputs.cache-hit != 'true'
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 == ''
+ if: steps.baseline-cache.outputs.cache-hit != 'true'
run: |
+ rm -rf "$GITHUB_WORKSPACE/.api-snapshots-baseline"
pnpm --dir .worktrees/snapi-baseline dlx --package "$SNAPI_PACKAGE" snapi snapshot \
--output "$GITHUB_WORKSPACE/.api-snapshots-baseline"🧰 Tools🪛 zizmor (1.25.2)[error] 114-114: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy) (unpinned-uses) 🤖 Prompt for AI Agents |
||
| - 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 | ||
|
|
||
|
Comment on lines
+124
to
+127
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Build fallback baseline from immutable PR base SHA. Line 126 and Line 132 use Proposed fix - name: Fetch base branch
if: steps.baseline-cache.outputs.cache-hit != 'true'
- run: git fetch origin "${GITHUB_BASE_REF}:refs/remotes/origin/${GITHUB_BASE_REF}" --depth=100
+ run: git fetch origin "${{ github.event.pull_request.base.sha }}" --depth=1
- name: Create baseline worktree
if: steps.baseline-cache.outputs.cache-hit != 'true'
run: |
mkdir -p .worktrees
- git worktree add .worktrees/snapi-baseline "origin/${GITHUB_BASE_REF}"
+ git worktree add --detach .worktrees/snapi-baseline "${{ github.event.pull_request.base.sha }}"
cp snapi.config.json .worktrees/snapi-baseline/snapi.config.jsonAlso applies to: 132-133 🤖 Prompt for AI Agents |
||
| - 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" | ||
|
|
||
| - 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 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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/**" | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| { | ||
| "packages": ["packages/clerk-js", "packages/react", "packages/shared", "packages/ui"], | ||
| "snapshotDir": ".api-snapshots", | ||
| "mainBranch": "main", | ||
| "checkVersionBump": true, | ||
| "outputFormat": "markdown" | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: clerk/javascript
Length of output: 1112
🏁 Script executed:
Repository: clerk/javascript
Length of output: 4977
🏁 Script executed:
Repository: clerk/javascript
Length of output: 117
🏁 Script executed:
Repository: clerk/javascript
Length of output: 475
🏁 Script executed:
Repository: clerk/javascript
Length of output: 168
🏁 Script executed:
Repository: clerk/javascript
Length of output: 3054
🏁 Script executed:
Repository: clerk/javascript
Length of output: 8024
🏁 Script executed:
Repository: clerk/javascript
Length of output: 821
🏁 Script executed:
Repository: clerk/javascript
Length of output: 42
Pin checkout/cache actions to commit SHAs and disable persisted credentials in
api-changes.yml.actions/checkout@v4in.github/workflows/api-changes.ymlis unpinned and lackspersist-credentials: false(also present on the second checkout step in the same workflow).actions/cache/save@v4(line 80) andactions/cache/restore@v4(line 114) are also unpinned; pin them to commit SHAs.🧰 Tools
🪛 zizmor (1.25.2)
[warning] 57-61: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
[error] 58-58: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)
(unpinned-uses)
🤖 Prompt for AI Agents