menu事業部マイクロサービス基盤チームに所属している、新卒1年目の立木です。
menu事業部では、ビルド・デプロイの自動化などのCI/CDツールとして、GitHub Actionsを使用しています。
GitHub Actionsでは、さまざまな操作を行う際に、リポジトリをランナー内にクローンすることがほぼ必須になります。その際に頻繁に使用されるのが、actions/checkout
です。
github.com
今回はこのactions/checkout
の挙動を紹介します!
簡単なGitHub Actionsのワークフロー
このbra1ブランチには、コミットがプッシュされた際にワーキングディレクトリを出力するだけのワークフローが設定されています。
このコミットをbra1ブランチにプッシュしてワークフローを発火させてみましょう。
name: Sample workflow bra1 on: push: jobs: bra1: runs-on: ubuntu-latest steps: - run: echo $PWD
出力:
GitHub Actionsのワーキングディレクトリは /home/runner/work/{トリガーされたリポジトリ}/{トリガーされたリポジトリ}
になっており、actions/checkout
を使用した時も、クローンされたリポジトリがこの場所に展開されます。
actions/checkout
を試してみる
先ほどのsample_bra1.yaml
を書き換え、actions/checkout
を使用してリポジトリをクローンしその中身と git branch
を表示するようにしました。
ワークフローを bra1 ブランチにプッシュしてみましょう。
name: Sample workflow bra1 on: push: jobs: bra1: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: | ls -a echo "" git branch -a
出力:
actions/checkout
はデフォルトで、ワークフローをトリガーしたリポジトリとブランチのみをクローンします。
今回トリガーした bra1ブランチがクローンされ、ワーキングディレクトリに展開されます。またbra1 ブランチとそのリモート追跡ブランチが追加されています。
連続で別のリポジトリをクローンした場合
問題です。次のようなワークフローをプッシュしたら出力はどうなるでしょう?
このワークフローでは、トリガーしたリポジトリをactions/checkoutした後、続けて別のリポジトリをactions/checkoutしています。
name: Sample workflow bra1 on: push: jobs: bra1: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 # 続けてoctocat/hello-worldをクローン - uses: actions/checkout@v4 with: repository: octocat/hello-world - run: | ls -a echo "" git branch -a
actions/checkout
では、repository
オプションを使用してクローンするリポジトリを指定できます。
答え:
bra1ブランチの内容が消えて、octocat/hello-worldの内容だけになってますね。
actions/checkout
は、続けて別のリポジトリをクローンすると、最初のリポジトリの内容や.gitを上書きします。
連続で別のブランチをクローンした場合
次に新しいブランチとしてbra2ブランチをmainから切ります。
bra2ブランチの構成は以下のようになっています。
次の問題です。bra1とbra2を連続でactions/checkout
するとどうなるでしょうか?
bra2ブランチのsample_bra2.yamlを以下のようにしてbra2ブランチにプッシュしてみます。
GitHub Actionsはon pushにおいては、プッシュ先のブランチに対応するワークフローを実行します。つまり、このプッシュは 先ほどの
sample_bra1.yaml
ではなく、sample_bra2.yaml
ワークフローをトリガーします。
name: Sample workflow bra2 on: push: jobs: bra2: runs-on: ubuntu-latest steps: # bra1ブランチをクローン - uses: actions/checkout@v4 with: ref: bra1 # 現在のブランチ(bra2)をクローン - uses: actions/checkout@v4 - run: | ls -a echo "" git branch -a
actions/checkout
では、ref
オプションを使ってクローンするブランチを指定できます。
答え:
先ほどと同様に、同じリポジトリであっても、後でクローンした bra2 ブランチの内容に上書きされ、bra2ブランチにチェックアウトされています。
しかし、git branch -a
の出力のremotes/origin/bra1
に注目してください。
最初にクローンしてきた bra1 ブランチのリモート追跡ブランチが残っています。同じリポジトリである場合、リモート追跡ブランチだけは残るようです。
このリモート追跡ブランチは、例えば git diff bra2..remotes/origin/bra1
みたいに、ブランチ間の差分を確認したいときに利用できるかもしれません。
とはいえgit fetchでいいですし、ぱっと見何やってるかわからないのが難点です。
プルリクエストの場合
pull_request
をトリガーにする場合は、actions/checkout
のデフォルトの挙動が少し変わります。
このワークフローをプッシュして、bra2
ブランチから bra1
ブランチへのプルリクエストを作成し、ワークフローをトリガーしてみましょう。
name: Sample workflow bra2 on: pull_request: jobs: main: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: | ls -a echo "" git branch -a
出力:
HEAD が pull/11/merge
というリファレンスを指しています。
この pull/数字/merge
というのは、プルリクエストがマージされた結果を指す特殊なコミットです。
つまりプルリクエストの場合、headとbaseのマージ後の結果がクローンされます。
その証拠に、bra1ブランチのbra1.txtとbra2ブランチのbra2.txtが共存しています。
もしheadブランチやbaseブランチをクローンしたい場合は、actions/checkout
の際に ref: ${{ github.head_ref }}
や ref: ${{ github.base_ref }}
のようにブランチを指定する必要があります。
以上、覚えておくと役に立つかも?なactions/checkoutの挙動でした!