Skip to content
Mike Larah By Mike Larah Software Engineer II
The importance of specific & immutable dependency versions

You always want your build process to be reliable and repeatable. If you haven't made any changes, then you would expect the build you ran last year to produce identical artifacts to the build you run today.

Most dependency management tooling allows you to be loose when specifying versions for dependencies (e.g. use any version greater than version X), or if you are downloading tools and packages directly through web links often there is a link to download the latest version.

Whilst this may be useful in some scenarios (it avoids having to manually update dependency references everytime a new version becomes available), you should use caution; if you do not own the dependency being referenced, then you have no control over the changes that a new version may introduce. Fellow endjineer Carmel has previously written about the dangers of using loose version constraints with NuGet.

And even if the dependency purports to adhere to semantic versioning, there is still no guarantee that even a new patch release will not accidentally introduce a breaking change for your software.

An example of where not using specific versioning has caught me out recently is in a GitHub Actions workflow. Actions in the workflow are pulled in at runtime from GitHub repos, and can be referenced either by branch name, tag, or commit SHA. In this case, we were referencing an action by branch name, which will pull in whatever the latest version on that branch is. Since the last time the workflow ran, a major version had been published, along with breaking changes which resulted in errors in my workflow, the cause of which was not immediately obvious.

You may think then that, in this case, referencing actions by tag (which are often version numbers) would be sufficient to make the workflow impervious to change, but this is another thing to be careful with: git tags are not immutable. They can be deleted and re-created, applied to different commits. This is not unique to git / GitHub, the same is true with tagging for Docker images, and I'm sure with other systems too. Both GitHub Actions and Docker support referencing actions/images by SHA, which would ensure identical versions between runs.

So the lesson here is that if you want your build to be reliable and repeatable, then you should use specific & immutable dependency references where you can.

Mike Larah

Software Engineer II

Mike Larah

Mike is a Software Engineer at endjin with almost a decade of experience in solving business problems with technology. He has worked on a wide range of projects for clients across industries such as financial services, recruitment, and retail, with a strong focus on Azure technologies.