3.4 Templates and versions
Included from Basic tiertemplates
After this you can: create a template, pin a version to an exact revision, assign it to assets, and run the version lifecycle with its in-use protections.
Before you start — tick each one:
- Lesson 3.3 — Git remotes and the identity policy (
opschain learn 3.3)
In the GUI: the Templates tab on a project page, beside Git remotes — versions, the assets pinned to each, lock/unlock/archive.
Lesson 1.1 ended with an asset pinned to a template version; this lesson is where that version comes from. A template names which remote its content comes from, a template version pins a revision — branch, tag or commit — of that repository, and every asset pinned to a version takes its action catalog from that exact commit. By the end you will have cut a version, moved assets onto it, and seen the server refuse to pull a version out from under the assets that use it.
1. Create a template and pin its first version
Both can be made in one command, against the remote from lesson 3.3:
opschain templates create acme \
--code web_tier --name "Web Tier" \
--git-remote infra \
--version 1.0.0 --git-rev v1.0
created template acme/web_tier (01a14002-…-example)
created version 1.0.0 (ready, git rev v1.0 (0a1b2c3))
The server resolves --git-rev against the remote right away: the
version stores both the revision you asked for and the exact commit it
resolved to, so what a version means never drifts — and a commit you
rehearsed locally with --ref before pushing (lesson 2.6) is exactly
what pinned assets will run. A revision that does not exist in the
repository is a named 422 (Git rev must match a Git revision (branch/tag/commit) in the template's Git remote), not a stored
mistake.
Template codes are immutable and lowercase ([a-z0-9_]+). The
repository itself carries the template's content — its actions under
.opschain/templates/<code>/actions/ — authored exactly as lessons 2.1
and 2.4 taught, which is why a template version is "a revision of a
repo" and nothing more.
2. Assign a version to assets
Assets met templates in lesson 1.1: nodes create … --template web_tier:1.0.0 pins at creation. templates assign is the fleet move —
repoint existing assets at a version in one command:
opschain templates assign acme/web_tier --version 1.1.0 \
--asset acme/environments/dev/assets/web \
--asset acme/environments/dev/assets/api
assigned version 1.1.0 of acme/web_tier to 2 asset(s)
Each asset must already belong to this template (the server refuses a cross-template assignment by name), and you need update rights on the template and on every named asset.
How template actions reach the asset catalog. Assigning (or pinning
at creation) opens a new entry in the asset's version history and
refreshes its action catalog in the background — the server checks out
the version's pinned commit and derives the actions it declares. Until
the refresh lands, the previous catalog keeps serving, so a broken
revision never leaves an asset with no actions. From there it is
lesson 3.1's world: opschain actions list shows the catalog, and
runs create change executes from it.
opschain nodes show acme/environments/dev/assets/web # template: web_tier:1.1.0
opschain actions list --project acme --env dev --asset web # the refreshed catalog
Declarative YAML action files are the default authoring lane and run on
any runner. A template whose repository also carries an actions.rb or
a MintModel document — applicable only to existing MintPress customers
and those using the MintPress SDK or the packs:mintpress feature —
has those actions derived on a Ruby-capable runner and merged into the
same catalog, gated by the packs:mintpress entitlement per step;
opschain docs packs-mintpress covers that lane in full.
3. The version lifecycle
templates show is the lifecycle dashboard:
opschain templates show acme/web_tier
code: web_tier
id: 01a14002-…-example
project: acme
name: Web Tier
description: -
type: asset
git_remote: infra
archived: false
versions:
VERSION STATE GIT REV LOCKED ARCHIVED IN USE
1.0.0 ready v1.0 (0a1b2c3) no no -
1.1.0 ready main (9f8e7d6) no no 2 asset(s)
New versions come from version upsert — the same command updates an
existing version's revision or description:
opschain templates version upsert acme/web_tier --version 1.2.0 --git-rev release/1.2
upserted version 1.2.0 of acme/web_tier (ready, git rev release/1.2 (4c5d6e7))
opschain templates version upsert acme/web_tier --version 1.2.0 --fetch
--fetch re-resolves the stored revision against the remote — a version
pinned to a branch picks up its new head; --float makes that the
version's standing behaviour. Versions that assets are in use by are
protected: changing or fetching their revision, unlocking them, or
archiving them is refused with a named error —
opschain templates version archive acme/web_tier --version 1.1.0
Error: the server answered HTTP 422: Template version cannot be archived as the version is currently in use
— and --ignore-in-use is the deliberate override: it accepts the risk
and, for a revision change, rolls the pinned assets onto the newly
resolved commit (their catalogs refresh again).
lock is the release freeze: a locked version accepts no revision or
metadata changes until unlocked.
opschain templates version lock acme/web_tier --version 1.1.0
locked version 1.1.0 of acme/web_tier
archive retires a version from assignment without deleting anything;
unarchive brings it back. The everyday flow is: upsert the next
version → assign it → lock what production runs. The GUI's screens
ride the same calls over the v2 API (opschain docs api-v2), with the
same in-use refusals.
Check yourself
- Archive the version your assets pin: what does the server answer, and which column of
templates showtells you why before you try?
What you learned
- A template names a remote; a version pins a revision of it and stores the exact commit it resolved to, so a version never drifts.
templates assign --version … --asset …repins assets in one move and refreshes their action catalogs in the background, the old catalog serving until the new one lands.version upsertcuts or repins versions,--fetch/--floatfollow a moving branch, andlockfreezes a release.- A version in use refuses a revision change, unlock or archive by name;
--ignore-in-useis the explicit override that rolls the assets forward with it.
Next: lesson 3.5 — Secrets and the vault (opschain learn 3.5), or back to your track (opschain learn).