tagsmith tag
Resolves a release version, creates an annotated Git tag at HEAD, and optionally pushes it.
Synopsis
tagsmith tag --channel <name> --bump <type>
tagsmith tag --channel <name> --version <semver>
tagsmith tag --target <name> --channel <name> --bump <type>
tagsmith tag --target <name> --channel <name> --bump <type> --push
tagsmith tag --target <name> --channel <name> --bump <type> --dry-run --jsonFlags
| Flag | Required | Description |
|---|---|---|
--target <name> | required when config has multiple targets; optional with single target | Selects the target. |
--channel <name> | required | Selects the channel. Must exist in the target's channel set. |
--bump <type> | one of --bump/--version required | major, minor, patch, or prerelease. Stable channels reject prerelease. |
--version <semver> | one of --bump/--version required | Explicit canonical SemVer. Must match the channel's shape. |
--dry-run | optional | Runs full preflight and skips create/push. |
--push | optional | After local create, pushes to git.remote and verifies. |
--json | optional | Machine output. See Output modes. |
--bump and --version are mutually exclusive. --github-output is not accepted on tag. --verbose is human-only.
Behavior
In order:
- Discover repo, load config, validate target paths.
- Run preflight: working tree clean, read local/remote tags, read remote base branch tip, read HEAD, HEAD equals remote tip.
- Resolve version against managed tag history. See Versioning.
- Validate
dependsOnfor the resolved version's base. - Render
tagPatternandtagMessage. - Create the annotated tag at
HEAD(skipped on--dry-run). - If
--push: push togit.remote, then re-read remote tags to verify annotation and peel (skipped on--dry-run).
Resolving version
| Channel strategy | --bump major | --bump minor | --bump patch | --bump prerelease |
|---|---|---|---|---|
stable | next major from latest stable | next minor from latest stable | next patch from latest stable | rejected |
prerelease | new line at <bumped-base>-<channel>.1 | new line at <bumped-base>-<channel>.1 | new line at <bumped-base>-<channel>.1 | continues highest same-channel line: N → N+1 |
If no stable tag exists yet, bumps resolve from initialVersion. --bump prerelease fails if no same-channel prerelease exists; start a line with --bump major|minor|patch or --version.
See Versioning for the full rules and worked examples.
Single-target auto-selection
When the config has exactly one target, --target is optional. With multiple targets and no --target, Tagsmith fails with tag requires --target when config has multiple targets.
Interactive flow
In an eligible TTY (no --json, no CI, etc.) Tagsmith fills omissions only:
- Resolves Git repo, loads config, validates target paths.
- Selects target — automatic if single-target; prompts if
--targetis missing and multiple targets exist. - Selects channel — automatic if single channel; prompts if
--channelis missing and multiple channels exist. - Prompts for version intent if neither
--bumpnor--versionwas given:- "bump" → choose
major | minor | patch | prerelease(filtered by strategy;stablechannels show only the first three). - "explicit version" → enter a SemVer literal with strategy-shaped hints.
- "bump" → choose
- Runs full preflight.
- Shows a review screen with target, channel, strategy, version intent, resolved version, rendered tag, rendered annotated message, full commit SHA, and the equivalent non-interactive command.
- Asks for confirmation:
- Without
--push: "local create" / "create and push" / "no action". Default: local create. - With
--push: confirm or cancel. Default: cancel (safe-negative).
- Without
- Executes the chosen action.
Cancellation (Ctrl+C or selecting the safe-negative) exits 1 with tagsmith failed: tagsmith cancelled. and no mutation.
Even when all flags are supplied, the review/confirmation still runs in interactive mode. That's intentional. In non-interactive mode (CI, machine output, non-TTY), Tagsmith executes without confirmation as long as preflight passes.
Output
tag --json and tag --dry-run --json share the same 11-key shape — see Output modes.
Human-mode success after create:
Tagged v1.2.3 (1.2.3) for target app channel stable.
Commit: 012345678901
Created: yes
Pushed: yesHuman-mode dry-run:
Resolved v1.2.3 (1.2.3) for target app channel stable.
Commit: 0123456789abcdef0123456789abcdef01234567
Dry run: No tag was created.
Because --push was provided, Tagsmith would have pushed the tag.Errors
The most common tag failures:
working tree must be clean before taggingHEAD must equal <remote>/<baseBranch> (<sha>) before taggingCannot bump prerelease for <target> <channel>: no existing <channel> prerelease tag found. …stable channel <name> rejects --bump prereleaselocal tag <tag> exists but was not pushed: <git-error>push verification failed for <tag>: remote tag does not peel to <commit>. Local tag remains.
See Error catalogue for the full list. Tagsmith does not roll back the local tag on push failure.