💭
GitHub Actionsでマニュアルチェックアウトする
こんにちは、サーバーサイドエンジニアの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
Discussion