こんにちは!虎の穴ラボの鷺山です。
「GitHub Actionsでソースコードを自動フォーマットして、その変更をGITHUB_TOKENを使ってPushする」ことは広く採用されている仕組みだと思います。
しかし、GitHub Actionsには「GITHUB_TOKENによるPushでは別のワークフローが自動起動されない」という制約があります。
GITHUB_TOKENによってトリガーされたイベントでは (中略)、新しいワークフロー実行は作成されません。
そのため「自動フォーマットのPush後、別のビルド用ワークフローを自動実行させる」ことが、そのままではできません。 その結果、ブランチの最新ビルドステータスが不明になってしまい、開発時に不便な状況になります。
この課題を解決するため、この記事ではGITHUB_TOKENによるPush後に、別のワークフローを自動起動させる方法をご紹介します。
変更前のワークフロー
まずソースコードを自動フォーマットしてPushするGitHub Actionsワークフローの例を示します。
今回は例として、PythonのコードをBlackで自動フォーマットするワークフローを扱います。
▼自動フォーマット用ワークフロー (変更前)
# .github/workflows/auto-format-by-black.yml name: Blackによる自動フォーマット on: push: branches: [main, develop] paths: ["**/*.py"] pull_request: paths: ["**/*.py"] permissions: contents: write jobs: format: runs-on: ubuntu-latest timeout-minutes: 10 steps: - uses: actions/checkout@v4 with: ref: ${{ github.head_ref || github.ref_name }} - uses: actions/setup-python@v5 - name: Blackのインストール run: pip install black - name: Blackで自動フォーマットを実行 run: black . - name: 差分をチェック id: check-diff run: git diff --exit-code || echo "has_changes=true" >> $GITHUB_OUTPUT - name: 差分をPush if: steps.check-diff.outputs.has_changes == 'true' run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add . git commit -m "Blackによる自動フォーマット" git push
このワークフローはPythonファイル (*.py) の変更時に実行されます。
なお、ワークフロー中にGITHUB_TOKENは明記されていませんが、actions/checkoutで内部的に使用されています。
今回は、この自動フォーマットのPushによってコードベースが変更された際に、以下のビルド用ワークフローを起動させたい場面を考えます。
▼ビルド用ワークフロー (変更前)
# .github/workflows/build.yml name: ビルド on: push: branches: [main, develop] paths: ["**/*.py"] pull_request: paths: ["**/*.py"] jobs: build: runs-on: ubuntu-latest steps: ... # 各ビルドステップ
このワークフローも、Pythonファイル (*.py) の変更時に実行される設定になっています。
しかし、自動フォーマットによってPythonファイル (*.py) が変更されても、このビルド用ワークフローは自動実行されません。
これは前述のGITHUB_TOKENによるPushでは別のワークフローが自動起動されないというGitHub Actionsの制約によるものです。
変更後のワークフロー
自動フォーマット用ワークフローでGITHUB_TOKENによるPushを行った後にビルド用ワークフローを起動させるには、それぞれのワークフローを以下のように変更します。
▼自動フォーマット用ワークフロー (変更後)
# .github/workflows/auto-format-by-black.yml name: Blackによる自動フォーマット ... permissions: contents: write actions: write # 👈 Actionsの実行権限を追加 jobs: format: ... steps: ... # 👇 ビルドを起動するステップを追加 - name: ビルドを起動 if: steps.check-diff.outputs.has_changes == 'true' uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | // GitHub APIを使って workflow_dispatch イベントをトリガー await github.rest.actions.createWorkflowDispatch({ owner: context.repo.owner, repo: context.repo.repo, workflow_id: 'build.yml', // 起動したいワークフローのファイル名 ref: '${{ github.head_ref || github.ref_name }}' // ワークフローを起動するブランチ })
💡ポイント
permissions:にactions: writeを追加し、別のワークフローを起動できるようにします。- ワークフローを起動するAPI
createWorkflowDispatch()を実行するステップを追加します。- 明示的なワークフロー起動であれば、
GITHUB_TOKENによるトリガーであっても制約を受けずに起動できます。 workflow_idに起動したいワークフローのファイル名(build.yml)を指定します。refにワークフローを起動するブランチを指定します。ここでは自動フォーマットが行われたブランチを指定します。
- 明示的なワークフロー起動であれば、
▼ビルド用ワークフロー (変更後)
# .github/workflows/build.yml name: ビルド on: ... workflow_dispatch: # 👈 ここを追加 ...
💡ポイント
on:にworkflow_dispatchを追加し、 外部からのワークフロー起動を受け付けるようにします。
ビルドステータスを更新する
以上の変更で、GITHUB_TOKENによるPushから別のワークフローを自動起動させることができるようになります。
しかし、workflow_dispatchによるワークフロー起動ではコミットのビルドステータス (成功✅ or 失敗❌️) の反映が行われません。
これではブランチの最新ビルドステータスが分かりにくいため、ビルド用ワークフローにステータス更新APIを明示的に実行するステップを追加します。
▼ビルド用ワークフロー (さらに変更後)
# .github/workflows/build.yml name: ビルド ... permissions: ... statuses: write # 👈 ステータスの変更権限を追加 jobs: build: runs-on: ubuntu-latest steps: ... # 👇 ステータスを更新するステップを追加 - name: ステータス更新 (workflow_dispatch 用) if: always() && github.event_name == 'workflow_dispatch' uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const state = '${{ job.status }}' === 'success' ? 'success' : 'failure'; await github.rest.repos.createCommitStatus({ owner: context.repo.owner, repo: context.repo.repo, sha: context.sha, state: state, target_url: `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`, context: '${{ github.workflow }} / ${{ github.job }} (${{ github.event_name }})', description: state.charAt(0).toUpperCase() + state.slice(1), });
💡ポイント
permissions:にstatuses: writeを追加し、コミットステータスを更新できるようにします。- コミットのステータスを更新するAPI
createCommitStatus()を実行するステップを追加します。- ビルドの成功・失敗に応じた結果がコミットのステータス (
state) に反映されるように設定します。 - トリガーイベントが
workflow_dispatchの場合のみ実行されるようにif:文で制御します。
- ビルドの成功・失敗に応じた結果がコミットのステータス (
これにより、GITHUB_TOKENによるPushから別のワークフローを自動起動させつつ、その後のビルドステータスも更新させることができるようになります。
ビルドステータスを更新
まとめ
この記事では、GitHub Actionsのworkflow_dispatchとGitHub APIを組み合わせることで、GITHUB_TOKENによるPush後に別のワークフローを起動させる方法をご紹介しました。
これにより、自動フォーマット後のコードでCIを自動実行し、ビルドステータスを常に最新の状態に保つことができます。
同じような課題で悩んでいた方の参考になれば幸いです!
採用情報
虎の穴ラボでは一緒に働く仲間を募集中です!
この記事を読んで、興味を持っていただけた方はぜひ弊社の採用情報をご覧ください。
toranoana-lab.co.jp
