GitHub Actions のデプロイをスマホで承認する方法
公開日:2026-11-08
GitHub Actions で手動の承認を挟む標準の方法は、Environments の保護ルール(required reviewers)です。ただし GitHub Free、Pro、Team のプランでは、required reviewers は公開リポジトリでしか使えません。非公開リポジトリでは、Issue のコメントで承認するコミュニティのアクションや、iPhone へ承認を送る blipdrop/nodd-action のように、ステップの中で待つ方法を使います。
デプロイの前に人の承認を挟む理由
本番へのデプロイ、データベースの移行、リリースの公開は、自動で進めたい一方で、最後に人が見てから進めたい作業です。main へのマージで自動にデプロイすると、レビューを通った変更でも、時間帯や他の作業との兼ね合いで今は出したくないことがあります。
よくある要望は次の 3 つです。
- デプロイの直前でワークフローを止め、誰かが承認したときだけ進める
- PC の前にいなくても、スマホで内容を見て判断する
- 却下したときは、その理由をワークフローの側で残す
Environments の保護ルール
GitHub の標準の方法です。リポジトリの設定で production などの Environment を作り、保護ルールの required reviewers に承認する人を登録します。ジョブに environment を書くと、そのジョブは始まる前に止まり、承認を待ちます。
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- run: ./deploy.sh
GitHub のドキュメントによると、仕組みは次のとおりです。
- 承認する人は、ユーザーかチームを 6 件まで登録できます。リポジトリの読み取り権限が必要です
- 登録した人のうち 1 人が承認すれば進みます
- デプロイを始めた本人の承認を禁止する設定があります
- 承認や却下のときにコメントを残せます。却下するとワークフローは失敗します
- 待っているジョブの状態は Waiting になり、30 日以内に承認されなければ自動で失敗します
- 1 分から 43,200 分(30 日)の wait timer で、ジョブの開始を遅らせることもできます
- 承認されるまで、その Environment の secrets にジョブからアクセスできません
GitHub Mobile でも、デプロイの承認の依頼をプッシュ通知で受け、承認や却下ができます(2021 年の GitHub の changelog で発表)。
強みは、ジョブが始まる前に止まることと、承認が secrets を守る仕組みと結びついていることです。ワークフローの外の設定で管理できるので、監査の面でも分かりやすい方法です。
弱いのは使える条件です。GitHub Free、Pro、Team のプランでは、required reviewers と wait timer は公開リポジトリでしか使えません。非公開リポジトリで使うには GitHub Enterprise が必要です。また、却下したジョブは始まらないので、却下のコメントをそのジョブの中で受け取って処理することはできません。
Issue で承認するアクション
Environments を使えない非公開リポジトリのために、コミュニティのアクションがあります。よく使われる trstringer/manual-approval は、ワークフローの途中で Issue を作り、承認する人に割り当てます。Issue に approve や lgtm とコメントすると進み、deny などで失敗します。
- uses: trstringer/manual-approval@v1
with:
secret: ${{ github.TOKEN }}
approvers: user1,user2
minimum-approvals: 1
issue-title: "Deploying v1.3.5 to prod"
- 非公開リポジトリでも追加の費用なしに使えます
- 必要な承認の人数(
minimum-approvals)や、起動した人を承認者から外す設定があります - 結果は出力の
approval-status(approvedかdenied)で受け取れます - Issue のコメントなので、スマホの GitHub アプリからでも返事ができます
一方で、承認を待つあいだもステップはランナーの上で動き続けるので、ランナーの時間を使います。README にも、待ち時間はワークフローの実行の上限と利用料金の対象になると書かれています。承認はコメントの単語で判定するので、本人確認は GitHub へのログインに任せる形です。
方法の比較
| 比較 | Environments の保護ルール / Issue で承認するアクション / Nodd の GitHub Action |
|---|---|
| 承認する場所 | GitHub の画面、GitHub Mobile / GitHub の Issue / iPhone の Nodd アプリ |
| 非公開リポジトリ(Free、Pro、Team) | 使えない(Enterprise が必要)/ 使える / 使える |
| 応答の本人確認 | GitHub へのログイン / GitHub へのログイン / 応答のたびに Face ID |
| 待つ場所 | ジョブの開始前(ランナーは動かない)/ ステップの中 / ステップの中 |
| 却下の理由を後のステップで使う | できない(ジョブが始まらない)/ 結果の値だけ / 出力の note で受け取れる |
| 待つ時間の上限 | 30 日で失敗 / ジョブとワークフローの上限まで / expires-in の 15 分後まで |
| 2 人以上の承認 | できない(1 人で進む)/ minimum-approvals / CLI の --approvals(Team プラン) |
| secrets の保護 | 承認まで Environment の secrets を渡さない / なし / なし |
公開リポジトリか GitHub Enterprise を使っているなら、まず Environments の保護ルールを使うのが自然です。非公開リポジトリで、承認者が GitHub をよく見ているなら Issue のアクションで足ります。GitHub を開かずに通知から判断したいとき、Face ID での応答を求めたいとき、却下の理由をワークフローへ返したいときに、次の方法が向いています。
iPhone で承認する(Nodd の GitHub Action)
Nodd は、スクリプトや CI からの確認を iPhone に届け、Face ID での応答を送った側へ返すアプリです。blipdrop/nodd-action@v1 を使うと、ステップの中で承認を待てます。
- Nodd のアプリでチャンネルを作り、送信キーを発行します
- リポジトリの Secrets に
NODD_KEYとして登録します - ワークフローにステップを追加します。ランナーに
curlとjqが必要です
jobs:
deploy:
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- uses: actions/checkout@v4
- id: approval
uses: blipdrop/nodd-action@v1
with:
key: ${{ secrets.NODD_KEY }}
title: 本番へデプロイしますか
body: ${{ github.sha }}
level: high
wait: "true"
expires-in: "1800"
- name: 却下の理由を出す
if: failure() && steps.approval.outputs.decision == 'rejected'
env:
NOTE: ${{ steps.approval.outputs.note }}
run: echo "$NOTE"
- run: ./deploy.sh
wait: "true" のステップは、承認が記録されたときだけ成功し、却下、期限切れ、取り下げ、失敗ではジョブが失敗します。そのため、後ろの ./deploy.sh は承認のときだけ動きます。応答した人が却下の理由を書くと、出力の note で受け取れます。note は人が書いた文なので、例のように env で渡し、run の中へ直接埋めないでください。
入力と出力
key | 必須。送信キー。Secrets から渡します。ログでは隠します |
|---|---|
title | 必須。通知の見出し |
body | 本文 |
level | low、normal、high。既定は normal |
wait | "true" で承認を求めて待ちます。既定は "false" |
expires-in | 応答期限の秒数。既定は "3600" |
api-url | API の URL |
出力 id | 通知の ID |
出力 decision | approved、rejected、expired、cancelled、failed。wait: "true" のときだけ付きます |
出力 note | 応答した人が書いた理由。あるときだけ付きます。改行は空白に置き換えます |
wait を付けなければ、デプロイの完了や失敗を知らせる通知だけを送れます。
CLI でステップに組み込む
GitHub Action には、2 人以上の承認と、応答がないときの引き継ぎの入力がありません。必要なら CLI の nodd ask を使います。CI ではログインせず、環境変数 NODD_KEY に送信キーを渡します。バイナリは Releases から入手できます(例の版は公開時点のものです)。
- name: Install nodd
run: |
curl -sSL https://github.com/blipdrop/nodd/releases/download/v0.3.0/nodd-x86_64-unknown-linux-musl.tar.gz \
| tar xz -C "$RUNNER_TEMP"
echo "$RUNNER_TEMP" >> "$GITHUB_PATH"
- name: 本番 DB の変更を承認
env:
NODD_KEY: ${{ secrets.NODD_KEY }}
run: |
nodd ask "本番 DB を変更しますか" --level high \
--field 環境=production \
--approvals 2 --escalate-after 600 --expires-in 1800
nodd ask は承認で終了コード 0、却下で 10、期限切れなど応答なしで 11 を返すので、承認のときだけステップが成功します。却下の理由は標準エラー出力に Note: 理由 と出ます。--approvals の 2 人以上と --escalate-after は Team プランだけです。
注意すること
- Nodd の GitHub Action が待つのは
expires-inの 15 分後までです。ジョブのtimeout-minutesはそれより長くしてください。GitHub のジョブのtimeout-minutesの既定は 360 分で、GitHub ホストのランナーではジョブは 6 時間までです - ステップの中で待つので、待っているあいだもランナーの時間を使います。長い応答期限には向きません
- ステップの中の承認は、ワークフローを書き換えられる人なら外せます。本番の secrets は Environment に置くなど、GitHub の権限の設定と組み合わせてください
- Nodd の無料プランは 1 人、端末 1 台で、同時の応答待ちは 3 件までです。チームで承認を受けるなら Team プランです
- 未応答を承認として扱わないでください。期限切れではジョブが失敗します
よくある質問
- 非公開リポジトリで Environments の承認は使えますか
- GitHub Free、Pro、Team のプランでは、required reviewers と wait timer は公開リポジトリだけです。非公開リポジトリで使うには GitHub Enterprise が必要です。それ以外では、ステップの中で承認を待つアクションを使います。
- GitHub Mobile でデプロイを承認できますか
- できます。Environments の required reviewers に登録された人は、GitHub Mobile でプッシュ通知を受け、承認や却下ができます。
- 却下の理由をワークフローで受け取れますか
- Nodd の GitHub Action では、応答した人が書いた理由が出力の note に入ります。CLI では標準エラー出力に Note として出ます。Environments で却下したジョブは始まらないので、そのジョブの中では受け取れません。
- 承認がないまま放っておくとどうなりますか
- Environments では 30 日以内に承認されないジョブが自動で失敗します。Nodd では応答期限を過ぎると expired になり、ジョブが失敗します。どちらも承認なしには進みません。
- Nodd で 2 人の承認を求められますか
- CLI の nodd ask に --approvals 2 を付けると、2 人の承認がそろうまで待ちます。2 人以上の承認は Team プランだけで、GitHub Action には人数の入力がありません。
Nodd は、スクリプトや CI、AI エージェントからの確認を iPhone に届け、Face ID での承認を送った側のプログラムへ返すアプリです。無料プランがあります。