feat(hub): publish agent wheels to PyPI (dual R2 + PyPI) (#1179)#1454
Conversation
The dual-publish CLI (gaia agent publish) already uploaded each agent wheel to both R2 and PyPI at author time, but nothing published the wheels on a release. This adds the missing CI half: publish_agents.yml builds every production gaia-agent-* wheel and publishes it to PyPI on a v* tag via pypa/gh-action-pypi-publish, with skip-existing so an unchanged agent version is a no-op (PyPI-native immutability, no custom overwrite logic). The publish matrix is derived from setup.py's [agents] extra through a new util/list_agent_packages.py helper, so the meta-package, the install docs, and the publish workflow all read one source of truth — adding an agent to the extra is enough to start publishing it.
Review: feat(hub): publish agent wheels to PyPI (#1454)SummaryClean, well-scoped devops PR that closes the last gap in #1179 — a Security posture is sound: Issues Found🟢 Token scoping vs. the approval gate ( 🟢 🟢 Narrow exception catch in the AST reader ( 🟢 Heads-up, not introduced here: Strengths
VerdictApprove. No blocking issues — the three minors are optional hardening. Just make sure the |
Why this matters
gaia agent publishalready dual-uploads each agent wheel to R2 (the Hub UI source) and PyPI (thepip installsource) at author time — but nothing published those wheels on a release. Sopip install gaia-agent-<id>andamd-gaia[agents]had no automation behind them. This adds the missing CI half: on av*tag, every productiongaia-agent-*wheel is built and published to PyPI viapypa/gh-action-pypi-publishwithskip-existing: true, so an unchanged agent version is a no-op (PyPI-native immutability — no custom overwrite logic). Closes the last open item of #1179.The publish matrix is derived from
setup.py's[agents]extra through a newutil/list_agent_packages.pyhelper, so the meta-package, the install docs, and the publish workflow all read one source of truth — adding an agent to the extra is enough to start publishing it (no second list to drift).Scope note: the dual-publish
publisher.py, thegaia agent publish/loginCLI,tests/unit/test_hub_publisher.py, the[agents]/[agent-*]extras, and theamd-gaia>=wheel deps all landed earlier (#1415, #1102 wave). This PR adds only what was still missing for #1179: the release-tag PyPI workflow, the drift-proof matrix helper, guard tests, and the install/CI docs.Test plan
python util/lint.py --black --isort— cleanpylint -E util/list_agent_packages.py tests/unit/test_agent_pypi_publish.py— cleanpytest tests/unit/ -k "agent and (publish or install or hub)"— 38 passedpytest tests/unit/test_agent_pypi_publish.py— 10 passed (helper drift, wheelamd-gaiadep,gaia-agent-<id>naming, workflow usesgh-action-pypi-publish+PYPI_API_TOKEN+skip-existing, publish gated onv*)python -m build hub/agents/python/summarize— wheel builds;twine checkPASSED; metadata declaresRequires-Dist: amd-gaia>=0.20.0python util/list_agent_packages.py --format matrix— resolves the 11 migrated agents to theirhub/agents/python/<id>dirspaths:filter (so a release isn't skipped when the tagged commit didn't touch an agent)PYPI_API_TOKENrepository/org secret with upload rights to thegaia-agent-*projects before the first tagged release