Harden the release pipeline: dry-run dispatch, tested artifacts, strict smoke, TestPyPI check - #13
Merged
Merged
Conversation
…ifacts, strict smoke, TestPyPI check release-python.yml gains a dry run: dispatch on a branch with the tag input naming the intended tag and skip-publish on, and the tag validation, version policy, full test matrix and artifact build run without uploading anything or consuming a tag. Uploads and the draft release now require a real tag ref. The separate build job is gone: the test job's ubuntu dist cell already builds, verifies and smoke-tests the wheel and sdist, so the publish and release jobs download that dist-<plugin> artifact and the published bytes are the tested bytes. The clean-project smoke installs are strict unless plugin.toml allow-final is false (the only case where the SDK still ships the same files), on TestPyPI as well as PyPI; allow_final is a prepare output. check-version-policy also refuses a version that already exists on TestPyPI, because uploads are immutable and skip-existing would otherwise hide the failure while the smoke test validated stale bytes. transition_markers() fails closed on git errors instead of reporting no markers. The release checkout no longer persists the write token, assets are uploaded with gh release upload --clobber, first-release notes link tree/refs/tags/<tag>/<dir>, and the SDK-overlap warning appears in pre-release notes only for plugins the SDK still bundles.
12 tasks
brianstrauch
approved these changes
Sep 10, 2026
…spatch inputs Self-review of the hardening PR found that a hard failure on a version already staged on TestPyPI removed the only recovery path for a failed final release (fix-forward cannot produce a new 1.0.0, and a fresh dispatch or re-run of all jobs would trip the check). The staged check is now a warning behind --check-testpypi, and the real guarantee moves to where it belongs: both smoke jobs run verify-index-files, which fails unless the index serves exactly the sha256 of the artifacts this run built (uv_build is reproducible, so a legitimate re-run passes and only foreign bytes fail). A dispatch on a tag ref with a different tag input could publish plugin A while rewriting plugin B's release: prepare now rejects that, requires the tag input for branch dispatches, and exports the parsed tag so the release job never reads github.ref_name. The publish gate compares skip-publish against the literal false, so a malformed value is a dry run rather than an upload. Artifacts are named per lane (dist-<plugin>-<deps>) and the release consumes -locked. draft-release refuses to modify a release that is already published. transition_markers fails closed when git is missing. github-release uses !cancelled(), and the concurrency group is per tag so dry runs do not queue behind each other. The policy tests no longer reach the network, and the workflow tests pin the smoke strictness expressions, the dist-cell ordering and the dispatch guard. The runbook now puts the dry run between the version bump and the tag push.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses the actionable items of #12 before the first tag.
Changes
workflow_dispatchgainstagandskip-publish. Dispatching onmainwith-f tag=python/<name>/v<version>runs tag parsing, the manifest check, the version policy, the full test matrix and the artifact build; nothing is uploaded, nothing is drafted, no tag is consumed. A dispatch from a branch can never publish (github.ref_type != 'tag');skip-publishadditionally turns a dispatch on a tag ref into a dry run, and only the literalfalsepublishes.preparerejects a dispatch on a tag ref whosetaginput names a different tag, and a branch dispatch without ataginput.buildjob is removed; publish, smoke and release jobs usedist-<plugin>-locked, the artifact that_python-plugin.yml's ubuntu dist cell built, verified withcheck_wheel.pyand smoke-tested in isolation. Artifact names carry the dependency lane.verify-index-filesbefore installing: every local file must be served with an identical sha256. uv_build is reproducible, so a legitimate re-run passes.--check-testpypi, not a failure; "Re-run failed jobs" keepsprepare's outputs and the tested artifact.allow_finalis aprepareoutput and both smoke jobs setALLOW_OVERLAP_WITH_COREfrom it: overlap with the SDK is tolerated only whileallow-final = false, on TestPyPI as well as PyPI.gh release upload --clobber; the release job works fromprepare's parsed tag rather thangithub.ref_name.transition_markers()raises on anygit grepfailure and on a missing git; the release checkout setspersist-credentials: false; first-release notes linktree/refs/tags/<tag>/<dir>; the SDK-overlap warning in pre-release notes appears only for plugins the SDK still bundles; per-tag concurrency group;!cancelled()on the release job.Not in this PR (from #12): repo visibility (decision), PyPI project owners (after the first upload), the
1.0.0rc2release PR (after #6), adapter test coverage (#6).Testing
uv run --project scripts --locked pytest scripts/tests -q: 79 passed at the merged head; the policy tests no longer touch the network.scripts/ci/check_conventions.py: OKgh workflow run release-python.yml --ref main -f tag=python/openai_agents/v1.0.0rc1.