LoginSignup
7
4

More than 3 years have passed since last update.

gitlab の private repository を go get する

Posted at

TL;DR :pencil:

  1. read_apiread_repository権限のついた、gitlab Personal Access Tokenを作る
  2. ~/.netrcを作成

    ~/.netrc
    machine gitlab.com
      login yourname@gitlab.com
      password yourpersonalaccesstoken
    
  3. go getする

    GO111MODULE=on GOPRIVATE=gitlab.com/group go get gitlab.com/group/subgroup/hoge.git@v1.0.0
    
  4. container image や CI 内でやりたい場合ば、.netrcgo getする環境に渡してあげる

Private repository の go get :surfer:

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が切られているので、まずはこれをチェック。
注目すべきは最後のコメントで、

  1. read_apiread_repository権限のついた、gitlab Personal Access Tokenを作る
  2. ~/.netrcを下記の内容で作る

    machine gitlab.com
      login yourname@gitlab.com
      password yourpersonalaccesstoken
    
  3. go get --insecure を使って対象のモジュールをダウンロードする

  4. .gitconfiginsteadOfは使わない

とのこと。

なお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 buildgo testかもしれませんが、やりたいことはモジュールのダウンロードなのでgo getと同じです。

goで開発している場合、マルチステージビルドをすることが一般的かと思います。そうなると、マルチステージビルドの、ビルド環境側で下記のように.netrcを設定してあげる必要があります。

Dockerfile
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ファイルをボリュームマウントやADDCOPYなどして渡してあげることも可能ですが、今回はARGNETRC変数にファイルの中身を渡しています。従って、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}")"

まとめ :ramen:

gitlabの、subgroupを持つgoのprivate repositoryで、publicなモジュール同様にgo getする方法をご紹介しました。あくまで、2020/09/01時点(go 1.14)で調べたものですので、今後また変わってくると思います。なかなか面倒くさいですもんね :rolling_eyes:

7
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
4