unify docs

Template versions: pin one, move it on purpose, try the next early

Role: How to say which version of a template a project is on, change that deliberately, and try an unreleased one without committing to it. init, update and extends: take the same source forms, so one set of rules covers all three; read the templates guide first for what each does and the CLI reference for every flag. Every source literal below is classified by unify's own classifier, and the command lines in §3 run as printed, with the repository address swapped for a local git repository (tests/unit/template-versions.test.js, tests/conformance/template-versions.test.js). An npm fetch and a publish cannot run offline, so those parts are described from the code and from .github/workflows/publish-templates.yml instead.

1. What can be pinned

A source is pinned when it names one version for good. The four forms of templates.md §1 differ in how far they can be:

Source Form Same bytes every time? Cached by extends:?
docs built-in yes, under the same unify yes
unify-docs-template@0.4.0 npm yes, npm never reuses a version yes
unify-docs-template@0.5.0-next.57 npm yes, a prerelease is a version yes
https://github.com/fwdslsh/unify/templates/docs#3f2a9c1 git yes, a commit yes
https://github.com/fwdslsh/unify/templates/docs#v0.11.14 git until someone moves the tag no
https://github.com/fwdslsh/unify/templates/docs#main git no, the branch moves no
unify-docs-template npm no, it is the latest no
unify-docs-template@next npm no, a dist-tag moves no
../our-template directory no, it is whatever is on disk no, read in place

A #ref of 7 to 40 hex digits is read as a commit, anything else as a branch or tag. To see what exists: npm view unify-docs-template versions, npm view unify-docs-template dist-tags, git ls-remote --tags https://github.com/fwdslsh/unify.

2. Pin when you scaffold

Name the version in the source:

unify init unify-docs-template@0.4.0

init records the source exactly as you typed it, and unify update reads it back later (conformance-spec.md §19.10):

template:
  source: unify-docs-template@0.4.0
  keep:
    - unify.yaml
    - site/assets/theme.css

Commit it: that line is the pin.

A built-in name rides unify. unify init docs records docs, the copy embedded in the unify that ran, so its version is unify's own. Pin it by pinning unify:

npx @fwdslsh/unify@0.11.14 init docs
curl -fsSL https://raw.githubusercontent.com/fwdslsh/unify/main/install.sh | bash -s -- --version v0.11.14

The second line installs the binary at that release; UNIFY_VERSION=v0.11.14 is the same thing as an environment variable, and unify --version says which one you have. To pin a built-in apart from unify, name its package (unify-docs-template@0.4.0: the built-ins publish as unify-<name>-template, versioned on their own) or the unify release tag that holds it (https://github.com/fwdslsh/unify/templates/docs#v0.11.14, the templates/docs directory as that release shipped it).

3. Move a pin

unify update with no argument fetches the recorded source again. At a pin that is the same version, so there is nothing newer to bring in. To move, name the new source: update fetches it, lists what it would change, asks, copies, and replaces the recorded line.

unify init https://github.com/acme/templates/shop#v1
unify update https://github.com/acme/templates/shop#v2 --dry-run
unify update https://github.com/acme/templates/shop#v2
unify update https://github.com/acme/templates/shop#v2 --yes

Review the result the way templates.md §2 does (git diff, then unify build --dry-run --strict), and commit. Files you named under keep: are never overwritten, and nothing is ever removed. To go back, name the old pin; to move to a commit, put it after the #.

Moving a built-in means moving unify, because update reads the embedded copy of the unify that runs it:

npx @fwdslsh/unify@0.11.15 update --dry-run

Or move the project onto the package, which has versions of its own: unify update unify-docs-template@<version> --dry-run, then again without --dry-run. Read that list first; a package version older than your unify's embedded copy would take files back.

4. Pin what extends: builds on

extends: takes the same sources and builds on the template without copying it. Pin it the same way:

# unify.yaml
extends: unify-docs-template@0.4.0

An installed package pins through your lockfile instead: extends: node_modules/unify-docs-template (templates.md §4).

5. Try one before it ships

unify and each template have their own prerelease channel, and a git ref reaches anything else:

To try Command Where it comes from
unify, and the built-ins it embeds npx @fwdslsh/unify@next init docs a prerelease such as 0.11.15-alpha.1 publishes under npm's next; the binary is a GitHub pre-release, install.sh --version v0.11.15-alpha.1. install.sh with no version and a plain @fwdslsh/unify keep resolving to stable
a template's pending change unify init unify-docs-template@next a template whose version was bumped on a release/* branch publishes there as <version>-next.<run number> under next (§6)
anything on a branch unify init https://github.com/fwdslsh/unify/templates/docs#release/0.11.15 git: any branch, tag or commit

6. For template authors