Don't couple your Go code to GitHub
One of the good features of Go is that you namespace your code with the location
to fetch the code. This means if you host your Go code at
http://github.com/vitalvas/kasper then you have the line
import "github.com/vitalvas/kasper" and Go will fetch it using git. This makes
it super easy to know where to go to report bugs for open source libraries and
really easy to fetch and distribute go libraries without a centralised package
management system. For many, it’s literally the location of the git hosting, but
this has some downsides, and you should use your own custom domain, and I’ll
explain why.
Problem
The main problem with using your git hosting location is that your code is now coupled to a hosting provider. That is, if you move your git hosting to GitLab then you have to change your code! Otherwise, you’ll be fetching the old verison. This can result in you being unable to change git hosting provider because the amount of overhead in switching. So you literally end up with your code coupled to GitHub. Which sounds completely nuts, but it’s something that is pretty much defacto in the Go community.
I’ve seen this problem become such a huge issue for a company that were using GitLab, GitHub, and Azure Devops at the sametime because changing the location of the code was such a large task for them and they didn’t “have time” that it was easier for them to operate on three platforms. So this problem literally cost the company money since they had to pay for three hosting services at the same time.
Solution
The solution is to use custom domains such as go.vitalvas.com, go.uber.org,
go.mongodb.org, etc. This allows you to just change where those domains point
to. For example, go.vitalvas.com/kasper points to github.com/vitalvas/kasper
and if I move to GitLab nothing will change for the end users the install
command is the same.
In my opinion, every commerical software development team using Go should be using custom domains for namespacing their internal libraries and packages. As it’s an easy way to avoid any pointless coupling.
Here is a sample nginx config you can adapt for your projects.
Nginx.conf
server {
server_name go.vitalvas.com;
root /var/www/go.vitalvas.com;
index index.html;
location / {
# Check if the query string does NOT contain 'go-get=1'.
# The '~' is for a case-sensitive match.
if ($args !~ go-get=1) {
# This is a human visitor. Issue a permanent redirect to GitHub.
# $request_uri will be the path, e.g., /kasper
return 301 https://github.com/vitalvas$request_uri;
}
# If it's the Go tool (with ?go-get=1), serve the HTML file as before.
try_files $uri $uri/ =404;
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="go-import" content="go.vitalvas.com/kasper git https://github.com/vitalvas/kasper">
<meta name="go-source" content="go.vitalvas.com/kasper https://github.com/vitalvas/kasper https://github.com/vitalvas/kasper/tree/main{/dir} https://github.com/vitalvas/kasper/blob/main{/dir}/{file}#L{line}">
</head>
<body>
</body>
</html>