Automate Updating Major Release Tag on New Releases of a GitHub Action
Tags: github, devops, tutorial, programming
Published: 2023-01-11 15:35:07

I maintain several GitHub Actions, such as [jacoco-badge-generator](https://github.com/cicirello/jacoco-badge-generator), [generate-sitemap](https://github.com/cicirello/generate-sitemap), [javadoc-cleanup](https://github.com/cicirello/javadoc-cleanup), and [user-statistician](https://github.com/cicirello/user-statistician). I've also written posts here on DEV about each of these if you'd like more information. GitHub's documentation for GitHub Action developers recommends [maintaining a major release tag](https://docs.github.com/en/actions/creating-actions/about-custom-actions#using-tags-for-release-management) for the Action so that users can either reference the Action by its specific release tag, such as `v1.2.3`, or simply by the major release with `v1`. In fact, it is so commonplace that users will likely assume that your Action supports specifying full version tag or major tag only. Note that some Actions use major release branches (e.g., branch named `v1`) instead of tags. My intention in this post is not to discuss the advantages/disadvantages of each of these alternative approaches. In the Actions that I maintain, I use major release tags for the simple reason that it is what GitHub's documentation recommends.

It is important to ensure that the major release tags are consistent with the released versions of the Action. For example, if the current version is `v1.2.3`, then the major release tag `v1` should point to the git ref of version `v1.2.3`. And if a new version `v1.2.4` is released, then `v1` should be updated to point to that new version. Whenever a new major version is released, such as `v2.0.0`, you'd want to introduce a corresponding major tag `v2`. It would be tedious to update the major release tags manually, as well as error prone (e.g., forgetting about it, etc). In this post, I explain how to automate the creation and update of a major release tag using GitHub Actions.

__Table of Contents:__
* [How to Reference an Action in a Workflow](#how-to-reference-an-action-in-a-workflow)
* [GitHub Actions Release Tags](#github-actions-release-tags)
* [A Workflow for Maintaining Major Release Tags](#a-workflow-for-maintaining-major-release-tags)
* [Information About Actions I Maintain](#information-about-actions-i-maintain)
* [Where You Can Find Me](#where-you-can-find-me)


## How to Reference an Action in a Workflow

You can skip this section if you are familiar with using GitHub Actions. In a GitHub Actions workflow, there are several ways of referencing an Action that you want to run as one of the steps in your workflow. All of which utilize the user name or organization name of the owner of the Action, as well as the name of the repository of the Action. You then need either a tag, branch, or the full SHA of a commit, such as the following examples:

```YAML
    steps:

    - uses: user-or-organization/repository-of-action@tag

    - uses: user-or-organization/repository-of-action@branch

    - uses: user-or-organization/repository-of-action@full-sha-of-commit
```

The above examples assume that the Action has no inputs. It is meant as a simple example of referencing an Action in a workflow.


## GitHub Actions Release Tags

When you release an Action to the GitHub Marketplace to make it easy for others to discover and use in their own workflows, you must tag the release. GitHub's documentation recommends using [Semantic Versioning](https://docs.npmjs.com/about-semantic-versioning), and they also recommend [maintaining a major release tag](https://docs.github.com/en/actions/creating-actions/about-custom-actions#using-tags-for-release-management). 

In this way, if your latest release is `v1.2.3`, users can use it in a workflow with something like:

```YAML
    steps:

    - uses: user-or-organization/repository-of-action@v1.2.3
```

Or they can use the following if they want to use the major release tag so that they automatically get non-breaking changes when you release a new version:

```YAML
    steps:

    - uses: user-or-organization/repository-of-action@v1
```

But this only works if a `v1` tag exists.


## A Workflow for Maintaining Major Release Tags

Maintaining a major release tag manually will almost certainly lead to problems (e.g., you might forget to update it). So just automate it in GitHub Actions. Here is a workflow that will accomplish this. Start by creating a `major-release-num.yml` file (or whatever you want to name it) within your `.github/workflows` directory. Include the following in that file (put your name and GitHub username in the appropriate places):

```YAML
name: Move Major Release Tag

on:
  release:
    types: [created]

jobs:
  movetag:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3

    - name: Get major version num and update tag
      run: |
        VERSION=${GITHUB_REF#refs/tags/}
        MAJOR=${VERSION%%.*}
        git config --global user.name 'YOUR NAME'
        git config --global user.email 'USERNAME@users.noreply.github.com'
        git tag -fa ${MAJOR} -m "Update major version tag"
        git push origin ${MAJOR} --force
```

The above workflow runs whenever you create a new release. It gets the release tag from the `GITHUB_REF` environment variable, and sets `MAJOR` to the part of that tag prior to the first dot. If it is a new major version, then a new major release tag is created; and otherwise it is updated to reference the latest release.

The above workflow is derived from one of my projects. See [major-release-num.yml](https://github.com/cicirello/jacoco-badge-generator/blob/main/.github/workflows/major-release-num.yml) for the original workflow.


## Information About Actions I Maintain

If you'd like to learn more about the various GitHub Actions that I maintain, I have a website about them:

{% embed https://actions.cicirello.org %}


## Where You Can Find Me

Follow me here on DEV:

{% user cicirello %}

Follow me on GitHub:

{% github cicirello/cicirello %}

Or visit my website:

{% embed https://www.cicirello.org/ %}