增加4 行代码,实现使用 Go module 在线上环境打包
Golang 在 1.11 开始支持 module,终于不用把依赖包上传了。
初始化
go mod init
把生成好的 go.mod 和 go.sum 提交到代码仓库。
如果要开启 module,需要设置环境变量:
export GO111MODULE="on"
下载外网代码
执行打包脚本,发现报了一堆报错:
go: golang.org/x/sys@v0.0.0-20180909124046-d0be0721c37e: unrecognized import path "golang.org/x/sys" (https fetch: Get https://golang.org/x/sys?go-get=1: dial tcp 216.239.37.1:443: connect: connection timed out)
下载超时,这也是能够预料到的。不过可以使用replace
来解决,比如上面的 Go 扩展包,它没法下载,而它正好在 GitHub 上面有代码镜像,通过replace
就可以到 GitHub 上面下载了。详细用法可以参考When should I use the replace directive?。不过我并没有用这个方法,这里就不展开说了。
我的方法是使用代理。
export http_proxy=10.244.255.3:7766
export https_proxy=10.244.255.3:7766
下载内网私有代码
再次执行打包脚本,因为有了代理,刚才的报错没有了,不过又有了新的报错:
cd .; git clone https://github.com/examplesite/myprivaterepo /Users/tom/go/src/github.com/examplesite/myprivaterepo
Cloning into '/Users/tom/go/src/github.com/examplesite/myprivaterepo'...
fatal: could not read Username for 'https://github.com': terminal prompts disabled
package github.com/examplesite/myprivaterepo: exit status 128
这个报错也不难看懂,下载内网包的时候没有授权,需要输入密码,而 Go 会屏蔽输入密码的操作,导致下载失败。
打开密码输入也很简单:
env GIT_TERMINAL_PROMPT=1 go get xxxx
不过这个并不是我想要的方法。一个原因是通过打包脚本输密码不方便,还有一个原因是把开发者个人密码写到打包脚本里也并不合适。
Git 支持两种授权方式,一种是 HTTPS,一种是 SSH。刚才的问题就是通过 HTTPS 下载代码的时候引起的,而通过 SSH 校验权限的话并不需要密码。那么问题来了,为什么go get
是通过 HTTPS 下载代码而不是 SSH 呢?
Go 官方也给出了解释:Why does “go get” use HTTPS when cloning a repository? 。
公司一般喜欢只暴露80端口(HTTP)和433端口(HTTPS),其它端口会被屏蔽,包括9418(git)和22(SSH)。当使用 HTTPS 而不是 HTTP 协议时,git 会强制执行证书验证,预防中间人、窃听和篡改攻击。所以go get
使用 HTTPS 协议来保证安全。
其实还有一个原因,Github 本身也推荐使用 HTTPS,大家去克隆代码的时候默认的连接都是 HTTPS 的。
如果是通过 HTTPS 下载私有代码,可以在$HOME/.netrc
文件中配置密码用于授权。如果是 GitHub 用户,密码可以是access token。
machine github.com login USERNAME password APIKEY
当然,go get
也是可以通过 SSH 协议实现授权的。git 也支持替换的功能,可以把 HTTPS 替换成 SSH。比如要访问 Github 的私有仓库,可以把下面的代码放到~/.gitconfig
里面:
[url "ssh://git@github.com/"]
insteadOf = https://github.com/
也可以通过一条命令实现:
git config --global url."git@git.cyeam.com:".insteadOf "https://code.cyeam.com/"
SSH 授权需要用到私钥,这里就不展开讲了。默认情况下是在$HOME/.ssh/id_rsa
的文件。
详细说说 insteadOf
如果你都没有填错的话,代码就可以正常下载并编译了。
但是我实际操作的时候真是费了特别大的劲,网上的搜索结果都是上面的一条替换命令,再也没有多说了,但是有一个符号错了就会有问题。
insteadOf
其实就是字符串替换。
比方说我的仓库,HTTPS 连接:
https://github.com/mnhkahn/gogogo.git
SSH 连接:
git@github.com:mnhkahn/gogogo.git
这两个协议区别就是一个是 https 开头,而一个是 git(注意:是git,不是你的用户名)。中间是域名,自己的私有仓库就换成仓库的域名。后面的仓库地址,这部分是完全一样的。而域名和仓库地址中间的符号,这里也有区别,一个是斜线,一个是冒号。
总结
在编译脚本里加下面的4行代码,就能通过 Go1.11 实现自动下载依赖包了,代理自己搭哦。推荐这个。
export GO111MODULE="on"
export http_proxy=10.244.255.3:7766
export https_proxy=10.244.255.3:7766
# 内网似有包需要通过ssh下载
git config --global url."git@git.cyeam.com:".insteadOf "https://code.cyeam.com/"
原文链接:增加4 行代码,实现使用 Go module 在线上环境打包,转载请注明来源!
–EOF–