GitHub Actions のデプロイをスマホで承認する方法

公開日:2026-11-08

GitHub Actions で手動の承認を挟む標準の方法は、Environments の保護ルール(required reviewers)です。ただし GitHub Free、Pro、Team のプランでは、required reviewers は公開リポジトリでしか使えません。非公開リポジトリでは、Issue のコメントで承認するコミュニティのアクションや、iPhone へ承認を送る blipdrop/nodd-action のように、ステップの中で待つ方法を使います。

デプロイの前に人の承認を挟む理由

本番へのデプロイ、データベースの移行、リリースの公開は、自動で進めたい一方で、最後に人が見てから進めたい作業です。main へのマージで自動にデプロイすると、レビューを通った変更でも、時間帯や他の作業との兼ね合いで今は出したくないことがあります。

よくある要望は次の 3 つです。

Environments の保護ルール

GitHub の標準の方法です。リポジトリの設定で production などの Environment を作り、保護ルールの required reviewers に承認する人を登録します。ジョブに environment を書くと、そのジョブは始まる前に止まり、承認を待ちます。

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    steps:
      - uses: actions/checkout@v4
      - run: ./deploy.sh

GitHub のドキュメントによると、仕組みは次のとおりです。

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"

一方で、承認を待つあいだもステップはランナーの上で動き続けるので、ランナーの時間を使います。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 を使うと、ステップの中で承認を待てます。

  1. Nodd のアプリでチャンネルを作り、送信キーを発行します
  2. リポジトリの Secrets に NODD_KEY として登録します
  3. ワークフローにステップを追加します。ランナーに 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本文
levellow、normal、high。既定は normal
wait"true" で承認を求めて待ちます。既定は "false"
expires-in応答期限の秒数。既定は "3600"
api-urlAPI の URL
出力 id通知の ID
出力 decisionapproved、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 プランだけです。

注意すること

よくある質問

非公開リポジトリで 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 での承認を送った側のプログラムへ返すアプリです。無料プランがあります。

関連する記事