TL;DR
-
read_apiとread_repository権限のついた、gitlab Personal Access Tokenを作る -
~/.netrcを作成~/.netrcmachine gitlab.com login yourname@gitlab.com password yourpersonalaccesstoken -
go getするGO111MODULE=on GOPRIVATE=gitlab.com/group go get gitlab.com/group/subgroup/hoge.git@v1.0.0 -
container image や CI 内でやりたい場合ば、
.netrcをgo getする環境に渡してあげる
Private repository の go get
go module が導入され、モジュールの依存関係を go.mod で管理することもメジャーになってきました。そんな中、自チームで作成した private な git repository を go get して、他のアプリでも使いたいという場面もあるかと思います。Github で管理された priavte repository でこれを実現する方法は、ググればたくさん出てくるのですが、GitLab でやる方法はまだまだマイナーです。
そこで、gitlab.com で管理している go の private git repository を go get する方法をご紹介します!
Local環境に go get する
まず、 private repository を手元のローカル環境に go get することを考えます。が、その前に目的のモジュールがgitlabのsubgroup配下にあるかどうか確認してください。
対象モジュール(hoge)が、例えばgitlab.com/group/subgroup/hogeのように、subgroupに属している場合、go get対象となるパッケージ名はgitlab.com/group/subgroup/hoge.gitになります。
go get gitlab.com/group/subgroup/hoge.git
これを.git無しで実行すると、gitlab.com/group/subgroup.gitというリポジトリが見つからないというエラーが発生します。
githubだとgroupまたはユーザの階層の直下がリポジトリ階層になるので、subgroupの部分がリポジトリ扱いされるのではないかと推測しています。明示的に.gitとすると、そこをリポジトリとして認識してくれます。
次に、gitlab private repositoryをgo getする方法ですが、公式にissueが切られているので、まずはこれをチェック。
注目すべきは最後のコメントで、
-
read_apiとread_repository権限のついた、gitlab Personal Access Tokenを作る -
~/.netrcを下記の内容で作るmachine gitlab.com login yourname@gitlab.com password yourpersonalaccesstoken -
go get --insecureを使って対象のモジュールをダウンロードする -
.gitconfigのinsteadOfは使わない
とのこと。
なおGo 1.13以降の場合、GOPRIVATEという変数が追加されており、3番目の--insecureオプションではなく、こちらを用いた方が良さそうです。
ここまでで、privateなgo git repositoryをlocalにgo getできたことかと思います。go getしたモジュールは$GOPATH/pkg/mod/gitlab.com/group/subgroup配下に指定したバージョンごとにhoge.git@v1.0.0のようなディレクトリ名で格納されているはずです。
Container image 内で go get する
続いて、Container image内でgo getする場合を考えます。この場合、実際に実行するコマンドはgo getではなく、go buildやgo testかもしれませんが、やりたいことはモジュールのダウンロードなのでgo getと同じです。
goで開発している場合、マルチステージビルドをすることが一般的かと思います。そうなると、マルチステージビルドの、ビルド環境側で下記のように.netrcを設定してあげる必要があります。
FROM golang:1.14 AS builder
ENV GO111MODULE=on
ENV GOPRIVATE=gitlab.com/group
ADD . /go/src/gitlab.com/group/subgroup/fuga
WORKDIR /go/src/gitlab.com/group/subgroup/fuga
ARG NETRC
RUN echo "${NETRC}" > /root/.netrc
RUN go build -o /bin/fuga .
## Product
FROM alpine:3.12
COPY --from=builder /bin/fuga /bin/
CMD [ "/bin/fuga" ]
.netrcファイルをボリュームマウントやADD、COPYなどして渡してあげることも可能ですが、今回はARGでNETRC変数にファイルの中身を渡しています。従って、docker buildコマンドは下記のようになります。
docker build -t fuga --build-arg NETRC="$(cat ~/.netrc)" .
GitLab CI環境で go get する
では、CIでimageをビルドする際にはどのように.netrcを渡せばいいでしょうか。個人のアクセストークンを使用したくはありません。
こちらも、gitlabの公式に答えが用意されていました。gitlabにはCI内で使用できるトークンが用意されており、下記の形で.netrcも設定できます。
echo -e "machine gitlab.com\nlogin gitlab-ci-token\npassword ${CI_JOB_TOKEN}" > ~/.netrc
これを応用してあげれば、CI内でgo getしたい場合には上記のトークンでモジュールをダウンロードできます。また、docker-in-dockerなど、CIのなかでdocker buildしたい場合や、/kaniko/executorしたい場合には、下記のようにして--build-argに渡すことができます。
--build-arg NETRC="$(echo -e "machine gitlab.com\n login gitlab-ci-token\n password ${CI_JOB_TOKEN}")"
まとめ
gitlabの、subgroupを持つgoのprivate repositoryで、publicなモジュール同様にgo getする方法をご紹介しました。あくまで、2020/09/01時点(go 1.14)で調べたものですので、今後また変わってくると思います。なかなか面倒くさいですもんね ![]()