Zenn
💭

GitHub Actionsでマニュアルチェックアウトする

2024/12/06に公開

こんにちは、サーバーサイドエンジニアのTakashiccです。
今回はかなり限定的な使い方となりますが、GitHub Actionsでマニュアルチェックアウトする方法を紹介したいと思います。

やりたかったこと

GitHub Actionsを利用してPRをトリガーにしたワークフローを作成している際、次のように実装する必要がありました。

  • PRのブランチ名を取得する。
  • 取得したブランチ名を使って、別のリポジトリの同名ブランチをクローンする。
    • もしそのブランチ名が存在しない場合は、何もしない。

当初はactions/checkoutアクションを利用して実現しようとしましたが、1点問題がありました。

ブランチがない場合、リトライ処理を繰り返す

actions/checkoutにはリトライ機構があるようで、指定したブランチが存在しない場合は数秒待ってから再試行するといった動きがありました。

リトライ処理があるとその分無駄に待機する必要があるので、指定したブランチが存在しない場合はすぐにエラーと判定して欲しいです。
これを解決するためにtimeout-minutesをステップに設定するといったやり方もありますが、timeout-minutesには最低1分までしか指定できないため、無駄に1分課金されてしまいます。

マニュアルでクローンする

gitコマンドを使用してCloneします。
ローカルだと以下のようなコマンドでできますが、

git clone --branch "$BRANCH_NAME" git@github.com:org/repo.git ./out

ワークフロー内で動作させる必要があるので、以下のようなコマンドでCloneします。

git clone --branch "$BRANCH_NAME" "https://x-access-token:${TOKEN}@github.com/org/another-repo.git" ./another-repo

TOKEN${{ github.token }}が使えますが、今回は同じOrganizationにある別リポジトリを参照するため、GitHub Appsが発行するトークンを使います。
GitHub Appsについての詳細はここでは省きますが、事前にGitHub Appsを作成し、クローン対象のリポジトリにインストールしておきます。

全体のワークフローは以下となります。

manual_checkout.yml
on:
  pull_request:
    types:
      - opened
      - synchronize

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

jobs:
  checkout-manually:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/create-github-app-token@v1
        id: app-token
        with:
          app-id: ${{ secrets.APP_ID }}
          private-key: ${{ secrets.PRIVATE_KEY }}
          owner: org
          repositories: another-repo

      - name: Get branch name
        id: get-branch-name
        run: echo "branch=${{ github.event.pull_request.head.ref }}" >> "$GITHUB_OUTPUT"

      - name: Checkout another-repo with same branch name
        id: checkout-another-repo
        continue-on-error: true # エラーが起こったとしても次のステップに進ませる
        run: |
          git clone --branch "$BRANCH_NAME" "https://x-access-token:${TOKEN}@github.com/org/another-repo.git" ./another-repo
        env: # https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions?learn=getting_started&learnProduct=actions#using-an-intermediate-environment-variable
          BRANCH_NAME: "${{ steps.get-branch-name.outputs.branch }}"
          TOKEN: ${{ steps.app-token.outputs.token }}

      # another-repoのクローンに成功した場合
      - name: Do something when another-repo clone succeeds
        if: ${{ steps.checkout-another-repo.outcome == 'success' }}
        run: |
          # do something
GitHubで編集を提案
ambr Tech Blog

Discussion

ログインするとコメントできます