5

Background

At my company, we use Bit Bucket to host our git repos. All traffic to the server flows through a custom, non-standard port. Cloning from our repos looks something like git clone ssh://git@stash.company.com:9999/repo/path/name.git.

The problem

I would like to create Go modules hosted on this server and managed by go mod, however, the fact that traffic has to flow through port 9999 makes this very difficult. This is because go mod operates on the standard ports and doesn't seem to provide a way to customise ports for different modules.

My question

Is it possible to use go mod to manage Go modules hosted on a private git server with a non-standard port?

Attempted solutions

Vendoring

This seems to be the closest to offering a solution. First I go mod vendor the Go application that wants to use these Go modules, then I git submodule the Go module in the vendor/ directory. This works perfectly up to the point that a module needs to be updated or added. go mod tidy will keep failing to download or update the other Go modules because it cannot access the "git URL" of the custom Go module. Even when the -e flag is set.

Editing .gitconfig

Editing the .gitconfig to replace the URL without the port with the URL with the port is a solution that will work but is a very dirty hack. Firstly, these edits will have to be done for any new modules, and for every individual developer. Secondly, this might brake other git processes when working on these repositories.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 6
    Setup a Webserver that returns appropriate meta tags as described in https://golang.org/cmd/go/#hdr-Remote_import_paths – Peter Jun 22 '21 at 11:06
  • 1
    If you want these to be widely available, you must setup a server to handle the canonical import path. Otherwise, configure your local VCS to handle the different locations. – JimB Jun 22 '21 at 12:38
  • 1
    The link above should cover all information you need. A while ago I also asked [a similar question](https://stackoverflow.com/q/57908619/4108803) specifically for import paths above v1, which contains also useful context – blackgreen Jun 22 '21 at 14:06
  • Does this answer your question? [How can I specify ports using Go remote import paths?](https://stackoverflow.com/questions/34922929/how-can-i-specify-ports-using-go-remote-import-paths) – BadZen Jun 22 '21 at 16:21
  • (was pre-modules but the unaccepted .gitconfig solution should work for you!) – BadZen Jun 22 '21 at 16:22
  • Thanks Peter. I think this would be the best solution as scale. I had a deeper dive along these lines and it seems that there are tools that integrate with our wider tool-set to help us manage Go modules. If anyone is interested, [JFrog](https://www.jfrog.com/confluence/display/JFROG/Go+Registry) is what I specifically look into. – William Hicklin Jun 24 '21 at 13:30
  • Thanks BadZen. This was a solution I had tried but it would not work well at our scale. – William Hicklin Jun 24 '21 at 13:32

1 Answers1

4

The go tool uses git under the hood, so you'd want to configure git in your environment to use an alternate url. Something like

git config --global url."ssh://git@stash.company.com:9999/".insteadOf "https://stash.company.com"

Though I recall that bitbucket/stash sometimes provides an extra suffix for reasons I don't recall, so you might need to do something like this:

git config --global url."ssh://git@stash.company.com:9999/".insteadOf "https://stash.company.com/scm/"

ADDITIONAL EDIT

user bcmills mentioned below that you can also serve the go-import metadata over HTTPS, and use whatever vanity URL you like, provided you control the domain resolution. This can be done with varying degrees of sophistication, from a simple nginx rule to static content generators, dedicated vanity services or even running your own module proxy with Athens

This still doesn't completely solve the problem of build environment configuration, however, since you'll want the user to set GOPRIVATE or GOPROXY or both, depending on your configuration.

Also, if your chosen domain is potentially globally resolvable, you might want to consider registering it anyway to keep it from being registered by a potentially-malicious third party.

Flowchartsman
  • 371
  • 2
  • 13
  • This was something I had attempted just to see if I can make it work. However, this is not a goo long term solution as it requires these edits to be replicated for every developer and have new ones added as the number of modules increases. – William Hicklin Jun 24 '21 at 13:14
  • 2
    Build environment configuration on a per-developer basis is a common thing, so I'm not sure how else you'd like to see this managed. It's not much different from needing each developer to establish an identity with the private, internal VCS. This is already a best practice.I 'm not sure what you mean by "new ones added as the number of modules increases". The global change to gitconfig should take care of any modules coming from your internal repo. – Flowchartsman Jun 24 '21 at 16:44
  • 1
    The “good long term solution” is to set up an HTTPS server to serve `go-import` metadata (on the standard port 443) per https://golang.org/ref/mod#vcs-find. The `repo-url` field in that metadata can specify the correct port for the VCS connection. – bcmills Jun 28 '21 at 19:13