feature:release
Release a feature: auto-infer its contract, bump version, tag, publish to GitHub and PyPI, and create a versioned cache snapshot.
Table of contents
Usage
splent feature:release <feature_name> [<version>] [--attach]
| Argument / Option | Description |
|---|---|
<feature_name> |
Feature to release (splent_feature_auth or splent-io/splent_feature_auth). |
<version> |
Optional. Version to release (e.g. v1.2.7). If omitted, the semver wizard runs. |
--attach |
After release, attach the new version to the active product. |
Examples
With the semver wizard (recommended)
Omit the version and the wizard fetches the current tag from GitHub, shows the three semver options, and asks you to choose:
splent feature:release splent_feature_auth
Fetching current version from GitHub...
Current version: v1.2.6
Bump type:
[1] patch v1.2.7 bug fixes, no new features
[2] minor v1.3.0 new features, backward compatible
[3] major v2.0.0 breaking changes
[4] cancel
Choice: 1
Will release as v1.2.7
Proceed? [y/N]: y
Releasing splent_io/splent_feature_auth v1.2.7
contract updating from source code...
contract written to pyproject.toml
version 1.2.7 written to pyproject.toml
commit changes committed and pushed
tag v1.2.7 created
tag v1.2.7 pushed to origin
github release created: https://github.com/...
pypi building package...
pypi upload complete
snapshot splent_feature_auth@v1.2.7 (read-only)
splent_io/splent_feature_auth v1.2.7 released.
With an explicit version
splent feature:release splent_feature_auth v1.2.7
Release and attach to the active product
splent feature:release splent_feature_auth --attach
Description
Performs a full release pipeline:
- Validates environment credentials.
- Infers the feature contract from source code (see below).
- Writes the inferred contract to
[tool.splent.contract]in the feature’spyproject.toml. - Updates
[project].versionto<version>. - Stages, commits, and pushes all pending changes to
main. - Creates and pushes a Git tag.
- Creates a GitHub Release.
- Cleans build artifacts (
__pycache__,dist/,build/,*.egg-info). - Compiles frontend assets (delegates to
feature:compile). - Builds and uploads the package to PyPI.
- Creates a versioned snapshot in
.splent_cache(read-only). - Asks whether to attach the released version to the active product (default: yes). Use
--attachto skip the prompt and attach automatically.
Automatic contract inference
Before any versioning step, feature:release delegates to feature:contract --write to scan the feature’s source code and rewrite [tool.splent.contract] in pyproject.toml. Both commands use the same update_contract() function, ensuring consistent inference whether done during development or at release time.
[tool.splent.contract]
description = "Authentication feature" # ← preserved if already set
[tool.splent.contract.provides]
routes = ["/auth/login", "/auth/logout", "/auth/register"]
blueprints = ["auth_bp"]
models = ["User"]
commands = []
hooks = ["layout.anonymous_sidebar", "layout.authenticated_sidebar"]
services = ["AuthService"]
docker = []
signals = ["user_registered", "user_logged_in"]
translations = ["en", "es"]
[tool.splent.contract.requires]
features = []
env_vars = ["SECRET_KEY", "MAIL_SERVER"]
signals = ["profile_updated"]
[tool.splent.contract.extensible]
hooks = true
signals = true
What is scanned:
| Field | Source file | What is detected |
|---|---|---|
provides.routes |
routes.py |
@<bp>.route(...) decorator paths |
provides.blueprints |
__init__.py |
BaseBlueprint / Blueprint variable names |
provides.models |
models.py |
class <Name>(db.Model) definitions |
provides.commands |
commands.py |
@click.command("name") decorators in commands.py |
provides.hooks |
hooks.py |
register_template_hook("slot", func) slot names |
provides.services |
services.py |
class <Name>(BaseService) definitions |
provides.docker |
feature root | docker-compose*.yml / docker-compose*.yaml files |
provides.signals |
signals.py |
define_signal() calls in signals.py |
provides.translations |
translations/ |
Locale directories in translations/ |
requires.features |
all .py files |
Imports of other splent_feature_* packages |
requires.env_vars |
all .py files |
os.getenv(...) and os.environ[...] calls |
requires.signals |
signals.py |
connect_signal() calls in signals.py |
The developer’s description field is preserved across releases. Everything else is regenerated from source.
Run splent feature:release after every meaningful change to keep the contract accurate. Other products and product:validate rely on this data.
Requirements
Environment variables:
| Variable | Purpose |
|---|---|
SPLENT_APP |
Active product (required for --attach) |
TWINE_USERNAME / PYPI_USERNAME |
PyPI authentication |
TWINE_PASSWORD / PYPI_PASSWORD |
PyPI authentication |
GITHUB_TOKEN |
Required for creating GitHub Releases and for the semver wizard to fetch the current version without rate limits |
Result
After a successful release:
- The feature contract in
pyproject.tomlis up to date. - A Git tag is pushed.
- A GitHub Release is created.
- The package is published to PyPI.
- A versioned snapshot exists in:
<workspace>/.splent_cache/features/<namespace>/<feature_name>@<version>/
If --attach is used, the feature version is also linked to the active product and recorded in splent.manifest.json with state declared.
Notes
- The feature must be in editable (non-versioned) state at workspace root. Use
feature:unlockfirst to convert a versioned snapshot. - The semver wizard fetches the latest GitHub tag to compute the next version. If no tags exist yet, it starts from
v0.0.0and suggestsv0.0.1/v0.1.0/v1.0.0. - The wizard offers patch, minor, major, and cancel. Choosing cancel aborts immediately. The wizard also ends with a
Proceed?confirmation before doing anything irreversible. - Passing an explicit
<version>skips the wizard entirely — useful in CI or when you know exactly what to release. - Build artifacts (
__pycache__,dist/,build/) are cleaned automatically before the PyPI build to prevent stale files or permission issues from causing build failures.
See also
feature:contract— infer/update contract independently (same logic used here)feature:attach— pin a released version to a productproduct:validate— compare two feature contracts before releasingfeature:status— verify state after attachingexport:puml— generate diagrams from contracts- Feature contract — contract format reference