Releases and environments
A source release is an immutable snapshot of your configuration directory in object storage. An environment is a named pointer, such as staging or production, to one release. Hosts running rivet run follow an environment. Promoting a release changes what they apply on their next run.
Hosts get a catalog from a release in one of two ways:
If acquisition fails, the run stops. Rivet never switches modes or silently uses an older catalog.
Publish and promote
Stores are gs://bucket/prefix, s3://bucket/prefix, or file:///absolute/directory for local testing. Cloud stores use the standard credential chains. Give publishers write access and give hosts and the compile service separate read-only identities.
Keep agent and server configuration files out of the published directory: every top-level *.hcl file there is compiled as configuration.
Publishing copies regular files, skips .git, and refuses symlinks and special files. Objects are written only if absent, and the release index goes last, so a half-finished upload never looks like a release. Publishing identical content again gives the same digest.
Promoting first checks that every file in the release is present with the right size and SHA-256, then updates the environment pointer conditionally. If another promotion happened since you read the pointer, yours fails rather than overwriting it. --expected-generation N adds an explicit check: 0 requires a new environment, and a positive value requires that exact current generation. Each run reads the pointer once, so a promotion during a run doesn’t affect it.
Rolling back is promoting an older release. That changes what future runs apply; it doesn’t undo changes already made to hosts.
Environment names are 1 to 128 ASCII letters, digits, underscores, or hyphens.
Check a release before promoting
Without --facts, release validate uses the built-in Ubuntu baseline. Neither command touches a managed host.
What a release can contain
Releases include the top-level *.hcl files and the resource assets they reference. They don’t support:
- Modules, local or remote.
- Other files read by
file()ortemplatefile(). --vars-fileor data hierarchies, so every variable needs a default.
Inline templates and functions that don’t read other files work as usual. Use direct compilation when you need the unsupported features.
Storage layout
For a store ending in /site:
release.json lists every file with its SHA-256 and size, and its own digest identifies the release. An environment file holds a release digest and a promotion generation. Hosts read files through the index rather than listing the bucket.
Digests prove the files match the index, but not who wrote the index. Anyone who can write to the store can publish and promote. Releases aren’t signed, so treat storage write access as the trust boundary.
How hosts prepare a catalog
Before the runner starts, the host fetches every asset the catalog needs, verifies each size and SHA-256, and caches them under its private cache directory. A missing or mismatched asset stops the run before any change. The runner itself never downloads anything; apt repositories are the only network dependency during apply.
The cache reuses unchanged files across releases. Releases and cached files are kept forever; there’s no garbage collection yet.
See agent runs to set up hosts, and testing for how releases are tested.