Skip to content

chore(deps): bump @anthropic-ai/sdk from 0.100.1 to 0.115.0 in the production-dependencies group #175

chore(deps): bump @anthropic-ai/sdk from 0.100.1 to 0.115.0 in the production-dependencies group

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

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,
});
}