Description
tl;dr
- Having dependencies behind an auth scheme is not possible and/or workarounds are not practical/usable for developers and build pipelines.
- Go toolchain does not understand urls with more than two path items
Background
I have a private/hidden project hosted on GitLab where the URL looks something like this:
gitlab.com/my-company/my-project/my-subproject/my-important-library
Since it's a private repository, there's a need to authenticate. The simplest way is to use SSH with a key pair, as it avoids user interaction. However the go toolchain insists on using HTTPS, possibly due to the way gitlab handles go-get=1
requests. The docs suggest two approaches to get around this:
- HTTPS: authenticate using credentials from
.netrc
- Force SSH: rewrite url to trick
git
into usingssh
instead ofhttps
None of these workarounds seems to work. Aside from that, there are some problems:
Using .netrc
uses clear text passwords/tokens and it's not possible to use several credentials per host. Using .gitconfig
globally does not allow several credentials per host. Configuring it locally for each project is a possibility. All of these approaches get sort of hidden away and are not very intuitive for anyone who needs to use my-important-library
. It's also a nightmare to setup a build server.
Having lost the ssh
fight with git
/go get
/go mod
I tried adding GIT_TERMINAL_PROMPT=1
to my commands like so:
GIT_TERMINAL_PROMPT=1 go get gitlab.com/my-company/my-project/my-subproject/my-important-library
GIT_TERMINAL_PROMPT=1 go mod download
This introduced me to a different problem. Seems like go
can only understand urls in the form <host>/<user>/<library>
.
What did you do?
$ GIT_TERMINAL_PROMPT=1 go get gitlab.com/my-company/my-project/my-subproject/my-important-library
What did you expect to see?
EXIT_CODE=0 and my-important-library
on disk
What did you see instead?
$ GIT_TERMINAL_PROMPT=1 go get gitlab.com/my-company/my-project/my-subproject/my-important-library
Username for 'https://gitlab.com': palsivertsen
Password for 'https://[email protected]':
# cd .; git clone https://gitlab.com/my-company/my-project.git /home/pal/projects/go/src/gitlab.com/my-company/my-project
Cloning into '/home/pal/projects/go/src/gitlab.com/my-company/my-project'...
remote: The project you were looking for could not be found.
fatal: repository 'https://gitlab.com/my-company/my-project.git/' not found
package gitlab.com/my-company/my-project/my-subproject/my-important-library: exit status 128
Note that the half the url (/my-subproject/my-important-library
) is missing.
System details
go version go1.12 linux/amd64
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/pal/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/pal/projects/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
GOROOT/bin/go version: go version go1.12 linux/amd64
GOROOT/bin/go tool compile -V: compile version go1.12
uname -sr: Linux 4.15.0-45-generic
Distributor ID: Ubuntu
Description: Ubuntu 16.04.6 LTS
Release: 16.04
Codename: xenial
/lib/x86_64-linux-gnu/libc.so.6: GNU C Library (Ubuntu GLIBC 2.23-0ubuntu11) stable release version 2.23, by Roland McGrath et al.
gdb --version: GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
$ git version
git version 2.7.4