September 19, 2020
Update: Configuring Gitlab CI and Private Go Modules
Just a few weeks ago I was lucky to work on migrating a few of our enterprise microservices to Go modules, I faced a few roadblocks and learned a lot about internals of Go Modules as well as Gitlab, in the end all the time invested was really worth it.
Historically we have been using, and recommending, both dep and retool as tools for managing dependencies, packages and tools respectively. However with the official introduction of Go Modules, sadly, both tools became instantly deprecated.
Specifically, we depend on the following Go tools for generating our code, testing it, linting it and releasing it:
- Linters
- Code generators
- Testing:
- go-junit-report: for generating JUnit XML-compatible file from a Go code coverage artifact,
- gocovermerge: for merging multiple code coverage outputs,
- migrate: for database migrations,
- go-semrel-gitlab: for generating Gitlab Releases.
Thankfully all those projects were already migrated to Go Modules so depending on them was really easy. I followed the recommended tools.go
paradigm and indicated a recent version, we had no issues.
One important thing we had to do regarding our internal private packages was to use git config
for making sure go get
was using SSH instead of https
when cloning the repositories, something like the following should be enough:
git config --global url."git@gitlab.private:".insteadOf "https://gitlab.private/"
Besides that because we use a self-hosted Gitlab and Gitlab CI instance, and the way we structure our projects follows a pattern like this: <project name>/<team>/<service>
, we had to explicitly use go 1.13.3 because having subprojects was an issue. Another important thing we needed to do was to define a replace
instruction in go.mod
to explicitly indicate the repository using the .git
hack, something like the following:
require (
private.gitlab.instance/project/team/service-name v1.0.0
)
replace (
private.gitlab.instance/project/team/service-name => private.gitlab.instance/project/team/service-name.git v1.0.0
)
And finally we introduced direnv
to our workflow, this is so when we install our tools those are relative to the project we are working on, a simple .envrc
with the following content is enough:
PATH_add bin
export GOBIN=$PWD/bin
Migrating to Go modules is a simple process after 1.13.3.