Problem
After the move to setuptools-scm, release artifacts need to be built from the tagged ref in order to get the exact release version.
PR #1606 fixed the correctness problem by making tag pushes run the full CI workflow and by requiring release uploads to consume artifacts from that tag-triggered run.
That is safe, but it is expensive:
- pushing a release tag re-runs the full CI matrix at the same commit
- release managers have to wait for a separate workflow run before they can publish
- we duplicate work that release does not actually need, especially large test matrices and docs
- the artifact handoff is indirect (
lookup-run-id, cross-run artifact download, "wait for tag CI")
Proposed long-term shape
Treat CI and Release as two different responsibilities:
CI validates PRs and main
Release builds and publishes release artifacts from a tag
The intended flow becomes:
- Merge to
main and let normal CI validate the commit.
- Create a release tag pointing at that known-good
main commit.
- Run the appropriate release workflow manually.
- Release preflight verifies:
- the tag exists
- the tag points to a commit reachable from
main
- that commit already has a successful
CI run on main
- The release workflow builds the publishable artifacts from the tag in the same workflow run.
- The release workflow validates those artifacts, builds release docs, uploads release assets, and publishes to PyPI/TestPyPI.
- Publish jobs consume artifacts from the same release workflow run that built them.
What changes in the repo
CI
- stop triggering
.github/workflows/ci.yml on release tag pushes
- keep
CI focused on validating PR branches and main
- keep the current broad build-and-test behavior there, because that is the validation path
Release
- make
.github/workflows/release.yml and .github/workflows/release-cuda-pathfinder.yml the only tag-aware workflows
- build release wheels inside the release workflow instead of pulling them from a separate tag-triggered
CI run
- keep release builds minimal and component-aware
- build release docs from the artifacts produced by that same release run
- publish only artifacts built and validated in that same release run
Artifact plumbing
- remove the need for cross-run artifact lookup such as
ci/tools/lookup-run-id
- stop requiring release managers to wait for a tag-triggered
CI run and pass around run IDs
- keep
ci/tools/validate-release-wheels or equivalent validation in the release path
Why this shape
With the current setuptools-scm setup, the tagged release wheel is inherently different from the pre-tag main wheel, so at least one rebuild at release time is hard to avoid.
The main optimization opportunity is therefore not "avoid every rebuild", but:
- do exactly one rebuild
- do it in the narrowest workflow possible
- keep the artifact lineage simple and local to the release workflow
This gives us:
- less duplicated work
- fewer moving pieces for release managers
- less waiting on unrelated CI jobs during release
- a clearer separation between validation and publication
Non-goal
This does not solve the stricter "build once in CI and later promote the exact same artifact" model.
That would likely require a larger packaging/versioning change, such as making the release version explicit before CI rather than deriving it only from the tag at build time.
Follow-up ideas
- split reusable build logic so release can build only the packages required for the selected component
- add lightweight release-only smoke checks (for example,
twine check plus install/import checks) instead of re-running the full CI test matrix
- document the new release flow in the release checklist and
RELEASE-*.md docs
- consider a dry-run release-build workflow to exercise the release-only path without publishing
Problem
After the move to
setuptools-scm, release artifacts need to be built from the tagged ref in order to get the exact release version.PR #1606fixed the correctness problem by making tag pushes run the fullCIworkflow and by requiring release uploads to consume artifacts from that tag-triggered run.That is safe, but it is expensive:
lookup-run-id, cross-run artifact download, "wait for tag CI")Proposed long-term shape
Treat
CIandReleaseas two different responsibilities:CIvalidates PRs andmainReleasebuilds and publishes release artifacts from a tagThe intended flow becomes:
mainand let normalCIvalidate the commit.maincommit.mainCIrun onmainWhat changes in the repo
CI.github/workflows/ci.ymlon release tag pushesCIfocused on validating PR branches andmainRelease.github/workflows/release.ymland.github/workflows/release-cuda-pathfinder.ymlthe only tag-aware workflowsCIrunArtifact plumbing
ci/tools/lookup-run-idCIrun and pass around run IDsci/tools/validate-release-wheelsor equivalent validation in the release pathWhy this shape
With the current
setuptools-scmsetup, the tagged release wheel is inherently different from the pre-tagmainwheel, so at least one rebuild at release time is hard to avoid.The main optimization opportunity is therefore not "avoid every rebuild", but:
This gives us:
Non-goal
This does not solve the stricter "build once in CI and later promote the exact same artifact" model.
That would likely require a larger packaging/versioning change, such as making the release version explicit before CI rather than deriving it only from the tag at build time.
Follow-up ideas
twine checkplus install/import checks) instead of re-running the full CI test matrixRELEASE-*.mddocs