【Go】gitlab 内部 Go 组件 Module 私有化
Gitlab 版本:13.12.5
Go: 1.17.7
私有化,也可以理解为组件,内部发布
问题描述
我们都知道 Go 可以用 go mod 来管理包依赖,但基本上是来管理 github 上面的第三方库。如果是内部组件,用 go mod 来管理的话,通常是在 go.mod 文件里面用 replace 来指向相对路径下的包,如下:
就比如内部封装的一个 json 包,用 go mod 去外网拉取,肯定是拉取不到的,那只能通过 replace 去找到对应的包。在 go mod tidy 的时候,就会自动加载这个依赖。
上面这个方法,在本地打包是没有问题的,因为内部组件的包都在本地。即使内部组件有更新,通知一下就会去 pull 最新的代码,然后再打包。这个方式看起来也没有什么太大的问题,小团队也挺合适的,但是在碰到下面这些问题的时候,可能就会出现一些麻烦:
gitlab CI/CD 要打包的时候,go mod tidy 不能拉取到内部组件,本地没有内部的依赖包;
内部组件无法通过版本区分,一个新的迭代可能要通过切分支来区分,不同项目打包就很痛苦。
主要原因是因为想要在 CI/CD 的时候编译,go build 的时候会出现包找不到的问题。当然,用 go mod vendor 是可以解决,但是整个包就会变得很大。
想要解决上面的两个问题,就可以转换为要把内部组件当做发布的包来管理,即 go mod tidy 的时候可以拉取到包,go mod 里面的内部组件的包可以通过版本号去指定。通过对内部 Go 组件 Module 发布,就可以解决在 CI/CD 时包拉取不到的问题,以及迭代版本可能误打包的问题。如果改成内部发布,则 go mod 的 replace 就会变成如下:
Module 私有化
假设 gitlab 的 IP 是 192.168.10.12,非 HTTS
假设域名是 git.zhengxm.cn,如要测试需改成自己的域名
如果 gitlab 是 HTTPS 的,需要再加凭证,我们内部的不是,就没有研究了
前期准备
准备一个内部组件 privatemodule,提供一个 Hello 的方法
创建一个项目 moduletest 来引用这个 privatemodule 的 Hello 方法
通过原本的方法 moduletest 内的 go.mod 如下:
moduletest 和 privatemodule 都在 gitlab 上面了
privatemodule 发布版本
如果要用私有化的 privatemodule,要先发布,通过如下指令
组件名称必须是带上域名的,不然会报组件找不到
给 gitlab 配置域名
内部 gitlab 原来是配置 IP,git clone 的时候也是直接用 IP,但是用 IP 在 go mod 里面是会报错的,且如果不改 IP 在后续会碰到 meta-tag 的问题。meta-tag 的问题就是去 gitlab 仓库拉取代码,一直显示原本 meta 数据是在 IP 下面,但现在用新的域名去拉取,拉取不到。
方式
进入 gitlab 软件安装服务器,进入到 gitlab 的 config 目录
修改 gitlab.yml 文件
把 host 修改为配置的域名
这一步如果是开发人员应该碰不到,修改这个配置我是去找运维改的
设置域名为非安全
如果直接 go get git.zhengxm.cn/zhengxm/privatemodule
,会出现如下错误,就是去 go get gitlab 组件的时候,用的是 HTTPS,但是 gitlab 不提供 HTTPS,只能用 HTTP

执行下面命令去修改
再执行 go get 就可以了
设置 GOPRIVATE
这步做不做都可以,主要是防止通过 goproxy 去拉取代码,我自己是拉取是没有报问题
可精确到代码仓库,也可以直接就域名
修改 moduletest 引用
已经发布了 privatemodule,则可以修改 moduletest 里面的引用
go.mod 改为
至此就可以在内部用私有组件,通过版本去控制,go mod 的时候也不会出问题。
遗留问题
遗留问题也是比较难搞的问题,虽然现在所有内部组件的引用都可以通过发布版本的方式去拉取,但这影响了旧的组件。旧的组件需要改 module 名称,其相关引用的代码就必须要一起改,这个其实工程量很大。
欢迎指教~
评论