Skip to main content
Version: Next

Alias tags

A package gets one release tag. dispat writes it using the package's tagFormat. In a monorepo that tag usually carries a path prefix to show which package released and which version:

services/dispat/v1.4.2

That is the right name for a record, but it is the wrong name for a pointer. Consumers often want to follow a release line instead of naming an exact version. A GitHub Action is the clearest example because the Marketplace only accepts this ref shape:

uses: yohimik/dispat@v1

Use aliasTags to give a package extra names beside its real tag. Every release writes all of them.

{
"packages": {
"dispat": {
"aliasTags": [
{ "format": "v{version}" },
{ "format": "v{major}", "moving": true, "channels": ["stable"] }
]
}
}
}

A release of dispat 1.4.2 now writes three refs at the same commit: services/dispat/v1.4.2, v1.4.2 and v1. dispat writes the first two once and never touches them again. It re-points v1 on every stable 1.x release, so @v1 always means the newest 1.x version.

Options

KeyDefaultMeaning
formatrequiredThe template. See Placeholders.
movingfalseRe-point the alias on every matching release instead of writing it once.
channelsevery channelOnly write the alias for releases on these channels.
forcecommit.forceWhether this alias may overwrite an existing ref. A moving alias cannot set this to false.

You can set aliasTags at the repository level, on a space, in a space folder's config file, and on a package. This works exactly like tagFormat. A list declared at a nearer level replaces the inherited one, so a package opts out of its space's aliases with an empty list:

{ "packages": { "internal-tool": { "aliasTags": [] } } }

Placeholders

format accepts everything tagFormat accepts, plus the three parts of the version on their own:

PlaceholderExample
{name}dispat
{version}1.4.2
{major}1
{minor}4
{patch}2
{channel}rc
{counter}1

{major}, {minor} and {patch} are available only here. A release tag must be readable back into the version that produced it. Because v1 names no release in particular, dispat refuses a tagFormat that uses these placeholders at load.

A format must name some part of the version. If it does not, every release of every package writes the same ref. latest is not a valid alias for that reason.

Channels

Use channels to restrict a moving alias. Without it, v1 follows whatever released last, including release candidates. A project publishing 1.5.0-rc.1 would move v1 onto a prerelease, and every consumer pinning @v1 would receive it.

{ "format": "v{major}", "moving": true, "channels": ["stable"] }

Now v1 only ever follows stable releases. A prerelease still gets its own exact alias if you configure one. This means uses: yohimik/dispat@v1.5.0-rc.1 works for anyone testing it, while v1 stays where it was.

The channels field takes the same values everywhere it appears in the configuration file. Naming nothing selects every release, stable selects the stable line, and * selects any prerelease. A bare name like beta selects that specific channel and ignores case. You also use this field to configure which channels record and which releases a changelog line reaches.

Aliases are never read back

dispat finds a package's history by listing the tags its tagFormat matches. It writes aliases but never reads them, so they take no part in that history.

This distinction is load-bearing, and dispat enforces it. If dispat could read an alias back as a release tag, the next run would find it while looking for the package's baseline. A moving alias is always the newest tag by creation date, so dispat would find it first:

  • A bare v1 does not parse as a version. An unreadable newest tag makes the whole baseline unreadable, so the package looks like it never released.
  • A bare v1.4.2 does parse. It quietly becomes some package's released version.

dispat refuses the configuration at load if any package's alias matches any package's tagFormat:

config: package "dispat": alias tag "v1.4.2" would be read back as a release tag of package "cli"
(tagFormat "v{version}"); an alias must never be readable as a release tag, or it becomes that package's history

The same check refuses two packages that write the same alias name. A shared-version group would trigger this if every member declared v{major}.

If your packages tag as {name}@{version} and you want bare aliases, give the aliases their own prefix (action-v{major}). Alternatively, give the packages a path-prefixed tagFormat.

Failures

An alias is a convenience ref, not the record of a release. If dispat cannot write one, it warns (W232) and carries on because the release tag is already there. You or the next release can re-point the alias later, which differs from the release tag itself, where a failure is a critical.

Pushing

dispat pushes aliases with the release tags, so it never leaves behind a ref nobody can fetch. A moving alias needs to replace the copy the remote already has. This is what commit.force does, and it is why the flag defaults to on.