release:resume
Finish a release that reached one channel and not the other, without bumping the version.
Table of contents
Usage
splent release:resume <target> [--yes] [--no-pypi] [--no-github]
| Target | Resolves to |
|---|---|
cli |
splent_cli |
framework |
splent_framework |
product |
The active product |
| A feature reference | splent_feature_auth, or splent-io/splent_feature_auth |
Options
| Option | Description |
|---|---|
--yes |
Do not ask for confirmation before publishing what is missing. |
--no-pypi |
Do not touch PyPI, even if something is missing there. |
--no-github |
Do not touch GitHub, even if something is missing there. |
Why it exists
The release gate lowers the odds of a mid
flight failure, it does not remove them. When a channel refuses after
another one has accepted, the version is stuck. Re-running
feature:release would bump the version again and burn a number while
leaving the broken one behind. That is exactly how several features
reached v0.2.1 without ever reaching PyPI.
This command is the other path. It never bumps. It reads the version that
is already committed in pyproject.toml, asks each channel what is
actually missing, and publishes only that.
Two rules that make it usable
It exists for a workspace where something is already wrong, so it is built for that state.
- A channel that is blocked never stops a channel that is not. If GitHub answers 401 and PyPI is the only thing missing, the PyPI half runs. Refusing to do the reachable half is how thirteen features became unrecoverable behind one unrelated token. The blocked channel is reported, the command exits non zero, and you run it again once that is fixed.
- It never moves your checkout. When the tag is not at
HEAD, the package is built from a temporarygit worktreeof the tag, which is removed afterwards. In a SPLENT workspace a feature directory is symlinked into the running product, and checking out a tag there would silently change what the product serves.
What it can finish
| Step | When it runs |
|---|---|
| Build and upload to PyPI | The version is not on PyPI and PyPI is reachable |
| Push the tag to origin | The tag is not on the remote |
| Create the GitHub release | The tag has no Release |
| Build and push the Docker image | Products only, when the tag is not on Docker Hub |
| Create the local snapshot | Features only, when .splent_cache/features/<org>/<name>@<tag> is missing and the tag is on the remote |
The snapshot is a clone of the tag from GitHub, so it can only be created once the tag is actually there. A feature release whose original run died before that step leaves a version that is published and still unusable locally, so finishing the job includes creating it.
When the tag does not exist yet, the tag will be created at HEAD and the
package built from the working tree, so the command refuses to start on a
dirty tree and tells you to commit or stash.
Example
splent release:resume splent_feature_team
Resuming splent-io/splent_feature_team v0.2.1
The version is read from pyproject.toml and is never bumped here.
Release gate (channels)
github ready, v0.2.1 is tagged on splent-io/splent_feature_team, release missing
pypi ready, credentials accepted, splent_feature_team exists so this is a new version
Missing
- build and upload splent_feature_team 0.2.1 to PyPI
- create the GitHub release for v0.2.1
Publish what is missing? [Y/n]
When everything is already in place the command says so and does nothing. When every channel is unreachable it refuses, because nothing can be finished.
See also
check:releases. Find every package that needs this- Release. The pipeline and the channel gate