On this page
Staging: a candidate used for real before it reaches a live account
A release that passes its gates and is published can still stop the people who use it: a hook catalogue that refuses every tool call of an agent session, a service that starts and serves nothing, a CLI whose first command refuses the configuration every account already has. Gates read the source and run its tests; none of them runs the candidate the way an account will. Staging does: before any delivery reaches a live account, the published candidate is installed into an account of its own on a fleet host and used there by the product's own journeys, and only a staging whose journeys passed lets the live deliveries run.
Stado places the delivery on a host, makes the staging account, installs the candidate there with the product's live installer, runs the journeys the product's manifest declares in that account, keeps the deliveries after it waiting and keeps the receipt. A journey is a program of the released source that uses the installed candidate as its users do; the product says what its journeys are, and its exit status is the journey's answer.
Declared as a delivery
Staging is one delivery of the manifest, and every delivery that reaches a
live account names it in after, so it is queued only once staging passed
(Publication and deliveries):
"deliveries": [
{"name": "staging", "platform": "darwin-arm64", "required": true,
"argv": ["stado", "release", "stage", "--install", "operator-account"]},
{"name": "operator-account", "platform": "darwin-arm64", "required": true,
"after": ["staging"],
"argv": ["stado", "release", "local", "install", "--member", "bin/tool"]}
],
"staging": {"journeys": [
{"name": "first-run", "argv": ["tests/staging/first-run.sh"]}
]}
--install names the live delivery whose program installs the product on an
account: every product installs itself its own way, and staging runs exactly
that program, so what is staged is what the account will get. It names a
delivery of the same manifest that declares after: ["staging"]; any other
name is refused by stado release stage before anything is
installed (install-unknown below).
staging.journeys lists the product's journeys in the order they run: each
has a name and an argv, run from the exported source.
What stado release stage does
The queue places the job on a host of the delivery's platform, and the
delivery worker runs it as it runs every delivery: in the exported source, with
WISENT_RELEASE_ARCHIVE and WISENT_RELEASE_SHA256 naming the candidate's
archive, WISENT_PRODUCT, WISENT_VERSION, WISENT_PLATFORM,
WISENT_SOURCE_DIR and WISENT_OUTPUT_DIR. There
stado release stage:
- makes the staging account
<WISENT_OUTPUT_DIR>/staging/home, owner-only and empty; - runs the
--installdelivery's program from the exported source with the same variables,HOMEandWISENT_STAGING_HOMEset to the staging home and itsbin,.local/binand.stado/binleadingPATH, so the candidate is placed, signed and linked exactly as it will be on a live account and nothing of the host's own accounts is read or written; its output is kept in<WISENT_OUTPUT_DIR>/staging/install.log; - runs each journey of
staging.journeysin order, the same way, its output kept in<WISENT_OUTPUT_DIR>/staging/<name>.log; a journey that fails or cannot be started stops the journeys after it, and a failed install runs none; - removes the staging home;
- writes
<WISENT_OUTPUT_DIR>/staging-receipt.json: the product, version, platform, archive digest,passed,staging_home_removed, the install and each journey that ran as{name, argv, exit, ended, started_at, ended_at, log}. It exits 0 only when the install and every journey exited 0 and the staging home was removed, printingstaged <product> <version> <platform>: installed by <delivery> and used by <n> journey(s); receipt <path>, and the delivery passes on that, as every delivery does.
What the manifest is held to
stado release submit, and every command that reads the manifest,
holds staging to these rules before anything is built:
- a delivery named
stagingneedsstaging.journeys, since without the product's journeys every candidate would pass; staging.journeysneeds a delivery namedstaging, since no other delivery runs them;- there is at least one journey, each with a unique name of letters, digits,
.,_and-, and a non-emptyargv.
Refusals
| Cause | Meaning |
|---|---|
stado.release.stage.outside-delivery |
a variable the delivery worker sets (WISENT_RELEASE_ARCHIVE, WISENT_SOURCE_DIR, WISENT_OUTPUT_DIR, …) is unset or empty, naming it: the command runs as a delivery, not by hand |
stado.release.stage.manifest-unread |
the exported source's .wisent-release.json could not be read as JSON, naming the path and the error |
stado.release.stage.install-unknown |
--install names no delivery of the manifest, or one that does not declare after: ["staging"], naming the deliveries after staging and every delivery the manifest declares |
stado.release.stage.no-journey |
the manifest's staging.journeys lists no journey, or one without a valid name or a non-empty argv; nothing was installed |
stado.release.stage.home-unmade |
the staging home could not be made owner-only and empty on this host, naming the path and the system's answer; nothing was installed |
stado.release.stage.install-failed |
the candidate's installer could not start or did not exit 0 in the staging account, with what it said last and where its output is kept; no journey ran |
stado.release.stage.journey-unstarted |
a journey's program could not be started, naming the journey, the program and the error; the journeys after it did not run |
stado.release.stage.journey-failed |
a journey exited non-zero or was ended by a signal using the staged candidate, naming the journey, how it ended and where its output is kept; the journeys after it did not run |
stado.release.stage.home-unremoved |
the candidate passed, but the staging home could not be removed, naming the path and the error; the receipt says staging_home_removed: false and the delivery fails, since the host keeps an account the release made |
stado.release.stage.receipt-unwritten |
the receipt could not be written, naming the path; the delivery is failed, as one with no receipt is |
stado errors show stado.release.stage lists the same causes with
their remedies and the test that provokes each.
Every refusal leaves the live accounts untouched: the deliveries that name
staging in after are recorded not queued: delivery staging did not pass,
and a required staging that did not pass fails the release run, as every
required delivery's failure does.
Real tests
tests/release/staging.rs runs the real stado release stage as the
delivery worker runs it, in an exported source of the case's own with the
variables the worker sets naming a real archive. The fixture product installs
itself by unpacking its archive into $HOME, and its journeys run the
installed program. A candidate whose journeys pass is staged and its receipt
says so; a failing journey stops the journeys after it; a failing install
stops every journey; each refusal of stado.release.stage is provoked. The
process's own HOME is a directory of the case, read back empty after every
case. tests/release/staging_manifest.rs holds manifests to the rules above
through the real stado quality format. Queuing the deliveries after
staging only once it passes is the release's ordering of after, which
Publication and deliveries describes.
Source: this website