INTPYTHON-1069 Avoid using TestPyPI in the release process (#436)
[INTPYTHON-1069](https://jira.mongodb.org/browse/INTPYTHON-1069) ## Summary Removes TestPyPI from the release process, following [PYTHON-5971 / winkerberos#161](https://github.com/mongodb/winkerberos/pull/161) and PYTHON-5970 (PyMongo). PyPI admins are deprecating TestPyPI and have already de-prioritized it; local validation replaces the round-trip. Two reasons specific to this repo: - **TestPyPI is a hard blocker for the first `langchain-mongodb-deepagents-vfs` release.** Trusted publishing needs a pending publisher on every index used, and the maintainer's TestPyPI account name/email doesn't match their PyPI one — recoverable only by emailing PyPI support. - `_test_release.yml` passed `skip-existing: true`, which its own comment describes as *"only for CI use and extremely dangerous otherwise"*. ## Changes in this PR | File | Change | |---|---| | `.github/workflows/_test_release.yml` | deleted (96 lines) | | `.github/workflows/_release.yml` | `test-pypi-publish` job removed; 3 `needs:` entries dropped; `validate-pyproject` + `twine check --strict` added to `build`; `pre-release-checks` reworked | `RELEASE.md` needed no change — it never referenced TestPyPI. ### The non-obvious part: `pre-release-checks` The coupling here is deeper than in winkerberos, which only had a publish step to delete. This job installed the package **from TestPyPI** to validate the built artifact the way a consumer receives it: ``` uv run pip install --extra-index-url https://test.pypi.org/simple/ "$PKG_NAME==$VERSION" || \ ( sleep 5 && uv run pip install --extra-index-url ... ) ``` TestPyPI was only the delivery mechanism for that check, so it now installs the wheel directly from the `dist` artifact the `build` job already uploads. A `download-artifact` step is added, since that job didn't previously fetch it. The sleep-and-retry loops are gone — they existed solely for TestPyPI propagation delay. ### ⚠️ twine must be pinned — the house recipe fails verbatim here ``` $ uvx twine check --strict dist/* ERROR InvalidDistribution: Invalid distribution metadata: '2.5' is not a valid metadata version ``` Not stale tooling: `uvx` resolves twine 6.2.0, and **twine <7 cannot parse `Metadata-Version: 2.5`**, which current hatchling emits. With the floor: ``` $ uvx --from 'twine>=7' twine check --strict dist/* Checking dist/langchain_mongodb-0.12.0-py3-none-any.whl: PASSED Checking dist/langchain_mongodb-0.12.0.tar.gz: PASSED ``` PyPI itself accepts Metadata 2.5 — `hatchling` 1.32.0 and `langsmith` 0.11.1 are published with it — so twine was simply behind. This also retroactively explains the `test_distribution.py` failure removed in #427; that was the same root cause, not vaguely "outdated local twine". ## Trade-off **Lost:** a genuine round-trip through a warehouse instance, which implicitly proved PyPI would accept the artifact's metadata *before* the real upload. That now surfaces in `publish` instead. `twine check --strict` in the `build` job is the intended mitigation and covers the same class of problem locally. **Gained:** `pre-release-checks` now resolves dependencies from **real** PyPI rather than a TestPyPI/PyPI hybrid, making it a more faithful consumer simulation than before; one fewer OIDC publisher per new package; `skip-existing` gone; shorter pipeline. ## Test Plan - `validate-pyproject` passes for **all four** libs (`langchain-mongodb`, `langchain-mongodb-deepagents-vfs`, `langgraph-checkpoint-mongodb`, `langgraph-store-mongodb`). - `twine check --strict` with `twine>=7` passes for the `langchain-mongodb` and `langchain-mongodb-deepagents-vfs` builds; fails with the default (6.2.0), which is why the floor is pinned. - `check-yaml` and `Validate GitHub Workflows` pre-commit hooks pass on the changed workflow. - Job dependency graph parsed and confirmed: `build → pre-release-checks → publish → mark-release`. - No TestPyPI references remain anywhere under `.github/`. Not exercised end-to-end: `_release.yml` only runs on `main` via `workflow_dispatch`, so the reworked `pre-release-checks` job cannot run on a PR. Reviewers may want a dry run before the next release — the deepagents-vfs first release is the natural candidate, since it is blocked on TestPyPI today either way. ## Checklist ### Checklist for Author - [ ] Did you update the changelog (if necessary)? - [ ] Is the intention of the code captured in relevant tests? - [ ] If there are new TODOs, has a related JIRA ticket been created? - [ ] Has a MongoDB Employee run [the patch build of this PR](https://github.com/mongodb-labs/ai-ml-pipeline-testing?tab=readme-ov-file#running-a-patch-build-of-a-given-pr)? ### Checklist for Reviewer - [ ] Does the title of the PR reference a JIRA Ticket? - [ ] Do you fully understand the implementation? (Would you be comfortable explaining how this code works to someone else?) - [ ] Is all relevant documentation (README or docstring) updated? Signed-off-by: Casey Clements <casey.clements@mongodb.com>
C
Casey Clements committed
091694c04b7669813724a88d6c8cc9e7aa6b4b9a
Parent: 006027e
Committed by GitHub <noreply@github.com>
on 8/24/2026, 4:45:12 PM