ci: a Prepare Release workflow, so the tag and __version__ agree by construction - #7
Merged
Merged
Conversation
…onstruction publish.yml refuses a tag that does not match de_shell.__version__ — a guard that can only fire after the tag is pushed, when the fix is a new tag. This does the bump and the changelog in a PR instead, so the version the tag has to match is the version the PR just wrote. Same flow and input vocabulary as SpyDE's and anyplotlib's Prepare Release (finalize / minor / bugfix / major / pre-release, plus the beta checkbox). Three things are de-shell's own: - PEP 440 `bN` pre-releases, anyplotlib's shape rather than SpyDE's semver `-rc.N`: this is a PyPI package, and pip sorts bN. The version regex is anchored at both ends, so `0.2.2.post1` is refused rather than silently read as 0.2.2. - The bump is a `sed` on de_shell/__init__.py, which is silent when its pattern misses — so the step reads the value back and fails if it did not land. A silent no-op here would open a release PR that bumps nothing and produce a tag publish.yml rejects. - SpyDE's release pre-flights carry over (`uv lock --check`, git deps pinned to SHAs or tags). Neither can fail today; the lock one matters most later, because the apps resolve the sidecar env from a lock on the user's machine, so drift surfaces at their user's first launch, not in a build of ours. Checked by extracting the embedded bump script from the YAML and running it: 14 cases, 9 bumps and 5 refusals, all as expected. The Releasing section and upcoming_changes/README.rst said the changelog was assembled by hand, which was true for exactly one commit; both now point here.
This was referenced Sep 24, 2026
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.
publish.ymlrefuses a tag that does not matchde_shell.__version__— aguard that can only fire after the tag is pushed, when the only fix is a new
tag. This does the bump and the changelog in a PR instead, so the version the
tag has to match is the version the PR just wrote.
Run it from the Actions tab, pick a bump, review the PR it opens, merge, tag.
Same as SpyDE and anyplotlib
The flow and the input vocabulary are theirs:
finalize/minor/bugfix/major/pre-release, plus the beta checkbox, with the same refusal to guesswhen you ask for a
minorbump while sitting on a pre-release of the nextversion. SpyDE's release pre-flights carry over too —
uv lock --checkand thegit-deps-pinned scan.
Three things that are de-shell's own
bNpre-releases — anyplotlib's shape rather than SpyDE's semver-rc.N, because this is a PyPI package and pip sortsbN. The version regexis anchored at both ends, so
0.2.2.post1is refused rather than silentlyread as
0.2.2(anyplotlib's is unanchored).npm version, whicherrors on its own. Here the bump is a
sedonde_shell/__init__.py, andsedis silent when its pattern misses — a silent no-op would open a releasePR that bumps nothing and produce a tag
publish.ymlrejects. The step readsthe value back and fails if it did not land.
--version-less towncrier.package = "de_shell"would let towncrierread the version itself, but that import wants the package's dependencies
installed and this job has no other reason to install them, so the version is
passed explicitly.
There is no download-links or docs-switcher step: this ships a wheel, not
installers or a docs site.
Checked
I pulled the embedded bump script back out of the YAML and ran it — 14 cases,
9 bumps and 5 refusals, all as expected:
Refused:
finalizewith nobN;minororbugfixfrom a beta (either wouldskip 0.3.0 entirely);
not.a.version;0.2.2.post1.Also checked: the YAML parses, the
sedbump and its read-back guard workagainst the real
de_shell/__init__.py, anduv lock --checkpasses today.Docs
The Releasing section and
upcoming_changes/README.rstsaid the changelog wasassembled by hand — true for exactly one commit. Both now point here.