Skip to content

Publish and release to Maven Central (h3-java pattern) - #94

Merged
drametwally merged 5 commits into
uber:mainfrom
drametwally:publish-and-release-maven-central
Oct 23, 2026
Merged

drametwally merged 5 commits into
uber:mainfrom
drametwally:publish-and-release-maven-central

Conversation

@drametwally

@drametwally drametwally commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Align USSI release automation with landed motif #281:

  • Tag-triggered .github/workflows/release.yml only (vX.Y.Z)
  • Prep on main via PR (VERSION_NAME, BUILD.bazel, # X.Y.Z in CHANGELOG.md)
  • publishToMavenCentral + mavenCentralAutomaticPublishing=true (org secrets, no manual Portal promote)
  • GitHub Release via gh release create + changelog section
  • USSI-only: validate BUILD.bazel maven_coordinates; JDK 21 only (single artifact)

Removes workflow_dispatch, auto-commits, and publishAndReleaseToMavenCentral from the prior draft.

After merge

Re-tag v0.1.0 on merge commit to publish com.uber.ussi:ussi:0.1.0 with current org signing.

Test plan

  • Ty review vs motif release.yml
  • Merge
  • Push v0.1.0 and confirm Actions + repo1 + GitHub Release

Match h3-java: upload, validate, and promote in CI instead of staging-only
publishToMavenCentral. Wait for PUBLISHED before the workflow completes.
Add CHANGELOG-driven GitHub Releases, workflow_dispatch snapshot stripping,
and VERSION_NAME/BUILD.bazel prep commits. Keep publishAndReleaseToMavenCentral.
Comment thread .github/workflows/publish-release.yml Outdated
exit 0
fi
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shoudln't check in an email, right?

run: ./gradlew publishToMavenCentral --no-daemon
run: ./gradlew publishAndReleaseToMavenCentral --no-daemon

- name: Create GitHub Release

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

h3-java includes the github token as an env var, is that needed to invoke the api and handle this?

awk -v ver="$RELEASE_VERSION" '
/^## / { if (found) exit; if (index($0, "## [" ver "]") == 1) { found=1; next } }
found
' CHANGELOG.md > release_notes.md

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you tracking a changelog already? If not, the generated one from PR names could also be an option, although I'm not sure what that looks like via the workflow.

Use runtime git identity, GITHUB_TOKEN for gh-release, match h3-java filename.

@tyvsmith tyvsmith left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for iterating on this. Motif's version of this workflow (uber/motif#281) landed and published 0.4.0-alpha16 successfully. Its structure would work well here, with a few ussi-specific differences.

Drop the manual dispatch

  • main requires "test on ubuntu-latest" and "test on macos-latest" to pass, with admins not exempt. The commit created by "Prepare release version on main" has no checks, so git push origin HEAD:main should be rejected. h3-java hit the same wall, which is why its snapshot-bump step is commented out.
  • Dispatch only works when VERSION_NAME is already the release version, and then it does what a tag push already does.
  • release_version has to equal the version derived from VERSION_NAME, so it can't override anything.
  • softprops creates the tag on whatever main's latest commit is when that step runs, not on the commit that was built.
  • Dropping dispatch also lets checkout go back to persist-credentials: false without fetch-depth: 0.

Gaps

  • Pin comments don't match the SHAs: checkout 3d3c42e is v7.0.1 (not v4.2.2), setup-java de7274f is v6.0.1 (not v4.7.0), gradle/actions 9c97196 is v6.3.0 (not v4.4.0), softprops efb3536 is v3.0.3 (not v2.3.3)
  • BUILD.bazel isn't checked: the tag path compares the tag with VERSION_NAME only. Please also check that maven_coordinates in BUILD.bazel matches, so Bazel coordinates can't drift.
  • v0.1.0 cleanup: a draft GitHub Release already exists for v0.1.0. Delete it before moving the tag, or the release step may update the draft or create a second one. Also confirm that deployment b099eae0… was dropped on Central first.
  • Notes check: [[ ! -s release_notes.md ]] passes a section with only blank lines. grep -q '[^[:space:]]' release_notes.md catches that.
  • Write access for a third-party action: contents: write covers every step. Motif uses gh release create "$RELEASE_TAG" --verify-tag --notes-file release_notes.md with GH_TOKEN: ${{ github.token }}, which avoids the third-party action entirely.
  • Redundant env vars:
    • ORG_GRADLE_PROJECT_RELEASE_SIGNING_ENABLED is already set in gradle.properties
    • softprops' token input already defaults to github.token

Keep as is

  • the vX.Y.Z tag format and the Keep a Changelog ## [X.Y.Z] sections
  • the Gradle test step: tests.yml only builds with Bazel, so this is the only place the Gradle publish path gets exercised. A Gradle build job in tests.yml that isn't a required check would catch breakage before release day; that can be a follow-up.
  • mavenCentralDeploymentValidation=PUBLISHED

Known limitation

If the GitHub Release step fails after publishing, "Re-run failed jobs" re-runs publish too, and that fails because Central won't accept the same version twice. Motif has the same gap; it's fine to leave for now.

Review drafted with an AI agent.

Tag-triggered publishToMavenCentral with automatic Central promotion,
motif-style changelog and GitHub Release, and USSI BUILD.bazel validation.

@tyvsmith tyvsmith left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this matches Motif's workflow (uber/motif#281) and keeps the right ussi-specific pieces. The dispatch removal, gh release create, the notes check, and the BUILD.bazel check all look good. I checked the BUILD.bazel check and the changelog extraction against this branch, and both return 0.1.0.

A correction to my earlier review: tests.yml already runs gradle test on ubuntu-latest, so dropping the Gradle test step from the release workflow is right. My "keep the Gradle test step" point was wrong.

Before re-tagging v0.1.0:

  • delete the existing draft GitHub Release for v0.1.0. A draft doesn't reserve the tag, so gh release create would likely create a second release next to it.
  • confirm deployment b099eae0… was dropped on Central
  • move v0.1.0 from 5ddc9e9 to the merge commit and push it with --force. A forced tag push still starts the workflow.

Nit: the CHANGELOG.md header still says it's based on Keep a Changelog, but the sections now use the # X.Y.Z format. Drop or reword that line.

Review drafted with an AI agent.

@drametwally
drametwally merged commit f32bc31 into uber:main Oct 23, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants