See docs/releasing.md for the Release Please PR, GitHub
environment approval, and PyPI verification steps on main.
Each branch carries one spec line. Draft-spec work stays out of stable releases (#1525).
| Branch | Carries | Releases |
|---|---|---|
main |
Work against the latest ratified AdCP version (3.2.x today) | The current major (9.x), through release-please |
release/N.x (release/8.x, release/7.x) |
Fixes for an older major | Patch releases of that major, from the branch's own release workflow |
next |
Work against draft specs, such as AdCP 3.3 agent identity and Web Bot Auth | Pre-releases only (10.0.0-alpha.N), from its own release-please configuration |
Open a PR against the branch that carries the spec it implements. Code written
to an unratified spec (an open adcontextprotocol/adcp PR or a draft) targets
next, never main.
- Fixes land on
mainfirst. A maintainer then backports the fix to eachrelease/N.xthat needs it, as a cherry-pick PR (git cherry-pick -x <sha>) into that branch. nexttakesmainregularly, so it doesn't drift. Mergeorigin/mainintonextwith a true merge: push the merge tonextdirectly, or merge the sync PR with Create a merge commit. Never squash or rebase a sync, or every later sync repeats the same conflicts. A forward-port PR (a cherry-pick ontonext) also works for a single urgent fix.- Draft-only changes stay on
next. If a change is needed only by draft-spec code, it never goes tomain. - At ratification,
nextmerges intomain, and the next major releases frommain(see Ratification). - Labels mark PRs that need a port:
backport release/8.x(and so on, one per maintained line) andforward-port next. Add the label to the merged PR; whoever opens the port PR links it back and removes the label. A backport action can open the port PRs later; until then this is manual.
next uses separate release files, so release automation conflicts are
limited:
CHANGELOG.md,release-please-config.json, and.release-please-manifest.jsonbelong tomain. Takemain's version; onnextnothing reads them except a test that acceptsmain's version.CHANGELOG.next.md,release-please-config.next.json,.release-please-manifest.next.json, and.github/workflows/release-please-next.ymlexist only onnext.mainnever changes them.- The
[project] versionline inpyproject.tomlconflicts after both lines have released. Keepnext's version (10.0.0aN).
next has its own release-please setup. The files are separate from main's
so that merges in either direction never change the other line's release flow:
.github/workflows/release-please-next.ymlruns on pushes tonextonly, with its own concurrency group andtarget-branch: next.release-please-config.next.jsonsetsversioning: prerelease,prerelease-type: alpha, andprerelease: true, and writesCHANGELOG.next.md..release-please-manifest.next.jsonholdsnext's current version.- The commit that added the setup ends with
Release-As: 10.0.0-alpha.0, so the first release is10.0.0-alpha.0. Every later release increments the alpha number (10.0.0-alpha.1, ...), whatever the commit type. Don't merge anextrelease PR that proposes a version without-alpha.N. - After release-please opens or updates the release PR, the workflow runs
scripts/normalize_pyproject_prerelease --release-prs --target-branch nextto rewritepyproject.tomlto PEP 440 (10.0.0a0). The normalizer accepts onlyrelease-please--branches--next--components--adcpPRs intonext. - When the release PR merges, release-please tags
v10.0.0-alpha.N, creates a GitHub release marked as a pre-release, and dispatchesrelease-publish.ymlwith--ref next. That workflow waits fornext's CI at the release commit, then publishes to PyPI after therelease-publishenvironment approval. PyPI treats10.0.0aNas a pre-release:pip install adcpkeeps resolving tomain's releases, and adopters opt in withpip install --pre adcporadcp==10.0.0a0.
One-time setup: add next to the release-publish environment's deployment
branches (GitHub Settings → Environments). The PyPI Trusted Publisher needs no
change, because it is bound to the release-publish.yml file name and the
release-publish environment, not to a branch.
#1502 added the experimental AdCP 3.3 identity code to main.
The revert PR removes it from main before 9.0.0-beta.4 (#1465) ships;
next already has the code. The trap: the next time next takes main, the
revert would come along and delete the identity code from next.
Right after the revert merges to main, and before anyone else merges main
into next, record the revert on next as merged without applying it:
git fetch origin
git switch next && git merge --ff-only origin/next
REVERT=$(git log origin/main --format=%H -1 --grep='^revert: move experimental AdCP 3.3 identity')
git merge --no-edit "$REVERT^" # main up to just before the revert
git merge -s ours "$REVERT" -m "chore: record main's revert of #1502 as merged; next keeps the identity code"
git merge --no-edit origin/main # the rest of main
git push origin nextThe -s ours merge makes the revert an ancestor of next but keeps next's
tree, so later syncs never apply it. Keep these merge commits: push directly
or merge with Create a merge commit.
Equivalent alternative: merge origin/main into next as usual, then
git revert <REVERT> on next (a revert of the revert). It gives the same
result but reports modify/delete conflicts wherever next has changed #1502's
files since, so prefer the -s ours sequence.
Use the same procedure for any later change that has to leave main but stay
on next.
When the draft spec that next tracks is ratified:
- Merge
mainintonextone last time and make surenext's CI passes. - Update
nextto the ratified spec (src/adcp/ADCP_VERSION, schemas, generated types, and the identity code's experimental markers). - On
next, delete.github/workflows/release-please-next.yml,release-please-config.next.json,.release-please-manifest.next.json, andCHANGELOG.next.md. Setpyproject.toml's version back tomain's. - Pick
main's first version of the new major. Commit it onnextas a conventional commit that ends with aRelease-As:footer, for exampleRelease-As: 10.0.0orRelease-As: 10.0.0-beta.0, and updaterelease-please-config.json's channel to match (seedocs/releasing.md). This must be the newestRelease-As:commit. Release-please uses the newest footer it finds, so it overridesnext's earlierRelease-As: 10.0.0-alpha.0. - If the 9.x line still needs fixes, create
release/9.xfrommain, with its own release-please workflow likerelease/8.x's. - Open a PR from
nextintomainand merge it with Create a merge commit, sonext's history (and the-s oursmerges above) stays intact. - Reset
nexttomain(or delete it and recreate it when the next draft spec starts).