如何配置Gitlab CI和私有Go模块

386 阅读2分钟

配置Gitlab CI和私有Go模块

我谈到了[私有仓库和Gitlab CI],以及我们[迁移到模块]时的故事,在迁移过程中(由于我们组织项目的方式),我们被迫开始为我们的私有模块添加.git ,并在go.mod 中使用replace 指令来明确指示Go该仓库的确切位置。

类似这样的事情。

require (
	private.gitlab.instance/project/team/service-name v1.0.0
)

replace (
	private.gitlab.instance/project/team/service-name => private.gitlab.instance/project/team/service-name.git v1.0.0
)

这种工作流程很繁琐,不符合习惯,而且使我们升级自己的内部依赖关系比正常情况下更难。

然而,经过更多的调查,我发现有一个更好的选择,那就是使用。

这需要做4个改动。

  1. 使用个人访问令牌。
  2. 更新.gitlab-ci.yml 以正确使用新的令牌。
  3. 更新我们的Dockerfile 以定义.netrc 的配置,以及
  4. 删除go.mod 中的replace 指令。

使用个人访问令牌

我们特别需要一个具有以下范围的新令牌。

  • read_api
  • repository_access

出于安全考虑,这个令牌将被定义为一个新的CI/CD环境变量,为此我们将定义两个新变量。

  • GO_MODULES_USER 代表Gitlab的用户名和
  • GO_MODULES_PERSONAL_ACCESS_TOKEN 代表我们刚刚创建的令牌。

定义一个新的令牌而不是使用CI_JOB_TOKEN 背后的原因是,这个令牌没有足够的权限来访问 Gitlab API,该 API 用于在幕后调用go mod <xyz> 确定正确的仓库。

更新.gitlab-ci.yml 以正确使用新的令牌

替换docker build 指令以传入新的变量应该就可以了,所以从类似这样的内容。

docker build \
  --build-arg CI_JOB_TOKEN

我们可以把它改成。

docker build \
  --build-arg GO_MODULES_USER
  --build-arg GO_MODULES_PERSONAL_ACCESS_TOKEN

更新我们的Dockerfile ,以定义.netrc 的配置

我们的Docker文件将被改成如下内容。

FROM golang:1.15.0-alpine3.12

ARG GO_MODULES_USER
ARG GO_MODULES_PERSONAL_ACCESS_TOKEN

WORKDIR /project-name/

RUN go env -w GOPRIVATE="private.gitlab.instance" && \
    echo -e "machine private.gitlab.instance\nlogin ${GO_MODULES_USER}\npassword ${GO_MODULES_PERSONAL_ACCESS_TOKEN}" > ~/.netrc

COPY ["go.mod", "go.sum", "./"]
RUN go mod download

COPY . .

#-

FROM golang:1.15.0-alpine3.12

WORKDIR /project-name/

ENV PATH=/go/bin/:$PATH

COPY --from=0 /project-name/ /project-name/
COPY --from=0 /go/ /go/

由于采用了多阶段构建,我们可以确定证书不会存储在正在构建的最终Docker镜像中。

删除go.mod 中的replace 指令。

最后一步是去掉那些.git 替换指令。

require (
	private.gitlab.instance/project/team/service-name v1.0.0
)

就这样,我们又回到了众所周知的go get/mod 的工作流程!