actions/checkout@v2はgitconfigを書き換える副作用がある
一言で言うと
github actionsで使用するactions/checkout@v2
は.git/configを書き換えるので、actions/checkout@v2
を使用した後にgitコマンドを使うと思わぬ動きをすることがあるから気をつけてほしい。
あと、.dockerignore
に.git
を忘れないように。
追記
コメントで頂きましたが、以下のように記述することで回避できました。
- uses: actions/checkout@v2
name: "チェックアウト"
with:
persist-credentials: false
何が起きたか
githubのプライベートリポジトリを依存に含んでいたため、トークンを使って依存解決していた。
以下のようなワークフローを書いていた。
# at github.com/Urotea/sample-private-app.git
name: sample
on:
push:
branches:
- "*"
jobs:
test1:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
name: "チェックアウト"
- name: set git config
env:
READONLY_GITHUB_TOKEN: ${{ secrets.PAT }}
run: git config --global url."https://${READONLY_GITHUB_TOKEN}:x-oauth-basic@github.com/Urotea".insteadOf "https://github.com/Urotea"
- name: access remote
# gitでリモートアクセスするサンプル
run: git clone https://github.com/Urotea/sample-private-lib.git
test2:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
name: "チェックアウト"
- name: set git config
env:
READONLY_GITHUB_TOKEN: ${{ secrets.PAT }}
run: git config --global url."https://${READONLY_GITHUB_TOKEN}:x-oauth-basic@github.com/Urotea".insteadOf "https://github.com/Urotea"
- name: access remote
# gitでリモートアクセスするサンプル
run: git clone https://github.com/Urotea/sample-private-lib.git
なんとtest1は落ちるが、test2は正しく動く。
原因はactions/checkout@v2
が.git/configを勝手に書き換えており、私が設定したconfigより優先されて適用されているからである。
(configの優先順位はlocal > global)
actions/checkout@v1
はそのようなことをやっていないっぽい。なのでtest2は通る。
「いや、ワークフロー上でgitコマンドなんか使わないよ。」と思うかもしれないが、もう一段罠がある。
docker buildをする場合である。次にこちらを説明する。
github actionsでdocker buildするときの注意
上記の発展形としてactions/checkout@v2
のせいでdocker buildが失敗することがある。
以下の例はgithubプライベートリポジトリを依存に含んだjsアプリをdockerビルドする場合である。
# at github.com/Urotea/sample-private-app.git
name: sample
on:
push:
branches:
- "*"
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
name: "チェックアウト"
- name: build docker
env:
READONLY_GITHUB_TOKEN: ${{ secrets.PAT }}
run: docker build --build-arg TOKEN=$READONLY_GITHUB_TOKEN -t test:latest .
FROM node:14
ARG TOKEN
WORKDIR /src
COPY . .
RUN git config --global url."https://${TOKEN}:x-oauth-basic@github.com/Urotea".insteadOf "https://github.com/Urotea"
RUN yarn install --frozen-lockfile # ここで落ちる
{
"dependencies": {
"sample-private-lib": "git+https://github.com/Urotea/sample-private-lib.git#v0.0.1",
},
// 以下略
}
なぜビルドがこけるのか。
-
actions/checkout@v2
が.git/config
を書き換える - docker build時に
COPY . .
によって.git/*
がdocker内にコピーされる -
yarn install --frozen-lockfile
を実行したときに、裏でgit
が叩かれるが、.git/config
を読み込んでしまい失敗する
適切に.dockerignore
を設定しないとactions/checkout@v2
が勝手に書き換えた.git/config
をdocker内に持ち込んでしまい、そのままビルドがこける。
そもそもCOPY . .
で全部持っていっているのが良くない?それはそう...
でも開発時にはみんなやるでしょ?
最後に
.dockerignoreを軽視してはいけない。また、COPY . .
みたいに全部持っていかず適切に持っていくものを選ぶこと。
同じgithubトークン使ってて、ローカルではdockerビルドが通るのにactionsのワークフローでは落ちる現象に悩まされて半日潰してしまった...
というか、actions/checkout@v2
も副作用がある動きをするのはやめてほしい。実行し終わったらconfig戻しておいてくれないかなー
ある意味プルリクチャンスかも。
Discussion
persist-credentials: false
で回避できないでしょうか?すごい!回避できました!
よく見たらUsageに書いてありますね...