spl:publish
Publishes the UVL model of an SPL through the marketplace and records the DOI it reports. The marketplace holds one UVLHub key for everybody, so you only need splent login and never generate a key of your own. Publishing mints a DOI and moves no product.
Table of contents
Example
splent spl:publish cms_spl
Publishing cms_spl to https://marketplace.splent.io
Release 3 accepted. Minting its DOI, which usually takes a minute or two.
Still minting (30s).
DOI 10.5281/zenodo.21610307
Concept DOI 10.5281/zenodo.21610306
Version v3
File cms_spl.uvl
Checked the published file matches the model that was sent
Recorded /workspace/splent_spl_cms/metadata.toml
'cms_spl' published (DOI 10.5281/zenodo.21610307).
Run it with --dry-run first to see the model it picked, the registry it resolved and whether you are logged in.
Options
| Option | Description |
|---|---|
--registry URL |
The marketplace to publish to. Defaults to SPLENT_MARKETPLACE_URL, then https://marketplace.splent.io. |
--dry-run |
Show what would be done without touching the network or metadata.toml. |
It runs in detached mode, since the model belongs to the workspace, not to a product.
What it does
- Finds the local model (see where the model is read from).
- Sends it to the marketplace with the token
splent loginstored. - Waits for the DOI, polling every five seconds (see waiting for the DOI).
- Records the DOI in the working copy’s
metadata.toml. - Names the products that pin the model, without changing any.
- Asks for a marketplace index rebuild.
Reading a model needs no account. spl:fetch downloads it from UVLHub by DOI, and UVLHUB_URL points those reads at another instance. Nothing reads a UVLHUB_API_KEY variable.
On the marketplace
| The marketplace sees | What it does |
|---|---|
| A line it has never seen | Creates a dataset and mints a DOI |
| A line it knows | Publishes a new version of the DOI it holds |
| Bytes it has already published | Answers with that DOI, reported as idempotent |
It checks the published file byte for byte against what was sent and reports match, mismatch, pending, unknown or imported, which the command prints in plain words on the Checked line. It mints one release of a line at a time, each on top of the one before, so a second model sent while the first is minting is refused until the first settles.
Waiting for the DOI
Minting is UVLHub waiting on Zenodo, six calls in a row for a new version, which can take minutes. So the command asks the marketplace to answer as soon as the release is reserved (Prefer: respond-async) and then asks every five seconds how it is going. A marketplace that ignores the header answers once the DOI exists, and the command handles both answers.
Release 3 accepted. Minting its DOI, which usually takes a minute or two.
Still minting (30s).
Still minting (1m 00s).
| The release | What the command does |
|---|---|
| Is published | Prints the DOI and records it |
| Is refused | Says nothing was minted, prints the reason and exits 1 |
| Is still minting after 20 minutes | Stops waiting and exits 1. The marketplace carries on |
| Lost track of its mint for 5 minutes | Stops waiting and exits 1. The marketplace keeps looking for the DOI |
Nothing local is written until the release is published, so stopping early loses nothing, Ctrl+C included (exit 130).
Running the same command again is always safe. The marketplace never mints two DOIs for the same bytes. A published model is answered with its DOI, a model still minting is refused until it settles, and a model whose mint lost track is looked for first.
When a mint loses track
If UVLHub does not answer the minting call, or the marketplace restarts during it, nobody knows whether a DOI exists. The marketplace does not send the model again. It walks the versions of the line’s dataset on UVLHub, downloads every DOI it has not recorded, and settles the release as published only when the served bytes hash to the bytes you sent. It looks again each time somebody asks about the release (at most once a minute) and each time the same model is sent. An administrator can reconcile every such release at once with splent feature:spl_registry reconcile.
Where the model is read from
- The working copy,
splent_spl_<name>/<spl>.uvl. While it exists it is the only place looked at, since the cache may hold an older model and publishing it would record the new DOI next to bytes that are not there. - The cache,
.splent_cache/spls/<spl>@<version or DOI>/<spl>.uvl(plain<spl>/when the pin records neither), only when there is no working copy. This lets a machine that never authored the model push a fix.
When neither exists, the command lists every path it looked in and stops.
Only spl:publish needs the file named exactly <spl>.uvl. Every other spl:* command and product derivation accept any *.uvl in the working copy. A working copy whose model has another name is refused before any network call, --dry-run included, with exit code 1.
No cms_spl.uvl in the working copy /workspace/splent_spl_cms.
Found cms.uvl.
Rename the model to cms_spl.uvl to publish it. While a working copy exists it is what gets published, never the cache.
With no *.uvl at all, the second and third lines are replaced by this one.
Put the model there as cms_spl.uvl. While a working copy exists the cache is never published.
What it writes locally
Only the working copy’s metadata.toml, only under [spl.uvl], and only when the marketplace reports the name of the file it stored.
doiandfile, the file name the server reports, which may differ from the local one.concept_doiandversionwhen reported. Empty values are skipped, so a recorded concept DOI is never erased.
A working copy without metadata.toml gets one with the name, doi, concept_doi, version and file. The edit is text level, so comments and formatting survive. It is backed by a .bak copy, written atomically and re-parsed to confirm the values, and the original is restored on any failure.
The cache is never written, since a DOI there would be lost when the cache is cleared. Without a working copy nothing local records the DOI and the command says so. Products that derive from the line need it in their own [tool.splent.spl_model], see spl:pin.
Products are not moved
Every product keeps deriving from the version it pins. The command ends by naming them.
Products pinning this model, none of them updated here:
innosoft_app v2
diversolab_app v2
Move one forward with: splent product:select <product> && splent spl:pin cms_spl
See spl:pin and spl:outdated.
The index rebuild
The last step asks the forge to run the index build workflow, build-index.yml in splent-io/splent_index (override with SPLENT_INDEX_REPO, SPLENT_INDEX_WORKFLOW and SPLENT_INDEX_REF), so the model shows in the marketplace within minutes. It needs SPLENT_FORGE_TOKEN, or GITHUB_TOKEN, with write access to the index repository. It is best effort. Without a token, or when the forge refuses, a yellow index line says the index will catch up on its own schedule, and the publication still succeeds.
Special cases
| Situation | What happens |
|---|---|
| No local model | Every candidate path is listed, with how to create or fetch one |
| Not logged in | Refused before sending anything, pointing at splent login |
| Token expired or revoked | Reported, and the stored credential is dropped so the next run says “not logged in”. A token from SPLENT_MARKETPLACE_TOKEN is only reported, since the CLI does not manage it |
| Publishing switched off on that marketplace | Reported apart from a server error, since retrying will not help |
| Another release of the line still minting | Refused until it settles |
| Published but no DOI reported | A failure, since nothing usable came back |
| The DOI cannot be recorded | The DOI is minted, so the command prints what to record by hand under [spl.uvl] and exits 0 |
| Upload sent, no answer within 60 seconds | Not reported as unreachable, since the release may have completed. Publishing again is safe |
The DOI could not be recorded in /workspace/splent_spl_cms/metadata.toml (<reason>).
Record it by hand under [spl.uvl] in that file.
doi = "10.5281/zenodo.21610307"
file = "cms_spl.uvl"
concept_doi = "10.5281/zenodo.21610306"
version = "v3"
The concept_doi and version lines appear only when the marketplace reported them.
Unexpected marketplace error (no status).
The upload of cms_spl was sent to the marketplace at https://marketplace.splent.io but no answer came back within 60 seconds. The release may have completed. Publishing the same model again is safe. The marketplace answers it with the DOI it minted and never mints a second one.
Retry the command, and report it if it happens again.
See also
spl:fetchreads a model by DOI, with no account.spl:pinmoves a product onto the new model.spl:outdatedlists the products that fell behind.