From da7c0cf00ecbdc9bd490518be986bceff2d48476 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 20 Feb 2026 06:55:09 +0000 Subject: [PATCH 1/5] feat(ci): add daily GitHub Action to update claude-agent-sdk Adds a scheduled workflow that runs daily at 8 AM UTC to check PyPI for the latest claude-agent-sdk version and opens a PR if a newer version is available. https://claude.ai/code/session_01AF1ro2VAMS7WSb7QayTetZ --- .github/workflows/daily-sdk-update.yml | 183 +++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 .github/workflows/daily-sdk-update.yml diff --git a/.github/workflows/daily-sdk-update.yml b/.github/workflows/daily-sdk-update.yml new file mode 100644 index 000000000..8c6f0e83b --- /dev/null +++ b/.github/workflows/daily-sdk-update.yml @@ -0,0 +1,183 @@ +name: Daily Claude Agent SDK Update + +on: + schedule: + # Run daily at 8 AM UTC + - cron: '0 8 * * *' + + workflow_dispatch: # Allow manual triggering + +permissions: + contents: write + pull-requests: write + +jobs: + update-sdk: + name: Update claude-agent-sdk to latest + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + ref: main + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup Python + uses: actions/setup-python@v6 + with: + python-version: '3.11' + + - name: Get latest SDK version from PyPI + id: pypi + run: | + LATEST=$(pip index versions claude-agent-sdk 2>/dev/null \ + | head -1 \ + | sed 's/claude-agent-sdk (\(.*\))/\1/' \ + | awk '{print $1}') + + if [ -z "$LATEST" ]; then + echo "Failed to fetch latest version from PyPI" + exit 1 + fi + + echo "latest=$LATEST" >> "$GITHUB_OUTPUT" + echo "Latest claude-agent-sdk on PyPI: $LATEST" + + - name: Get current minimum version + id: current + run: | + CURRENT=$(grep 'claude-agent-sdk>=' \ + components/runners/claude-code-runner/pyproject.toml \ + | sed 's/.*>=\([0-9][0-9.]*\).*/\1/') + + if [ -z "$CURRENT" ]; then + echo "Failed to parse current version from pyproject.toml" + exit 1 + fi + + echo "current=$CURRENT" >> "$GITHUB_OUTPUT" + echo "Current minimum version: $CURRENT" + + - name: Check if update is needed + id: check + run: | + LATEST="${{ steps.pypi.outputs.latest }}" + CURRENT="${{ steps.current.outputs.current }}" + + if [ "$LATEST" = "$CURRENT" ]; then + echo "Already up to date ($CURRENT)" + echo "needs_update=false" >> "$GITHUB_OUTPUT" + else + echo "Update available: $CURRENT -> $LATEST" + echo "needs_update=true" >> "$GITHUB_OUTPUT" + fi + + - name: Check for existing PR + if: steps.check.outputs.needs_update == 'true' + id: existing_pr + run: | + EXISTING=$(gh pr list \ + --head "auto/update-claude-agent-sdk" \ + --state open \ + --json number \ + --jq 'length') + + if [ "$EXISTING" -gt 0 ]; then + echo "Open PR already exists for SDK update branch" + echo "pr_exists=true" >> "$GITHUB_OUTPUT" + else + echo "pr_exists=false" >> "$GITHUB_OUTPUT" + fi + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Update pyproject.toml + if: steps.check.outputs.needs_update == 'true' && steps.existing_pr.outputs.pr_exists == 'false' + run: | + LATEST="${{ steps.pypi.outputs.latest }}" + CURRENT="${{ steps.current.outputs.current }}" + + sed -i "s/\"claude-agent-sdk>=${CURRENT}\"/\"claude-agent-sdk>=${LATEST}\"/" \ + components/runners/claude-code-runner/pyproject.toml + + echo "Updated pyproject.toml:" + grep claude-agent-sdk components/runners/claude-code-runner/pyproject.toml + + - name: Validate update + if: steps.check.outputs.needs_update == 'true' && steps.existing_pr.outputs.pr_exists == 'false' + run: | + LATEST="${{ steps.pypi.outputs.latest }}" + + # Verify the file was updated correctly + if ! grep -q "claude-agent-sdk>=${LATEST}" components/runners/claude-code-runner/pyproject.toml; then + echo "Validation failed: pyproject.toml does not contain expected version" + exit 1 + fi + + echo "Validation passed" + + - name: Create branch, commit, and open PR + if: steps.check.outputs.needs_update == 'true' && steps.existing_pr.outputs.pr_exists == 'false' + run: | + LATEST="${{ steps.pypi.outputs.latest }}" + CURRENT="${{ steps.current.outputs.current }}" + BRANCH="auto/update-claude-agent-sdk" + + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + # Delete remote branch if it exists (leftover from a merged/closed PR) + git push origin --delete "$BRANCH" 2>/dev/null || true + + git checkout -b "$BRANCH" + git add components/runners/claude-code-runner/pyproject.toml + git commit -m "chore(runner): update claude-agent-sdk >=${CURRENT} to >=${LATEST} + + Automated daily update of the Claude Agent SDK minimum version. + + Release notes: https://pypi.org/project/claude-agent-sdk/${LATEST}/" + + git push -u origin "$BRANCH" + + gh pr create \ + --title "chore(runner): update claude-agent-sdk to >=${LATEST}" \ + --body "$(cat <=${CURRENT}\` to \`>=${LATEST}\` + - File changed: \`components/runners/claude-code-runner/pyproject.toml\` + + ## Release Info + + PyPI: https://pypi.org/project/claude-agent-sdk/${LATEST}/ + + ## Test Plan + + - [ ] Runner tests pass (\`runner-tests\` workflow) + - [ ] Container image builds successfully (\`components-build-deploy\` workflow) + + --- + *Auto-generated by daily-sdk-update workflow* + EOF + )" \ + --base main \ + --head "$BRANCH" \ + --label "dependencies" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Summary + if: always() + run: | + LATEST="${{ steps.pypi.outputs.latest }}" + CURRENT="${{ steps.current.outputs.current }}" + + if [ "${{ steps.check.outputs.needs_update }}" == "false" ]; then + echo "## ✓ claude-agent-sdk is up to date ($CURRENT)" >> "$GITHUB_STEP_SUMMARY" + elif [ "${{ steps.existing_pr.outputs.pr_exists }}" == "true" ]; then + echo "## ⏭ Update PR already exists" >> "$GITHUB_STEP_SUMMARY" + echo "An open PR for \`auto/update-claude-agent-sdk\` already exists." >> "$GITHUB_STEP_SUMMARY" + else + echo "## ✅ PR created: claude-agent-sdk ${CURRENT} → ${LATEST}" >> "$GITHUB_STEP_SUMMARY" + fi From 9bc72abf9492f60f0a32648b9ad39191cb03d037 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 20 Feb 2026 07:00:10 +0000 Subject: [PATCH 2/5] refactor(ci): harden daily SDK update workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace pip index with PyPI JSON API (curl+jq) — removes setup-python step - Add version format validation to reject unexpected PyPI responses - Use sort -V for proper semver comparison — prevents downgrade PRs - Escape dots in sed regex to avoid wildcard matches - Merge update and validate steps into one - Build PR body in a variable instead of inline heredoc - Add failure case to step summary - Use POSIX = instead of bash == in test expressions https://claude.ai/code/session_01AF1ro2VAMS7WSb7QayTetZ --- .github/workflows/daily-sdk-update.yml | 77 +++++++++++++------------- 1 file changed, 37 insertions(+), 40 deletions(-) diff --git a/.github/workflows/daily-sdk-update.yml b/.github/workflows/daily-sdk-update.yml index 8c6f0e83b..ef7bbba04 100644 --- a/.github/workflows/daily-sdk-update.yml +++ b/.github/workflows/daily-sdk-update.yml @@ -23,24 +23,21 @@ jobs: ref: main token: ${{ secrets.GITHUB_TOKEN }} - - name: Setup Python - uses: actions/setup-python@v6 - with: - python-version: '3.11' - - name: Get latest SDK version from PyPI id: pypi run: | - LATEST=$(pip index versions claude-agent-sdk 2>/dev/null \ - | head -1 \ - | sed 's/claude-agent-sdk (\(.*\))/\1/' \ - | awk '{print $1}') + LATEST=$(curl -sf https://pypi.org/pypi/claude-agent-sdk/json | jq -r '.info.version') - if [ -z "$LATEST" ]; then + if [ -z "$LATEST" ] || [ "$LATEST" = "null" ]; then echo "Failed to fetch latest version from PyPI" exit 1 fi + if ! echo "$LATEST" | grep -qE '^[0-9]+(\.[0-9]+)+$'; then + echo "Unexpected version format: $LATEST" + exit 1 + fi + echo "latest=$LATEST" >> "$GITHUB_OUTPUT" echo "Latest claude-agent-sdk on PyPI: $LATEST" @@ -65,8 +62,11 @@ jobs: LATEST="${{ steps.pypi.outputs.latest }}" CURRENT="${{ steps.current.outputs.current }}" - if [ "$LATEST" = "$CURRENT" ]; then - echo "Already up to date ($CURRENT)" + # Use version sort — if current sorts last, we are already up to date + NEWEST=$(printf '%s\n%s' "$CURRENT" "$LATEST" | sort -V | tail -1) + + if [ "$NEWEST" = "$CURRENT" ]; then + echo "Already up to date ($CURRENT >= $LATEST)" echo "needs_update=false" >> "$GITHUB_OUTPUT" else echo "Update available: $CURRENT -> $LATEST" @@ -98,24 +98,20 @@ jobs: LATEST="${{ steps.pypi.outputs.latest }}" CURRENT="${{ steps.current.outputs.current }}" - sed -i "s/\"claude-agent-sdk>=${CURRENT}\"/\"claude-agent-sdk>=${LATEST}\"/" \ - components/runners/claude-code-runner/pyproject.toml - - echo "Updated pyproject.toml:" - grep claude-agent-sdk components/runners/claude-code-runner/pyproject.toml + # Escape dots for sed regex + CURRENT_ESC=$(echo "$CURRENT" | sed 's/\./\\./g') - - name: Validate update - if: steps.check.outputs.needs_update == 'true' && steps.existing_pr.outputs.pr_exists == 'false' - run: | - LATEST="${{ steps.pypi.outputs.latest }}" + sed -i "s/\"claude-agent-sdk>=${CURRENT_ESC}\"/\"claude-agent-sdk>=${LATEST}\"/" \ + components/runners/claude-code-runner/pyproject.toml - # Verify the file was updated correctly + # Verify the update landed if ! grep -q "claude-agent-sdk>=${LATEST}" components/runners/claude-code-runner/pyproject.toml; then - echo "Validation failed: pyproject.toml does not contain expected version" + echo "pyproject.toml was not updated correctly" exit 1 fi - echo "Validation passed" + echo "Updated pyproject.toml:" + grep claude-agent-sdk components/runners/claude-code-runner/pyproject.toml - name: Create branch, commit, and open PR if: steps.check.outputs.needs_update == 'true' && steps.existing_pr.outputs.pr_exists == 'false' @@ -140,10 +136,7 @@ jobs: git push -u origin "$BRANCH" - gh pr create \ - --title "chore(runner): update claude-agent-sdk to >=${LATEST}" \ - --body "$(cat <=${LATEST}" \ + --body "$PR_BODY" \ --base main \ --head "$BRANCH" \ --label "dependencies" @@ -170,14 +165,16 @@ jobs: - name: Summary if: always() run: | - LATEST="${{ steps.pypi.outputs.latest }}" - CURRENT="${{ steps.current.outputs.current }}" - - if [ "${{ steps.check.outputs.needs_update }}" == "false" ]; then - echo "## ✓ claude-agent-sdk is up to date ($CURRENT)" >> "$GITHUB_STEP_SUMMARY" - elif [ "${{ steps.existing_pr.outputs.pr_exists }}" == "true" ]; then - echo "## ⏭ Update PR already exists" >> "$GITHUB_STEP_SUMMARY" - echo "An open PR for \`auto/update-claude-agent-sdk\` already exists." >> "$GITHUB_STEP_SUMMARY" + if [ "${{ steps.check.outputs.needs_update }}" = "false" ]; then + echo "## No update needed" >> "$GITHUB_STEP_SUMMARY" + echo "claude-agent-sdk \`${{ steps.current.outputs.current }}\` is already the latest." >> "$GITHUB_STEP_SUMMARY" + elif [ "${{ steps.existing_pr.outputs.pr_exists }}" = "true" ]; then + echo "## Update PR already exists" >> "$GITHUB_STEP_SUMMARY" + echo "An open PR for branch \`auto/update-claude-agent-sdk\` already exists." >> "$GITHUB_STEP_SUMMARY" + elif [ "${{ job.status }}" = "failure" ]; then + echo "## Update failed" >> "$GITHUB_STEP_SUMMARY" + echo "Check the logs above for details." >> "$GITHUB_STEP_SUMMARY" else - echo "## ✅ PR created: claude-agent-sdk ${CURRENT} → ${LATEST}" >> "$GITHUB_STEP_SUMMARY" + echo "## PR created" >> "$GITHUB_STEP_SUMMARY" + echo "claude-agent-sdk \`${{ steps.current.outputs.current }}\` -> \`${{ steps.pypi.outputs.latest }}\`" >> "$GITHUB_STEP_SUMMARY" fi From f526522334b8bbbe213889de3aa7fb11c51212b4 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 20 Feb 2026 07:24:01 +0000 Subject: [PATCH 3/5] fix(ci): address code review feedback on daily SDK update workflow - Pin actions/checkout to commit SHA (de0fac2e, v6.0.2) for supply chain security - Move all ${{ steps.*.outputs.* }} into env: blocks to prevent expression injection - Add concurrency group to prevent parallel workflow races - Add timeout-minutes: 15 to the job - Add --max-time 30 to curl for PyPI requests - Replace silent 2>/dev/null || true with diagnostic echo on branch delete - Remove --label "dependencies" flag (label may not exist in repo) https://claude.ai/code/session_01AF1ro2VAMS7WSb7QayTetZ --- .github/workflows/daily-sdk-update.yml | 50 +++++++++++++++----------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/.github/workflows/daily-sdk-update.yml b/.github/workflows/daily-sdk-update.yml index ef7bbba04..55f7ba9ac 100644 --- a/.github/workflows/daily-sdk-update.yml +++ b/.github/workflows/daily-sdk-update.yml @@ -11,14 +11,19 @@ permissions: contents: write pull-requests: write +concurrency: + group: daily-sdk-update + cancel-in-progress: false + jobs: update-sdk: name: Update claude-agent-sdk to latest runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout repository - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: ref: main token: ${{ secrets.GITHUB_TOKEN }} @@ -26,7 +31,7 @@ jobs: - name: Get latest SDK version from PyPI id: pypi run: | - LATEST=$(curl -sf https://pypi.org/pypi/claude-agent-sdk/json | jq -r '.info.version') + LATEST=$(curl -sf --max-time 30 https://pypi.org/pypi/claude-agent-sdk/json | jq -r '.info.version') if [ -z "$LATEST" ] || [ "$LATEST" = "null" ]; then echo "Failed to fetch latest version from PyPI" @@ -58,10 +63,10 @@ jobs: - name: Check if update is needed id: check + env: + LATEST: ${{ steps.pypi.outputs.latest }} + CURRENT: ${{ steps.current.outputs.current }} run: | - LATEST="${{ steps.pypi.outputs.latest }}" - CURRENT="${{ steps.current.outputs.current }}" - # Use version sort — if current sorts last, we are already up to date NEWEST=$(printf '%s\n%s' "$CURRENT" "$LATEST" | sort -V | tail -1) @@ -94,10 +99,10 @@ jobs: - name: Update pyproject.toml if: steps.check.outputs.needs_update == 'true' && steps.existing_pr.outputs.pr_exists == 'false' + env: + LATEST: ${{ steps.pypi.outputs.latest }} + CURRENT: ${{ steps.current.outputs.current }} run: | - LATEST="${{ steps.pypi.outputs.latest }}" - CURRENT="${{ steps.current.outputs.current }}" - # Escape dots for sed regex CURRENT_ESC=$(echo "$CURRENT" | sed 's/\./\\./g') @@ -115,16 +120,18 @@ jobs: - name: Create branch, commit, and open PR if: steps.check.outputs.needs_update == 'true' && steps.existing_pr.outputs.pr_exists == 'false' + env: + LATEST: ${{ steps.pypi.outputs.latest }} + CURRENT: ${{ steps.current.outputs.current }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - LATEST="${{ steps.pypi.outputs.latest }}" - CURRENT="${{ steps.current.outputs.current }}" BRANCH="auto/update-claude-agent-sdk" git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" # Delete remote branch if it exists (leftover from a merged/closed PR) - git push origin --delete "$BRANCH" 2>/dev/null || true + git push origin --delete "$BRANCH" 2>&1 || echo "Branch $BRANCH did not exist or could not be deleted" git checkout -b "$BRANCH" git add components/runners/claude-code-runner/pyproject.toml @@ -157,24 +164,27 @@ jobs: --title "chore(runner): update claude-agent-sdk to >=${LATEST}" \ --body "$PR_BODY" \ --base main \ - --head "$BRANCH" \ - --label "dependencies" - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + --head "$BRANCH" - name: Summary if: always() + env: + NEEDS_UPDATE: ${{ steps.check.outputs.needs_update }} + PR_EXISTS: ${{ steps.existing_pr.outputs.pr_exists }} + CURRENT: ${{ steps.current.outputs.current }} + LATEST: ${{ steps.pypi.outputs.latest }} + JOB_STATUS: ${{ job.status }} run: | - if [ "${{ steps.check.outputs.needs_update }}" = "false" ]; then + if [ "$NEEDS_UPDATE" = "false" ]; then echo "## No update needed" >> "$GITHUB_STEP_SUMMARY" - echo "claude-agent-sdk \`${{ steps.current.outputs.current }}\` is already the latest." >> "$GITHUB_STEP_SUMMARY" - elif [ "${{ steps.existing_pr.outputs.pr_exists }}" = "true" ]; then + echo "claude-agent-sdk \`${CURRENT}\` is already the latest." >> "$GITHUB_STEP_SUMMARY" + elif [ "$PR_EXISTS" = "true" ]; then echo "## Update PR already exists" >> "$GITHUB_STEP_SUMMARY" echo "An open PR for branch \`auto/update-claude-agent-sdk\` already exists." >> "$GITHUB_STEP_SUMMARY" - elif [ "${{ job.status }}" = "failure" ]; then + elif [ "$JOB_STATUS" = "failure" ]; then echo "## Update failed" >> "$GITHUB_STEP_SUMMARY" echo "Check the logs above for details." >> "$GITHUB_STEP_SUMMARY" else echo "## PR created" >> "$GITHUB_STEP_SUMMARY" - echo "claude-agent-sdk \`${{ steps.current.outputs.current }}\` -> \`${{ steps.pypi.outputs.latest }}\`" >> "$GITHUB_STEP_SUMMARY" + echo "claude-agent-sdk \`${CURRENT}\` -> \`${LATEST}\`" >> "$GITHUB_STEP_SUMMARY" fi From 319c62d64d234329504c8cd5c055b5814b3c8822 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 21 Feb 2026 02:49:47 +0000 Subject: [PATCH 4/5] fix(ci): address round-2 review feedback on daily SDK update workflow - Add uv lock regeneration step after pyproject.toml update to keep uv.lock in sync and prevent broken local dev environments - Include uv.lock in the auto-generated commit - Document GITHUB_TOKEN CI triggering limitation in auto-generated PR body (PRs created by GITHUB_TOKEN don't trigger pull_request workflows) - Add defensive default (|| 'false') for PR_EXISTS env in Summary step when existing_pr step is skipped - Fix PR body formatting via heredoc to avoid indentation artifacts https://claude.ai/code/session_01AF1ro2VAMS7WSb7QayTetZ --- .github/workflows/daily-sdk-update.yml | 40 ++++++++++++++++++-------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/.github/workflows/daily-sdk-update.yml b/.github/workflows/daily-sdk-update.yml index 55f7ba9ac..1f1d2f228 100644 --- a/.github/workflows/daily-sdk-update.yml +++ b/.github/workflows/daily-sdk-update.yml @@ -118,6 +118,14 @@ jobs: echo "Updated pyproject.toml:" grep claude-agent-sdk components/runners/claude-code-runner/pyproject.toml + - name: Regenerate uv.lock + if: steps.check.outputs.needs_update == 'true' && steps.existing_pr.outputs.pr_exists == 'false' + run: | + pip install uv + cd components/runners/claude-code-runner + uv lock + echo "uv.lock regenerated" + - name: Create branch, commit, and open PR if: steps.check.outputs.needs_update == 'true' && steps.existing_pr.outputs.pr_exists == 'false' env: @@ -134,7 +142,8 @@ jobs: git push origin --delete "$BRANCH" 2>&1 || echo "Branch $BRANCH did not exist or could not be deleted" git checkout -b "$BRANCH" - git add components/runners/claude-code-runner/pyproject.toml + git add components/runners/claude-code-runner/pyproject.toml \ + components/runners/claude-code-runner/uv.lock git commit -m "chore(runner): update claude-agent-sdk >=${CURRENT} to >=${LATEST} Automated daily update of the Claude Agent SDK minimum version. @@ -143,22 +152,29 @@ jobs: git push -u origin "$BRANCH" - PR_BODY="## Summary + PR_BODY=$(cat <=${CURRENT}\` to \`>=${LATEST}\` +- Files changed: \`pyproject.toml\` and \`uv.lock\` - - Updates \`claude-agent-sdk\` minimum version from \`>=${CURRENT}\` to \`>=${LATEST}\` - - File changed: \`components/runners/claude-code-runner/pyproject.toml\` +## Release Info - ## Release Info +PyPI: https://pypi.org/project/claude-agent-sdk/${LATEST}/ - PyPI: https://pypi.org/project/claude-agent-sdk/${LATEST}/ +## Test Plan - ## Test Plan +- [ ] Runner tests pass (\`runner-tests\` workflow) +- [ ] Container image builds successfully (\`components-build-deploy\` workflow) - - [ ] Runner tests pass (\`runner-tests\` workflow) - - [ ] Container image builds successfully (\`components-build-deploy\` workflow) +> **Note:** PRs created by \`GITHUB_TOKEN\` do not automatically trigger \`pull_request\` workflows. +> CI must be triggered manually (push an empty commit or re-run workflows) or the repo can be +> configured with a PAT via \`secrets.BOT_TOKEN\` to enable automatic CI triggering. - --- - *Auto-generated by daily-sdk-update workflow*" +--- +*Auto-generated by daily-sdk-update workflow* +PREOF + ) gh pr create \ --title "chore(runner): update claude-agent-sdk to >=${LATEST}" \ @@ -170,7 +186,7 @@ jobs: if: always() env: NEEDS_UPDATE: ${{ steps.check.outputs.needs_update }} - PR_EXISTS: ${{ steps.existing_pr.outputs.pr_exists }} + PR_EXISTS: ${{ steps.existing_pr.outputs.pr_exists || 'false' }} CURRENT: ${{ steps.current.outputs.current }} LATEST: ${{ steps.pypi.outputs.latest }} JOB_STATUS: ${{ job.status }} From 2dfe19eb692b0db69507c75ecdde3bf757879014 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 21 Feb 2026 03:40:48 +0000 Subject: [PATCH 5/5] perf(ci): cache uv in daily SDK update workflow Replace `pip install uv` with `astral-sh/setup-uv` (SHA-pinned v7.3.0) which provides built-in caching keyed on uv.lock. This avoids re-downloading uv and re-resolving the dependency graph on each run. https://claude.ai/code/session_01AF1ro2VAMS7WSb7QayTetZ --- .github/workflows/daily-sdk-update.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/daily-sdk-update.yml b/.github/workflows/daily-sdk-update.yml index 1f1d2f228..7d1e6d293 100644 --- a/.github/workflows/daily-sdk-update.yml +++ b/.github/workflows/daily-sdk-update.yml @@ -118,10 +118,16 @@ jobs: echo "Updated pyproject.toml:" grep claude-agent-sdk components/runners/claude-code-runner/pyproject.toml + - name: Install uv + if: steps.check.outputs.needs_update == 'true' && steps.existing_pr.outputs.pr_exists == 'false' + uses: astral-sh/setup-uv@eac588ad8def6316056a12d4907a9d4d84ff7a3b # v7.3.0 + with: + enable-cache: true + cache-dependency-glob: components/runners/claude-code-runner/uv.lock + - name: Regenerate uv.lock if: steps.check.outputs.needs_update == 'true' && steps.existing_pr.outputs.pr_exists == 'false' run: | - pip install uv cd components/runners/claude-code-runner uv lock echo "uv.lock regenerated"