Updating untagged Go dependencies
I recently discovered that GitHub's dependabot does not automatically update Go dependencies referenced by commit. This is unfortunate as when you have multiple GitHub repos it's nice to rely on dependabot to keep your dependencies up to date.
As a result, I was looking for a workaround. What I came up with so far is a small tool and an accompanying GitHub Action that can look for these dependencies being out of date. I've called it check-untagged-go-deps. Note I am not suggesting this tool as a great solution as it is simplistic and likely will not handle many edge cases. However I think it will be adequate for repos I work with.
What are these dependencies?
The dependencies I'm talking about are in go.mod files and look like
this:
require ( github.com/maxmind/mmdbwriter v1.1.1-0.20251212174813-0dd562e0096e go4.org/netipx v0.0.0-20231129151722-fdeea329fbba )
As opposed to those referenced by a version tag:
require ( github.com/stretchr/testify v1.11.1 )
Go calls the first pseudo-versions.
Happily many modules today do tag releases, so having this kind of dependency is not very common. If you have a dependency that doesn't have a version tag, it is usually an older or less maintained dependency. Or you may need a more bleeding edge version of the module that isn't released yet. Whatever the reason, sometimes these are not easily avoidable.
If you're like me, typically you want your projects to have the latest version of their dependencies. This is nice for both security as well as not falling behind in features and compatibility.
How my tool works
check-untagged-go-deps reads go.mod and looks for these dependencies.
Then it uses go list -m -json example.com/sample/module@main to see if
there are new commits. If there are, right now it exits with a failure so
you can notice and address it. In the future it may make sense to have the
GitHub Action create a pull request updating the dependency, but I went
with exiting with a failure for simplicity. Note I realize main can vary.
Right now the tool is simplistic in its assumptions.
One notable aspect is that the tool parses go.mod. You might wonder
whether we could use go list -m -json all rather than parsing this file.
I found that the go list command lists transitive dependencies not listed
in go.mod, so go.mod seemed preferable.
You might also wonder whether we could run go get -u -t ./... and report
if any dependencies referenced by commit were updated. I found that go
get will update these dependencies if there is no version for the module
at all (e.g. a dependency that never tagged a release), but it won't do so
if the module has tagged a release.
For example, consider go4.org/netipx:
$ grep netipx go.mod go4.org/netipx v0.0.0-20230824141953-6213f710f925 $ go get -u -t ./... go: upgraded go4.org/netipx v0.0.0-20230824141953-6213f710f925 => v0.0.0-20231129151722-fdeea329fbba
We were able to update that module. But consider
github.com/maxmind/mmdbwriter:
$ grep mmdbwriter go.mod github.com/maxmind/mmdbwriter v1.1.1-0.20251212174813-0dd562e0096e $ go get -u -t ./... $ grep mmdbwriter go.mod github.com/maxmind/mmdbwriter v1.1.1-0.20251212174813-0dd562e0096e
This module wasn't updated even though there are newer commits in its
main.
check-untagged-go-deps handles both of these. Hopefully one day
dependabot will get updated to handle this and check-untagged-go-deps
won't be needed.