Release Process
Guide the full release lifecycle. Proceed autonomously through mechanical steps (running scripts, polling CI, creating PRs) and pause only for genuine decisions, failures, or destructive actions.
Phase 0: Determine Release Parameters
Read the current version from the root
pom.xml— the-SNAPSHOTsuffix indicates the current dev version.Ask the user which version to release if not already specified.
Apply the Final suffix convention: if the user specifies a plain version like
1.2.0, the release version is1.2.0.Final. Pre-release qualifiers (Alpha1,Beta1,CR1) are used as-is.Suggest a sensible next SNAPSHOT version and confirm with the user:
- Final:
1.1.0.Final→1.1.1.Final-SNAPSHOT - Pre-release:
1.1.0.Alpha1→1.1.0.Alpha2-SNAPSHOT
- Final:
Determine the documentation plan:
- Skip for micro/patch releases (X.Y.Z where Z > 0)
- Ask for pre-releases (Alpha/Beta/CR)
- Yes for major/minor Final releases (X.Y.0.Final)
Detect git remotes. Run
git remote -vand identify:- Upstream remote: the remote whose URL contains
a2aproject/a2a-java(this is the canonical repo — it may be calledupstream,origin, or anything else). - Fork remote: a different remote owned by the current user (typically
origin). Extract the fork owner from its URL (e.g.,kabirfromgithub.com:kabir/a2a-java.git).
Throughout this skill,
<upstream>refers to the detected upstream remote name and<fork>refers to the fork remote name. All PRs are created from the fork, and tags/main are pushed to/pulled from upstream.- Upstream remote: the remote whose URL contains
Phase 1: Pre-Release Verification
Verify
ghCLI is installed and authenticated:gh auth statusIf not installed or not logged in, stop and ask the user to run
gh auth login.Verify clean working tree:
git statusIf there are uncommitted changes, stop and ask.
Verify we are on
mainand in sync with upstream. Fetch first to ensure the remote ref is current:git fetch <upstream> main git log --oneline HEAD..<upstream>/main git log --oneline <upstream>/main..HEADIf local main is behind or ahead of
<upstream>/main, stop and ask the user.Check latest CI status on main:
gh run list --repo a2aproject/a2a-java --branch main --limit 5If CI is failing, alert the user and stop.
Confirm the current SNAPSHOT version in
pom.xmlmatches expectations.
Phase 2: Version Bump & Release PR
Preview version changes:
./update-version.sh <current-SNAPSHOT> <release-version> --dry-runApply version update:
./update-version.sh <current-SNAPSHOT> <release-version>Verify the build compiles (tests will run in CI):
mvn clean install -DskipTestsIf the build fails, stop and report.
Create the release PR (pushed from fork):
git checkout -b release/<version> git add -A git commit -m "chore: release <version>" git push <fork> release/<version> gh pr create --repo a2aproject/a2a-java --head <fork-owner>:release/<version> --base main --title "chore: release <version>" --body "Release <version>"Wait for CI:
gh pr checks <pr-number> --repo a2aproject/a2a-java --watchIf there are flaky failures, rerun with
gh run rerun <run-id> --repo a2aproject/a2a-java --failedand watch again.Ask the user for confirmation before merging. Then merge:
gh pr merge <pr-number> --repo a2aproject/a2a-java --squash
Phase 3: Tag & Deploy
Update local main:
git checkout main git pull <upstream> mainCreate annotated tag:
git tag -a v<version> -m "Release <version>"Ask the user for confirmation before pushing the tag — this is irreversible and triggers Maven Central deployment.
Push the tag:
git push <upstream> v<version>This triggers
release-to-maven-central.ymlandcreate-github-release.yml.
Phase 4: Documentation, SNAPSHOT Bump & Post-Release PR
This phase combines documentation (when applicable) and the SNAPSHOT version bump into a single PR to avoid redundant CI waits.
Step 1: Update local main
git checkout main
git pull <upstream> main
Step 2: Documentation (conditional)
Documentation is created before the SNAPSHOT bump so that Javadoc generation uses release version strings.
Decision rules:
- Skip for micro/patch releases (X.Y.Z where Z > 0)
- Ask the user for pre-releases (Alpha/Beta/CR)
- Always do for major/minor Final releases (X.Y.0.Final)
When applicable:
Copy dev docs to the new version (replace dots with underscores in directory names to work around a Roq bug where dots break GitHub Pages serving):
cp -r docs/content/dev docs/content/<version_underscored>For example,
1.2.0.Final→ directory name1_2_0_Final.Create the version data file by copying
dev.yml(it has the most up-to-date menu):cp docs/data/versions/dev.yml docs/data/versions/<version>.ymlEdit
docs/data/versions/<version>.yml:- Set
labelto"<version>" - Set
pathto"<version_underscored>"(underscores, matching the content directory name) - Set
sortOrderto the next value — scan existing ymls for maxsortOrderexcludingdev.yml(which uses 999 as a sentinel), then increment by 1 - Set
defaultVersiontotrueonly for Final releases - Set
devVersiontofalse
- Set
For Final releases: set the previous default version's
defaultVersiontofalse.For pre-releases superseding a prior pre-release in the same X.Y.Z series: remove the old pre-release's content folder (
docs/content/<old-version_underscored>), version yml (docs/data/versions/<old-version>.yml), and apidocs folder (docs/public/<old-version_underscored>/apidocs/).Generate Javadoc. The
site-javadocprofile outputs todocs/public/dev/apidocs/:mvn javadoc:aggregate -Psite-javadoc cp -r docs/public/dev/apidocs docs/public/<version_underscored>/apidocsIf the
site-javadocprofile doesn't exist, note it and skip.Add Javadoc menu entry to the version yml if not already present.
Add a row for the new version to the compatibility table in
docs/content/index.html. The table is in the<section class="roq-section">block with headingCompatibility. Insert a new<tr>for the released version immediately before the<tr>fordev (unreleased), using the same A2A Protocol and Java columns as the previous row. Example:<tr> <td>1.3.0.Final</td> <td>1.0, 0.3</td> <td>17+</td> </tr>
Step 3: Bump to next SNAPSHOT
./update-version.sh <release-version> <next-SNAPSHOT>
Step 4: Create and merge the post-release PR
Use the branch name and PR title/body based on what the PR contains:
- With docs: branch
chore/post-release-<version>, title"chore: <version> docs and bump to <next-SNAPSHOT>", body"Versioned documentation for <version> and bump to <next-SNAPSHOT>" - Without docs: branch
chore/bump-to-<next-SNAPSHOT>, title"chore: bump version to <next-SNAPSHOT>", body"Bump version to <next-SNAPSHOT>"
git checkout -b <branch-name>
git add -A
git commit -m "<commit-message>"
git push <fork> <branch-name>
gh pr create --repo a2aproject/a2a-java --head <fork-owner>:<branch-name> --base main --title "<title>" --body "<body>"
gh pr checks <pr-number> --repo a2aproject/a2a-java --watch
If there are flaky failures, rerun with gh run rerun <run-id> --repo a2aproject/a2a-java --failed and watch again.
Step 5: Verify Maven Central deployment
Check that the Maven Central deployment workflow completed successfully:
gh run list --repo a2aproject/a2a-java --workflow=release-to-maven-central.yml --limit 5
If the release workflow failed, stop and guide troubleshooting (check logs — common causes: expired tokens, javadoc issues). May need to delete the tag and retag.
Step 6: Merge
Once CI and Maven Central deployment are both green:
gh pr merge <pr-number> --repo a2aproject/a2a-java --squash
Phase 5: Verify Deployment
Print the following URLs for the maintainer to check:
- Maven Central:
https://central.sonatype.com/artifact/org.a2aproject.sdk/a2a-java-sdk-parent/<version> - GitHub Release:
https://github.com/a2aproject/a2a-java/releases/tag/v<version>
Note that Maven Central propagation can take up to 2 hours.