# git tag Command: Create Tags in CI

> git tag creates and lists tags. Reference for -a annotated tags and -l listing, used to cut releases and discover versions in CI pipelines.

Source: https://latchkey.dev/learn/command-reference/git-tag-command-reference  
Updated: 2026-06-26

git tag marks specific commits with a name, typically a release version.

Release pipelines create tags to freeze a version and list tags to discover the latest release. Annotated tags carry metadata and are preferred for releases.

## Common flags

- `-a <name>` - create an annotated tag (stored as a full object with author and message)
- `-m <msg>` - supply the tag message (required for -a in non-interactive CI)
- `-l <pattern>` / `--list` - list tags, optionally filtered by a glob
- `--sort=-version:refname` - sort tags by version, newest first
- `-d <name>` - delete a local tag
- `-f` - replace an existing tag of the same name

## Example

```shell
# Cut an annotated release tag from CI
git tag -a "v${VERSION}" -m "Release v${VERSION}"
git push origin "v${VERSION}"
# Find the latest semver tag
git tag -l 'v*' --sort=-version:refname | head -n1
```

## In CI

Always pass -m with -a so tag creation does not block on an editor on a headless runner. Use --sort=-version:refname to find the newest version reliably instead of relying on creation order. Remember to push tags explicitly; a normal push does not send them.

## Using this in CI

CI checkouts are shallow and detached by default, which changes the answer this command gives you. Commands that read history, branch names, or tags need the checkout configured for it.

```.github/workflows/ci.yml
- uses: actions/checkout@v4
  with:
    fetch-depth: 0   # history, tags, and git describe all need this

- run: |
    git rev-parse --is-shallow-repository   # expect false
    git rev-parse --abbrev-ref HEAD          # prints HEAD when detached
```

> `git rev-parse --abbrev-ref HEAD` returns the literal string `HEAD` on a detached checkout rather than a branch name. On GitHub Actions read `github.ref_name` instead; the git command cannot know what it was checked out for.

## FAQ

### git tag Command: Create Tags in CI?

Release pipelines create tags to freeze a version and list tags to discover the latest release. Annotated tags carry metadata and are preferred for releases.

### In CI?

Always pass -m with -a so tag creation does not block on an editor on a headless runner. Use --sort=-version:refname to find the newest version reliably instead of relying on creation order. Remember to push tags explicitly; a normal push does not send them.

---

Latchkey runs CI/CD that repairs its own failures. Agent entry points: https://latchkey.dev/agent.txt, https://latchkey.dev/openapi.json, https://latchkey.dev/llms.txt
