Publishing your feature

There is no upload. You release your feature in your own organisation on the forge, open one pull request to get listed, and the marketplace derives everything else from your released tag.


Table of contents

  1. 1. Make it a real SPLENT feature
  2. 2. Release it
  3. 3. Get listed
  4. 4. Publish your SPL’s model (if you maintain a line)
  5. What does not exist, on purpose

1. Make it a real SPLENT feature

The marketplace renders contracts, and contracts are generated, not written.

  • Follow the feature anatomy and its naming conventions (splent_feature_*, the src/ layout, the contract in pyproject.toml).
  • Let feature:contract --write infer [tool.splent.contract] from your code. Set the preserved fields once, description, category, tags, and requires.features_manual for dependencies static analysis cannot see. pyproject.toml lists every field.

2. Release it

The feature must be an editable checkout in your workspace. Rehearse with --dry-run first, which stops before changing anything and works in any mode. A real release ends by offering to pin the new version in the selected product, so it needs a product selected.

splent product:select my_app
splent feature:release splent_feature_billing --dry-run
splent feature:release splent_feature_billing --bump patch

feature:release bumps the version, regenerates the contract and commits both. It uploads the package to PyPI, which production builds install from, and then pushes a semver tag (vX.Y.Z) and publishes the release on the forge. PyPI goes first because a PyPI version can never be replaced. The tag is the publication. The marketplace reads your pyproject.toml at the latest released tag, never from main, so an unreleased feature is invisible and the indexer reports it.

The only credentials are your own forge and PyPI ones, SPLENT_FORGE_TOKEN plus TWINE_USERNAME and TWINE_PASSWORD, which splent env:set pypi writes for you. With a PyPI API token the username is __token__.

Situation What happens
First release of a feature It creates a new project on PyPI, which limits how many an account may create per hour. The release paces itself under that limit, waiting or stopping before anything changes. See PyPI new-project limits
A channel would refuse The release refuses to start unless both channels would accept it, so no version number is burned on a token that was going to fail
A channel fails after the other accepted release:resume publishes what is missing without bumping the version. check:releases checks the whole workspace

3. Get listed

Being indexed is a curated one-line change, like a Homebrew tap. The index is built against one forge, git.splent.io, so the repository you list must live there. Open a pull request against splent-io/splent_index adding your organisation or repository to registry.toml.

[registry]
orgs  = ["splent-io"]
repos = ["your-org/splent_feature_billing"]

Once it is merged, CI rebuilds index.json. Every later feature:release, release:resume and spl:publish asks for a rebuild as its last step, so a new version shows up within a couple of minutes, and a schedule every 6 hours catches any request that could not be sent (the build pipeline). The build runs marketplace:index, which resolves your latest semver tag, parses the contract there, and skips and reports a repository with no released tag or a broken contract. You never push data into the marketplace. The index pulls from you.

4. Publish your SPL’s model (if you maintain a line)

A product line carries a UVL model. You edit it in your own splent_spl_<name>/ repository and publish it with one command. spl:publish works on the line, not on a product, so it runs with no product selected.

splent product:deselect
splent login
splent spl:publish my_spl

This is the one thing in SPLENT that goes through the marketplace, and the reason it has a login.

you --(splent CLI, bearer token)--> MARKETPLACE --(one key)--> UVLHub

spl:publish sends the model to the marketplace, which relays it to UVLHub on its own key, mints or versions the DOI, checks the published file byte for byte against what you sent and answers with the DOI it recorded. Bytes it has already published get the same DOI back.

You never generate a UVLHub API key. The marketplace holds one for everybody, so there is no write_dataset scope to request, no UVLHUB_API_KEY to export, and no account on uvlhub.io to create.

After publishing What to know
The DOI Written into your model’s metadata.toml, and into each product with spl:pin. spl:pin works on one product, so select each in turn. Publishing moves no product onto the new version, and spl:publish names the ones still on the old one
The wait Minting a DOI waits on Zenodo and can take minutes. The marketplace answers once the release is reserved and mints in the background, and spl:publish waits, reporting progress, and records the DOI once it exists
Publishing again Always safe. The marketplace never mints two DOIs for the same bytes, and when a mint loses its answer it looks the DOI up on UVLHub instead of minting again. It settles the release only when UVLHub serves exactly your bytes. See Waiting for the DOI

The reverse direction, spl:fetch, needs no login. It downloads models by DOI from UVLHub, which is how CI and fresh workspaces get the .uvl files.

See login for where the token is stored, and whoami for which credential is in use.

What does not exist, on purpose

Missing Why
An upload form or publish API for features The index is a cache over released tags. An upload channel would be a second source of truth that drifts from your repository
An account to publish a feature The forge and PyPI are the distribution and identity layer, and feature:release is the only publish action. The marketplace login exists only to publish a model, the one operation that needs a UVLHub key
A UVLHub key of your own The marketplace holds one for everybody
Manual index edits A wrong index is fixed in a contract or a tag, then regenerated. Editing index.json would hide the bug until the next rebuild
Push-based listing A reviewed pull request keeps the registry auditable. Releasing well-formed, contracted features is the whole submission process

If your feature takes part in an SPL, run check:contracts before releasing. It checks that your contract and the UVL constraints agree on dependencies.


Back to top

splent. Distributed by an LGPL license v3. Contact us: drorganvidez@us.es