Skip to content

Latest commit

 

History

History
84 lines (59 loc) · 4.21 KB

RELEASING.md

File metadata and controls

84 lines (59 loc) · 4.21 KB

Releasing

There are two ways to release the SDK: automatic (triggered by a CLI version bump) and manual (triggered via GitHub Actions UI).

Both flows call the same reusable build-and-publish.yml workflow, which builds platform-specific wheels on 5 OS targets, publishes to PyPI, updates version files, generates a changelog entry using Claude, pushes to main, and creates a git tag + GitHub Release.

Wheel targets:

Runner Platform tag
ubuntu-latest manylinux_2_17_x86_64
ubuntu-24.04-arm manylinux_2_17_aarch64
macos-latest macosx_11_0_arm64
macos-15-intel macosx_11_0_x86_64
windows-latest win_amd64

PRs that touch the build scripts, pyproject.toml, or the publish workflow trigger build-wheel-check.yml, which dry-runs the full build matrix and verifies each wheel contains the bundled CLI before merge.

PyPI rejects any file over this project's per-file limit of 250 MiB (raised from the default 100 MiB in pypi/support#12263). A wheel over that limit does not block the release: the publish job leaves it out, shows a warning on the run, and publishes the sdist and the other wheels. pip install on the platform that was left out gets the sdist, which has no bundled CLI, so the SDK there uses a separately installed Claude Code. The wheel stays in the run's build artifacts. The release still fails if the sdist or every wheel is over the limit.

Versioning

The project tracks two separate version numbers:

  • SDK version — in pyproject.toml and src/claude_agent_sdk/_version.py
  • Bundled CLI version — in src/claude_agent_sdk/_cli_version.py

Both follow semver (MAJOR.MINOR.PATCH). Git tags use the format vX.Y.Z.

Automatic Release (CLI Version Bump)

This is the most common release path. Every CLI version bump automatically produces a new SDK patch release.

Flow:

  1. A commit with message chore: bump bundled CLI version to X.Y.Z is pushed to main, updating _cli_version.py.
  2. The Test workflow runs on that push.
  3. On successful completion, auto-release.yml fires via workflow_run.
  4. It verifies the trigger commit message and that _cli_version.py changed.
  5. It reads the current SDK version from _version.py and increments the patch number (e.g., 0.1.24 → 0.1.25).
  6. It calls build-and-publish.yml, which builds, publishes, pushes, tags, and creates a GitHub Release.

Typical commit log after an auto-release:

ccdf20a chore: bump bundled CLI version to 2.1.25
baf9bc3 chore: release v0.1.25

Manual Release

Use this when you need to release with a specific version number (e.g., for minor/major bumps or non-CLI-bump changes).

Flow:

  1. Go to Actions → Publish to PyPI and click Run workflow.
  2. Enter the desired version (e.g., 0.2.0).
  3. The workflow runs the full test suite (Python 3.10–3.13) and lint checks.
  4. On success, it calls build-and-publish.yml, which builds, publishes, pushes, tags, and creates a GitHub Release.

Scripts

All release-related scripts live in scripts/:

Script Purpose
update_version.py Updates SDK version in pyproject.toml and _version.py
update_cli_version.py Updates CLI version in _cli_version.py
build_wheel.py Downloads the CLI binary, builds the wheel, retags with platform-specific tags
download_cli.py Downloads the Claude Code CLI binary for the current platform

Required Secrets

Secret Used For
ANTHROPIC_API_KEY Changelog generation and e2e tests
DEPLOY_KEY SSH key for direct pushes to main

Publishing to PyPI needs no secret: it uses PyPI trusted publishing. The claude-agent-sdk project on PyPI trusts build-and-publish.yml, the reusable workflow whose publish job does the upload, in the production environment. PyPI checks the workflow that runs the upload job, not the one that called it, so publish.yml and auto-release.yml need no entry of their own. Renaming build-and-publish.yml, or moving the upload to another workflow or out of the production environment, needs the matching change on PyPI.