Go Module Rename & V2 Release
Today, I’m working on a project that intends to both rename a Go module and cut a v2 release (all while keeping main as the default branch). Why do both? Essentially rebranding without losing existing links.
In any case, before attempting this level of shenanigans, I wanted to make sure that it worked (spoiler alert: it did). Below are the steps I followed that got me there using a dummy repository:
Have existing module at some v1.x.x release.
I waited until pkg.go.dev picked up the changes to be sure, but this could also be verified by querying the Go module proxy:
$ curl https://proxy.golang.org/github.com/rodaine/modulemagic@v/list v1.0.0 v1.0.1Cut a
v1branch offmainFor support reasons, we intend to still maintain the
v1.x.xreleases for any sort of bug fixes and the like, just not new features. Splitting the trunk to av1branch allows that git history to continue. Tags are independent of branches and are tied directly to a commit so this is free and has no impact on the Go module.To be on the safe side, I also set up GitHub branch protections on both
mainandv1to make sure these branches aren’t accidentally damaged. GitHub (blessedly) remembers everything, so recovery is always possible, but better to avoid that kind of “oh, s#!%” moment if you can. There’s also a beta for something called repository rulesets which lets you protect a pattern of tags or branches with similar rules provided by the branch protections. Worth checking that out as well. Don’t want someone accidentally removing or changing a tag.Create
v2in a new branch offmainThis is a temporary
v2branch for the new code, so in case we have issues getting everything squared away,mainhasn’t (yet) been polluted. Here we replace thego.modimport path with the new module name suffixed with “/v2”, and update the code accordingly. At this point, make sure CI is still functional.I would not tag the
v2.0.0release on this branch. To avoid rebase/merge situations, we only want to add tags to commits onmain(or, for legacy support, onv1). Unless we get lucky with a fast-forward, tags changing references will potentially misalign withgo.mod.sumand cause a world of hurt downstream.Rename, merge & release
v2.0.0Once satisfied with the code, use the GitHub repository settings UI to rename the repo to the new desired module name. GitHub automatically maintains redirects from the old name to the new one. Pleasantly, it maintains redirects for the entire name history of a repository. (This will be the third rename of this repository, and I strongly don’t recommend ever having to do this if you can avoid it.)
Merge the
v2branch intomain, and tag theHEADcommit asv2.0.0. You can once again verify this on the module proxy:$ curl https://proxy.golang.org/github.com/rodaine/renamedmodule/v2/@v/list v2.0.0Revel in your Go module chicanery
🎉 ~ Despite the two modules being collocated in the same repository,
go getblocks fetching the original module asv2and the new module asv1due to the name mismatch in thego.modfiles. pkg.go.dev takes its sweet time updating, but will eventually resolve the new module.