2025-12-24 00:59:00 +00:00

update-tags-action

Easily create/update one or more Git tags in a GitHub repository.

Latest Release GitHub Issues GitHub Pull Requests License

Generally useful for moving major (v1) and minor (v1.2) tags to same commit as the latest v1.x.x tag.

This action uses itself to move its own major and minor tags.

Examples

Basic

- uses: jimeh/update-tags-action@v2
  with:
    tags: v1,v1.2
- uses: jimeh/update-tags-action@v2
  with:
    tags: |
      v1
      v1.2

Deriving Tags from Version

Automatically derive major and minor tags from a semver version string:

- uses: jimeh/update-tags-action@v2
  with:
    derive_from: v1.2.3
    # Creates tags: v1, v1.2

With a custom template (major tag only):

- uses: jimeh/update-tags-action@v2
  with:
    derive_from: v1.2.3
    derive_from_template: '{{prefix}}{{major}}'
    # Creates tag: v1

Combine derived tags with explicit tags:

- uses: jimeh/update-tags-action@v2
  with:
    derive_from: v1.2.3
    tags: latest
    # Creates tags: latest, v1, v1.2

With Release Please

This example uses jimeh/release-please-manifest-action, but you can just as easily use the official google-github-actions/release-please-action instead.

First you'll want the workflow setup to run on push:

on: [push]

Then you'll want a release-please job which only runs on pushes to your main branch, and exposes relevant outputs from release please:

jobs:
  # [...]
  release-please:
    runs-on: ubuntu-latest
    if: ${{ github.ref == 'refs/heads/main' }}
    outputs:
      release_created: ${{ steps.release-please.outputs.release_created }}
      tag_name: ${{ steps.release-please.outputs.tag_name }}
    permissions:
      contents: write
      issues: write
      pull-requests: write
    steps:
      - uses: jimeh/release-please-manifest-action@v3
        id: release-please

And finally a job to create MAJOR and MINOR release tags, which only runs when release-please reports having created a release:

jobs:
  # [...]
  release-tags:
    runs-on: ubuntu-latest
    needs: release-please
    if: ${{ needs.release-please.outputs.release_created }}
    permissions:
      contents: write
    steps:
      - uses: jimeh/update-tags-action@v2
        with:
          derive_from: ${{ needs.release-please.outputs.tag_name }}
          # Creates tags: v1, v1.2 (for tag_name v1.2.3)

Inputs

name description required default
tags

List/CSV of tags to create/update. Supports per-tag ref and annotation overrides using the format 'tag:ref:annotation'. Use 'tag::annotation' to specify an annotation with the default ref.

false ""
derive_from

Semver version string to derive tags from (e.g., 'v1.2.3'). When provided, generates tags using derive_from_template input. Default template will produce major and minor tags. (e.g., 'v1', 'v1.2')

false ""
derive_from_template

Handlebars template for deriving tags from the derive_from input. Uses the same format as the tags input, and supports the following handlebars placeholders: {{prefix}}, {{major}}, {{minor}}, {{patch}}, {{prerelease}}, {{build}}, {{version}}.

false {{prefix}}{{major}},{{prefix}}{{major}}.{{minor}}
ref

The SHA or ref to tag. Defaults to SHA of current commit.

false ${{ github.sha }}
when_exists

What to do if the tag already exists. Must be one of 'update', 'skip', or 'fail'.

false update
annotation

Optional default annotation message for tags. If provided, creates annotated tags. If empty, creates lightweight tags. Can be overridden per-tag using the 'tag:ref:annotation' syntax in the tags input.

false ""
dry_run

If true, logs planned operations without executing them.

false false
github_token

The GitHub token to use for authentication.

false ${{ github.token }}

Tag Input Syntax

The tags input accepts a comma or newline-delimited list of tags. Each tag specification supports optional per-tag ref and annotation overrides using the format:

tag[:ref[:annotation]]
Format Description
tag Tag using default ref and annotation inputs
tag:ref Tag using specified ref, default annotation
tag:ref:annotation Tag using specified ref and annotation
tag::annotation Tag using default ref with specified annotation

Per-tag refs allow different tags to point to different commits:

- uses: jimeh/update-tags-action@v2
  with:
    tags: |
      v1:main
      v2:develop

Per-tag annotations allow different annotation messages for each tag:

- uses: jimeh/update-tags-action@v2
  with:
    tags: |
      v1:main:Latest v1.x release
      v1.2:main:Latest v1.2.x release

Use tag::annotation to specify an annotation while using the default ref:

- uses: jimeh/update-tags-action@v2
  with:
    tags: |
      v1::This is the v1 tag annotation
      v1.2::This is the v1.2 tag annotation

Per-tag values override the global ref and annotation inputs:

- uses: jimeh/update-tags-action@v2
  with:
    tags: |
      v1:main:Custom annotation for v1
      v2
    ref: develop
    annotation: Default annotation for tags without per-tag override
    # v1 -> main with "Custom annotation for v1"
    # v2 -> develop with "Default annotation..."

Annotations can contain colons (everything after the second colon is the annotation):

- uses: jimeh/update-tags-action@v2
  with:
    tags: |
      v1:main:Release: version 1.0.0
    # Annotation will be "Release: version 1.0.0"

Derive Template Syntax

The derive_from_template input uses Handlebars for template rendering. Splitting the template into separate tags by comma or newline is done after the template is rendered.

Available placeholders:

Placeholder Description
{{prefix}} v or V if input had a prefix, empty otherwise
{{major}} Major version number
{{minor}} Minor version number
{{patch}} Patch version number
{{prerelease}} Prerelease identifier (e.g., beta.1), empty if none
{{build}} Build metadata (e.g., build.123), empty if none
{{version}} Full version string without prefix

Conditional Sections

Use Handlebars {{#if}} blocks to include content only when a variable has a value. This is useful for optional components like prerelease or build metadata:

- uses: jimeh/update-tags-action@v2
  with:
    derive_from: v1.2.3-beta.1
    derive_from_template: |
      {{prefix}}{{major}}{{#if prerelease}}-{{prerelease}}{{/if}}
    # Creates tag: v1-beta.1

For a stable release without prerelease:

- uses: jimeh/update-tags-action@v2
  with:
    derive_from: v1.2.3
    derive_from_template: |
      {{prefix}}{{major}}{{#if prerelease}}-{{prerelease}}{{/if}}
    # Creates tag: v1 (prerelease section omitted)

You can also use {{#unless}} for inverse logic:

- uses: jimeh/update-tags-action@v2
  with:
    derive_from: v1.2.3
    derive_from_template: |
      {{prefix}}{{major}}{{#unless prerelease}}-stable{{/unless}}
    # Creates tag: v1-stable (only for non-prerelease versions)

Outputs

name description
tags

List of tags that were created/updated.

created

List of tags that were created.

updated

List of tags that were updated.

skipped

List of tags that were skipped.

Runs

This action is a node24 action.

License

MIT

Description
Easily create/update one or more Git tags in a GitHub repository.
Readme MIT 23 MiB
Languages
TypeScript 96.5%
JavaScript 3.1%
Ruby 0.4%