When using GitHub Actions, the default is to use the Semantic Versions for which the actions where released. Semantic versioning (SemVer) is an industry wide standard of giving meaning to the version number. SemVer always follows this setup:
Given a version number you increment the:
The goal of using SemVer is that you can then specify what you as a user of a library want to use. You can be very specific and say you want to use version
9.1.4, but also be less specific and say you want to use version
9.1. Following SemVer this means you want to use any version that matches the
9.1 MAYOR.MINOR version. This means you will get the latest version of
9.1 that is available. This is very useful when you want to use the latest version of a library, but you don’t want to have to update your code every time a new version is released. You can just specify the MAYOR.MINOR version and you will get the latest version of that version. Effectively that means that you’re saying
If version 9.1.3 is the current latest PATCH version, your package manager will download that version. If version 9.1.4 is released, your package manager will download that version. If version 9.2.0 is released, your package manager will not download that version, because it does not match the MAYOR.MINOR version you specified.
The same setup goes for the MINOR version. If you specify version
9, you will get the latest version of that MAYOR version. This means that you will get the latest version of
9.3 and so on. Effectively that means that you’re saying
The runner that executes GitHub Actions for us is open source. You can check the source code for it here. If you dive into it, you can find that the runner tries to download the version from the Action you specified:
- uses: actions/checkout@v2 --> will download the repo with TAG = v2 - uses: email@example.com --> will download the repo with TAG = v3.1.0 - uses: actions/checkout@main --> will download the repo with BRANCH = main - uses: actions/checkout@e2f20e631ae6d7dd3b768f56a5d2af784dd54791 --> will download the repo with COMMIT = e2f20e631ae6d7dd3b768f56a5d2af784dd54791 (SHA hash)
If the TAG (or branch or SHA hash) you have specified is not available in the repo, the runner will give an error saying it cannot find that version.
Now the interesting thing is what happens if you specify a semantic versioning pattern for an action. For example:
- uses: firstname.lastname@example.org
Following semantic versioning, you’d expect that this example would work. Configuring actions with a version (or tag, or hash) is required these days so the runner can find the correct reference to download. That means that the maintainer of the action MUST follow SemVer when releasing their actions, as also described in the GitHub Actions documentation. If the maintainer does not follow SemVer, the runner will not be able to find the correct version to download.
Now guess again what happens when you specify version
v3.1 for the checkout action. The runner will try to download the repo with TAG =
v3.1. But that tag does not exist! The runner will then give an error saying it cannot find that version. So the runner does not check for matching versions by itself!
- uses: email@example.com <-- this will fail!
You can find the tags for this action here and see that v3.1 is missing! So even the most used action, does not follow GitHub’s best practices!!!
Even better, the GitHub Actions Marketplace actually does not show the version from the tags: it only shows the information from Releases in the repo! That means you could be missing out on tags that where not released as a GitHub Release.
Check the tag list versus the release list shown in the marketplace:
We keep telling people to follow SemVer for a reason, but for GitHub Actions the honus is on the maintainer of the action to actually re-tag all matching versions of their action with the correct SemVer version. And apparently, even GitHub doesn’t follow along with this.
So when you have a current release
v4.2.5, you also need to re-tag that commit with the
v4.2 tag, as well as the
v4 tag. This way the runner can find the correct version to download.
jobs: job1: runs-on: ubuntu-latest steps: # works, as this is an actual tag in the repo - uses: actions/checkout@v3 job2: runs-on: ubuntu-latest steps: # works, as this is an actual tag in the repo - uses: firstname.lastname@example.org job3: runs-on: ubuntu-latest steps: # does not work, as this is NOT an actual tag in the repo - uses: email@example.com