Skip to content

Add PyPI Publishing to Automated Release#4220

Open
adnanhemani wants to merge 14 commits intoapache:mainfrom
adnanhemani:ahemani/add_pypi_publishing_to_automated_release
Open

Add PyPI Publishing to Automated Release#4220
adnanhemani wants to merge 14 commits intoapache:mainfrom
adnanhemani:ahemani/add_pypi_publishing_to_automated_release

Conversation

@adnanhemani
Copy link
Copy Markdown
Contributor

@adnanhemani adnanhemani commented Apr 16, 2026

Changes the PyPI nightly build script to use Trusted Publishers, as well as adding publishing scripts when generating a new release candidate and publishing new Polaris versions.

I've tested this from my fork: https://github.com/adnanhemani/polaris/actions/runs/24500027607/

I've already set up Trusted Publishers for both PyPI and TestPyPI:

Screenshot 2026-04-16 at 1 06 56 AM Screenshot 2026-04-16 at 1 07 18 AM

Result:

Screenshot 2026-04-16 at 1 27 18 AM

Checklist

  • 🛡️ Don't disclose security issues!
  • 🔗 Clearly explained why the changes are needed, or linked related issues: Fixes #
  • 🧪 Added/updated tests with good coverage, or manually tested (and explained how)
  • 💡 Added comments for complex logic
  • 🧾 Updated CHANGELOG.md (if needed)
  • 📚 Updated documentation in site/content/in-dev/unreleased (if needed)

Comment thread .github/workflows/nightly.yml Fixed
Comment thread .github/workflows/release-3-build-and-publish-artifacts.yml Fixed
Comment thread .github/workflows/release-4-publish-release.yml Fixed
@adnanhemani adnanhemani marked this pull request as ready for review April 16, 2026 08:28
Copy link
Copy Markdown
Member

@snazy snazy left a comment

Choose a reason for hiding this comment

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

Thanks for the effort here!

I cannot judge on the Python/Makefile specific changes.
The changes to the nightly.yml + release-3-... workflows look fine.

I do have two concerns about release-4-...:

The OIDC (id-token: write) permission for PyPi trusted publishing is exposed to all other steps that don't need it.

If, for example, everything but the PyPi publishing fails, it cannot be retried, and we have to re-roll a whole new release including all the vote-"ceremony". Not really new, as Docker-Hub publishing can also fail. I think it's better to have separate workflow-jobs for Maven publishing, Docker-Hub publishing and PyPi publising plus an "aggregator" job that depends on those. This gives us the ability to retry only a failed publishing job without failing a whole release.

(Preexisting) The contents: write permission is only needed to create the GH release. That permission can then also be limited to that "aggregator-job".

Comment on lines +79 to +80
permissions:
id-token: write
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.

This permission isn't commonly known, please add a comment explaining what it's used for.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done!

needs: [prerequisite-checks]
permissions:
contents: read
id-token: write
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.

Same here, deserves a comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

name: Generate Release Email Body
runs-on: ubuntu-latest
needs: [prerequisite-checks, build-and-publish-artifacts, build-docker, build-and-stage-helm-chart]
needs: [prerequisite-checks, build-and-publish-artifacts, build-docker, build-and-stage-helm-chart, publish-python-client-rc]
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.

Nit: the list is growing, maybe migrate to one line per dependency.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
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.

This one concerns me, because all steps now get access to OIDC/trusted-publishing.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

+1 we can move this to the step that pushes to pypi

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved.

Copy link
Copy Markdown
Contributor

@HonahX HonahX left a comment

Choose a reason for hiding this comment

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

@adnanhemani Thank you so much for adding this to our release process!

Comment thread Makefile Outdated
Comment on lines +196 to +197
uv version "$(BUILD_VERSION)" && \
uv build --clear
Copy link
Copy Markdown
Contributor

@HonahX HonahX Apr 16, 2026

Choose a reason for hiding this comment

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

Instead of making an internal one, could we re-use client-build and extend it to optionally set the version?
Currently, CLI's License & Notice are only valid if we only publish the wheel (it will be a universal wheel): #3891 (comment). So we probably need FORMAT=wheel when building artifacts

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good call, changed.

Comment on lines +79 to +80
permissions:
id-token: write
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
permissions:
id-token: write
permissions:
# IMPORTANT: this permission is mandatory for Trusted Publishing
id-token: write

https://docs.pypi.org/trusted-publishers/using-a-publisher/

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done!

Copy link
Copy Markdown
Contributor

@kevinjqliu kevinjqliu left a comment

Choose a reason for hiding this comment

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

looks great, thanks!

for pyiceberg, we push RCs as pre-release to pypi. we should double check that its indeed labeled as pre-release. Otherwise, if it accidentally gets label as the normal release, we'd have to yank the entire version (and publish a patch release). very tedious!

Copy link
Copy Markdown
Contributor Author

@adnanhemani adnanhemani left a comment

Choose a reason for hiding this comment

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

Thank you all for your reviews. At this time, I've only separated out the "publish-python-client" step in the release-4... script, as it is the smallest change relevant to this PR. We should continue the refactor as @snazy suggests in a different PR.

Comment on lines +79 to +80
permissions:
id-token: write
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done!

Comment on lines +79 to +80
permissions:
id-token: write
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done!

needs: [prerequisite-checks]
permissions:
contents: read
id-token: write
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

name: Generate Release Email Body
runs-on: ubuntu-latest
needs: [prerequisite-checks, build-and-publish-artifacts, build-docker, build-and-stage-helm-chart]
needs: [prerequisite-checks, build-and-publish-artifacts, build-docker, build-and-stage-helm-chart, publish-python-client-rc]
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done.

runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Moved.

Comment thread Makefile Outdated
Comment on lines +196 to +197
uv version "$(BUILD_VERSION)" && \
uv build --clear
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good call, changed.

@adnanhemani
Copy link
Copy Markdown
Contributor Author

@kevinjqliu - we are pushing RCs to TestPyPI and only pushing the released versions to PyPI. I believe this should be good enough to not cause errant versions?

Comment thread .github/workflows/nightly.yml
Comment thread Makefile Outdated
Copy link
Copy Markdown
Contributor

@kevinjqliu kevinjqliu left a comment

Choose a reason for hiding this comment

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

Minor bug when passing the format arg, otherwise LGTM

Applied the fix locally and tested:

make client-nightly-build
RC_VERSION=1.4.0 RC_NUMBER=1 make client-rc-build                                                                    
RELEASE_VERSION=1.4.0 make client-release-build

@snazy
Copy link
Copy Markdown
Member

snazy commented Apr 21, 2026

The recent Polaris 1.4.0 release workflow failed quite early during the changes to Apache SVN, before it handles Helm charts, Docker images or Nexus or even create the GitHub release. I think, Helm charts, Docker images and Nexus jobs would have worked fine during that workflow run, if those would have been separate jobs in the workflow.

The unsolvable issue with release-related workflows is that those steps cannot be integration tested. This is why I think splitting the work across multiple jobs reduces the amount of non-executed steps, that require manual work later.

Adding PyPi publishing adds another step that can potentially fail a whole release, but having that as a separate workflow job reduces the risk of affecting other parts of the release automation.

@adnanhemani
Copy link
Copy Markdown
Contributor Author

@snazy I agree with you - that's why I separated the PyPI uploads into separate Jobs. Did I miss something there?

I also don't disagree with your comments that we should separate all these steps into different jobs - but I don't find that necessary in this PR. I would highly prefer to do that in a follow up PR to reduce the scope of this PR. Is this a blocker for you?

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.

5 participants