GitLab CI: Fetching Private Repository using Golang

 25th October 2022 at 1:19pm

在 Shopee 工作时遇到一个场景:在设置一个 Go 工程的 CI,期望让它跑单元测试。编译代码过程需要在公司自建的 GitLab (git.garena.com)上拉取公共包。有些公共包是 private 的,需要你的 GitLab 账号有权限才能拉取。

最终方法是,在 .gitlab-ci.yml 中编写如下代码:

test:
  image: golang:1.18

  before_script:
    # 由于本项目没有使用 vendor 机制,构建时需要从仓库拉取私有包,因此需要给容器注入 SSH key。
    # 具体做法参考了 GitLab 的官方文档:
    # https://docs.gitlab.com/ee/ci/ssh_keys/
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - ssh-keyscan git.garena.com >> ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts

    # 让 Go 使用 SSH 方式而不是 HTTPS 方式拉取依赖包
    - git config --global url."gitlab@git.garena.com:".insteadOf "https://git.garena.com/"

  cache:
    paths:
      - /go/pkg/mod/

  script:
    - go env -w GOPRIVATE=git.garena.com
    - go test -v ./...

然后需要在该项目的 GitLab 页面中,进入 Settings => CI/CD 菜单,在其中添加一个变量 SSH_PRIVATE_KEY,并使它的值为你的私钥。这样 CI 在运行时会以你的身份去拉取 Go 代码。要注意的是,这也意味着这个项目的 maintainer / owner 可以在设置页中看到你的私钥。你的私钥是暴露的。