chore(deps): bump @anthropic-ai/sdk from 0.100.1 to 0.115.0 in the production-dependencies group #175
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: API Check | |
| on: | |
| pull_request: | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| concurrency: | |
| group: api-check-${{ github.event.pull_request.number }} | |
| cancel-in-progress: true | |
| jobs: | |
| api-check: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| persist-credentials: false | |
| fetch-depth: 0 | |
| - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version: "24" | |
| cache: "pnpm" | |
| - name: Try fetching baseline artifact | |
| id: fetch-baseline | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| ARTIFACT_NAME: break-check-baseline-main | |
| REPO: ${{ github.repository }} | |
| BASELINE_DIR: ${{ github.workspace }}/.api-baseline-main | |
| run: | | |
| set -euo pipefail | |
| fallback() { | |
| echo "::notice::$1 Falling back to base-ref rebuild." | |
| echo "fetched=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| } | |
| # Bind the baseline to the PR's exact base commit: match the producing | |
| # run's head_sha (the main commit the baseline workflow ran on) against | |
| # github.event.pull_request.base.sha. Selecting by branch alone would | |
| # grab the newest main snapshot, which can be ahead of the PR base, so | |
| # the diff would compare against a tree the PR was never based on. | |
| ARTIFACT=$(gh api \ | |
| "repos/$REPO/actions/artifacts?name=$ARTIFACT_NAME&per_page=100" \ | |
| --jq "[.artifacts[] | select(.workflow_run.head_sha == \"$BASE_SHA\" and .expired == false)] | .[0]") \ | |
| || fallback "Artifact lookup failed." | |
| if [ -z "$ARTIFACT" ] || [ "$ARTIFACT" = "null" ]; then | |
| fallback "No baseline artifact '$ARTIFACT_NAME' for base $BASE_SHA." | |
| fi | |
| ARTIFACT_ID=$(echo "$ARTIFACT" | jq -r '.id') | |
| RUN_ID=$(echo "$ARTIFACT" | jq -r '.workflow_run.id') | |
| rm -rf "$BASELINE_DIR" | |
| mkdir -p "$BASELINE_DIR" | |
| ZIP_PATH="$RUNNER_TEMP/break-check-baseline.zip" | |
| gh api "repos/$REPO/actions/artifacts/$ARTIFACT_ID/zip" > "$ZIP_PATH" \ | |
| || fallback "Artifact download failed." | |
| unzip -q "$ZIP_PATH" -d "$BASELINE_DIR" \ | |
| || fallback "Artifact unzip failed." | |
| rm -f "$ZIP_PATH" | |
| echo "fetched=true" >> "$GITHUB_OUTPUT" | |
| echo "::notice::Using baseline artifact '$ARTIFACT_NAME' from run $RUN_ID." | |
| - name: Snapshot baseline from base branch | |
| if: steps.fetch-baseline.outputs.fetched != 'true' | |
| env: | |
| BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| run: | | |
| # Use the PR's base SHA so we diff against the exact commit the PR | |
| # was opened against, not the moving tip of the base branch. The | |
| # checkout above uses fetch-depth: 0 + persist-credentials: false, | |
| # so the SHA is already in local history and a fresh fetch would | |
| # fail without auth; check out directly. | |
| git worktree add --detach /tmp/base-checkout "$BASE_SHA" | |
| # Bring the PR's break-check.config.json over so first-run PRs (where the | |
| # base branch doesn't yet have one) can still produce a baseline. | |
| # If the base already has a config, cp -n leaves it untouched. | |
| cp -n break-check.config.json /tmp/base-checkout/break-check.config.json || true | |
| cd /tmp/base-checkout | |
| pnpm install --frozen-lockfile | |
| pnpm build | |
| node dist/cli.js snapshot --output "$GITHUB_WORKSPACE/.api-baseline-main" | |
| - name: Build current checkout from PR head | |
| env: | |
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} | |
| run: | | |
| # Pin the "current" side to the PR head commit, not the | |
| # refs/pull/N/merge ref actions/checkout resolves by default. The | |
| # merge ref is the PR head merged into the moving tip of the base | |
| # branch, so once main advances the merged tree absorbs unrelated | |
| # changes and break-check reports them as the PR's (issue #32). | |
| # fetch-depth: 0 + persist-credentials: false means the SHA is already | |
| # in local history, so check it out directly (a fresh fetch would fail | |
| # without auth). Symmetric with the baseline worktree above. | |
| git worktree add --detach /tmp/head-checkout "$HEAD_SHA" | |
| cd /tmp/head-checkout | |
| pnpm install --frozen-lockfile | |
| pnpm build | |
| - name: Detect API changes | |
| id: detect | |
| # Deliberately no BREAK_CHECK_ANTHROPIC_API_KEY here. This step runs the | |
| # dist/cli.js built from the PR head, which is untrusted on same-repo | |
| # branch PRs (forks never receive secrets). Putting the Anthropic key in | |
| # this env would let a malicious PR's build exfiltrate it. The structural | |
| # diff is all this self-dogfood check needs; the AI reviewer is exercised | |
| # separately in ai-smoke.yml, which only runs in trusted contexts | |
| # (workflow_dispatch + nightly schedule on main). | |
| continue-on-error: true | |
| env: | |
| BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| run: | | |
| set -uo pipefail | |
| # Diff from the PR head worktree. The baseline dir and report path live | |
| # in the workspace, so pass them as absolute paths since cwd is now the | |
| # worktree, not the workspace. | |
| cd /tmp/head-checkout | |
| run_detect() { | |
| node dist/cli.js detect \ | |
| --baseline "$GITHUB_WORKSPACE/.api-baseline-main" \ | |
| --output "$GITHUB_WORKSPACE/api-report.md" | |
| } | |
| # The baseline above is produced by the BASE ref's break-check, while this | |
| # step runs the PR's break-check. When the PR changes producer semantics | |
| # (API Extractor major, discovery version), detect refuses the | |
| # baseline with exit code 3. That's expected here; rebuild the | |
| # baseline with the current build (against the base checkout) so both | |
| # sides match, then retry once. | |
| status=0 | |
| run_detect || status=$? | |
| if [ "$status" = "3" ]; then | |
| echo "::notice::Baseline was produced by a different break-check (producer/discovery mismatch); rebuilding it with the current build and retrying." | |
| # The base worktree only exists when the baseline was rebuilt | |
| # locally; the artifact fast path above never creates it. Create | |
| # and build it on demand so the retry works on both paths | |
| # (previously this dereferenced a missing /tmp/base-checkout and | |
| # failed with a confusing snapshot error). | |
| if [ ! -d /tmp/base-checkout ]; then | |
| git -C "$GITHUB_WORKSPACE" worktree add --detach /tmp/base-checkout "$BASE_SHA" | |
| cp -n "$GITHUB_WORKSPACE/break-check.config.json" /tmp/base-checkout/break-check.config.json || true | |
| (cd /tmp/base-checkout && pnpm install --frozen-lockfile && pnpm build) | |
| fi | |
| # --output is resolved relative to the --config dir, so it must be | |
| # absolute to land back in the workspace where detect reads it. | |
| rm -rf "$GITHUB_WORKSPACE/.api-baseline-main" | |
| node dist/cli.js snapshot \ | |
| --config /tmp/base-checkout/break-check.config.json \ | |
| --output "$GITHUB_WORKSPACE/.api-baseline-main" | |
| status=0 | |
| run_detect || status=$? | |
| fi | |
| exit "$status" | |
| - name: Comment on PR | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const marker = '<!-- break-check-self-dogfood -->'; | |
| if (!fs.existsSync('api-report.md')) { | |
| core.warning('break-check report not found (detect failed); skipping comment.'); | |
| return; | |
| } | |
| const report = fs.readFileSync('api-report.md', 'utf-8'); | |
| const body = `${marker}\n${report}`; | |
| // Paginate and null-guard, mirroring the composite Action's comment | |
| // step: the bot comment can be past the first page, c.user is null | |
| // for deleted authors, and c.body can be undefined. | |
| const comments = await github.paginate(github.rest.issues.listComments, { | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| per_page: 100, | |
| }); | |
| const existing = comments.find( | |
| (c) => c.user?.type === 'Bot' && c.body && c.body.includes(marker), | |
| ); | |
| if (existing) { | |
| await github.rest.issues.updateComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| comment_id: existing.id, | |
| body, | |
| }); | |
| } else { | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body, | |
| }); | |
| } |