Recently we were working on migrating our backend repo to use go modules. Now given the size of our repo this was a huge change that involved changing almost every .go file in the repo. We managed to make this change in a safe manner keeping master green and this post explains how we did this using Github and CircleCI.

The hard part of changes like this are mostly around communication. Before your breaking change, you don't want other engineers merging a change, since this means you will need to rebase. Once you merge your change you want to force engineers to rebase since if they submit the PR with the old checks, master will be broken.

The first part was getting the change ready. This turned out to be programmatic changes but involved removing our vendor directory and changing hundreds of files. Once we had the change we added a job to our CircleCI build pipelines contains-go-mod which was a dummy job that did absolutely nothing. Once the pull request was reviewed we did the following

Added contains-go-mod as a required check to the master branch. This meant that no other PR could be merged to master. Of course we posted to the #eng channel on slack and told everyone why they were blocked. You can find branch protection rules for a repo here https://github.com/ORGNAME/REPO/settings/branches

Status checks for our repo showing contains-go-mod

Once this was done, we rebased and merged our PR. Now all engineers could merge to master, if they rebased / merged master into their branch. We kept this dummy job around for ~a week or two till all old PRs were merged in.

This way we managed to keep master green while making sure everyone was forced to merge master. Sure constant posts on slack and emails could work too, but invariably there will be that one person who misses that notification or merged before they saw it.