Releasing with multi-level version tagging

Sam Smith's avatarPosted by

Have you ever used an action and noticed that are multiple versions available to use? Sometimes you see v1.3.2, other times there will be v1.3.2 ,v1.3 , and v1. The reason for this is simple- sometimes you want to accept all patch, or all minor versions when you consume a package. Referencingv1.1 is convenient for users as they won’t have to update each individual patch version.

Today, we are going to update our workflows to achieve this result. The way this works is to create multiple tags (versions), and associate your releases with them. When another patch or minor version is released, you update the major version release with that tag, so that downstream, the user picks it up again.

First let’s look at how we release code today. We prefer to use the ncipollo/release-action, action. We pass the action a tag, a release name, and a GitHub token. We typically run this on every main branch update – so that a release is created after any code merges to the main trunk.

    - name: Create Release
uses: ncipollo/release-action@v1
with:
tag: "v${{ needs.build.outputs.Version }}"
name: "v${{ needs.build.outputs.Version }}"
token: ${{ secrets.GITHUB_TOKEN }}

The disadvantage of this is that workflows that depend on these actions are constantly asked to upgrade to include any bug fixes. Dependabot is great, until you are overwhelmed, and stop accepting the updates – which can cause security issues!

Now if we can automate the creation of major and minor updates, by creating additional releases with the major and minor versions. For example, to create an update for the major tag, the action would look something like this.

  • Note that before we update the release for the major version, we need to update the tag, this updates the commit SHA to point to the new assets.
    - name: Update major version tag
uses: richardsimko/update-tag@v1
with:
tag_name: "v${{ needs.build.outputs.Major }}"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create Major version Release
uses: ncipollo/release-action@v1
with:
tag: "v${{ needs.build.outputs.Major }}"
name: "v${{ needs.build.outputs.Major }}"
allowUpdates: true
token: ${{ secrets.GITHUB_TOKEN }}

We can do this for the minor version too. A complete release can be viewed here.

Now in my calling workflows, I can reference the major or minor version, and roll up all of the patch versions without a Dependabot update.

Now when we call our custom action we have three options – to either specify a specific patch version, or specify a major or minor version – to roll up the patch versions without changing our workflow, and without generating a huge number of dependabot PR’s.

There is one pretty big disadvantage to this process – you should only do this if you trust the workflow you are calling – for example, I trust the actions/download-artifact action, but maybe I don’t trust a random action created by an unverified owner. Otherwise, the owner could insert some code that you would not be aware of, because you are ignoring patch versions.

In the right situation, this is a huge timesaver, improving your security and time, as long as you are vigilant with your security and use this in the right places!

Leave a comment