GitHub Actionsの結果をAndroidに通知する

信頼できるGitHub Actionsジョブの結果を、実行ページを何度も開かずスマートフォンで確認します。

QuickStart

必要な環境: Actions secretsを設定できるGitHubリポジトリ

  1. AndroidにQueueRingをインストールし、端末登録と通知の許可を済ませて、現在のQueue IDをコピーします。端末をオンラインにしてください。
  2. Settings → Secrets and variables → Actionsでrepository secret QUEUERING_QUEUE_IDを設定します。YAMLをデフォルトブランチの.github/workflows/android-notification.ymlへ保存し、Actions → Run workflowでfail_demoを無効にして実行してください。有効にすると失敗を試せます。push先のmainは自分の信頼できるブランチに合わせてください。
  3. 端末で結果を確認する

Queue IDは送信権限を与える秘密です。公開せず、漏えい時はアプリで再発行して設定を更新してください。秘密管理の詳細。

202は受理のみで、端末表示・履歴保存・IDの有効性は保証されません。再送により重複する場合があります。再試行は通知だけにし、ジョブやagentをやり直さないでください。HTTPエラーと再試行の対処。

.github/workflows/android-notification.yml として保存
name: Android notification example
on:
  workflow_dispatch:
    inputs:
      fail_demo:
        description: Test the failure notification
        type: boolean
        default: false
  push:
    branches: [main]
permissions: {}
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Demonstrate a job result
        shell: bash
        env:
          FAIL_DEMO: ${{ inputs.fail_demo }}
        run: |
          if [[ "$FAIL_DEMO" == true ]]; then exit 1; fi
          printf 'Demo completed\n'
  notify:
    needs: build
    if: ${{ !cancelled() && (needs.build.result == 'success' || needs.build.result == 'failure') }}
    runs-on: ubuntu-latest
    timeout-minutes: 2
    steps:
      - name: Send job result to Android
        shell: bash
        env:
          QUEUE_ID: ${{ secrets.QUEUERING_QUEUE_ID }}
          BUILD_RESULT: ${{ needs.build.result }}
        run: |
          set -eu
          set +x
          : "${QUEUE_ID:?Load your Queue ID before sending}"
          [[ "$QUEUE_ID" =~ ^qr1\.[A-Za-z0-9_-]{1,16}\.[A-Za-z0-9_-]{59}$ ]] || {
            printf 'Invalid Queue ID format; copy it from the app.\n' >&2
            exit 1
          }
          message="GitHub Actions build: $BUILD_RESULT"
          status=$(curl --silent --connect-timeout 10 --max-time 30 \
            --output /dev/null --dump-header /dev/stderr --write-out '%{http_code}' \
            --request POST "https://api.queuering.org/q/$QUEUE_ID" \
            --header 'Content-Type: text/plain; charset=utf-8' \
            --data-binary "$message") || {
            printf 'Notification transport failed; check connectivity.\n' >&2
            exit 1
          }
          printf 'Notification HTTP %s\n' "$status" >&2
          [[ "$status" == 202 ]]

ボタンはコードだけをコピーします。使えない場合はコードを選択して手動でコピーしてください。コード内の表示メッセージは英語版と共通です。

端末で結果を確認する

workflow_dispatchをfail_demo無効・有効で1回ずつ実行し、Androidでbuild: successとbuild: failureを確認します。buildの失敗はそのまま失敗として残り、通知の失敗は別のnotifyジョブの失敗になります。Queue IDを出力せず、notifyジョブのログでHTTPステータスと応答ヘッダーを確認してください。

HTTP 202が返っても端末に通知が出ない場合は、現在のQueue ID・Androidの通知権限・端末の接続状態を先に確認してください。アプリの最近の履歴は追加の確認材料であり、配信を証明する受領記録ではありません。

追加例と外部連携の制限

連携の手順と制限

Actions secretsを設定できるリポジトリ、GitHubホストのUbuntu runner、runnerに含まれるcurlとBashが必要です。

notifyジョブはbuildに依存し、明示的な状態条件を使うため、build失敗時にも実行できます。スキップされたbuildとキャンセルされたworkflowは通知対象から除外します。送信中のキャンセルでは通知が中断される場合があります。この例にpull_requestやpull_request_targetトリガーはありません。信頼できないPRのコードへsecretを渡さないでください。forkやDependabotのworkflowには通常repository secretsが渡らず、再利用可能なworkflowには明示的なsecretの受け渡しが必要です。environment secretを使う場合はnotifyにそのenvironmentを指定し、保護ルールを満たしてください。詳細はGitHubのsecretsドキュメント(英語)と状態条件の説明(英語)を参照してください。

Queue IDの秘密管理の詳細

Queue IDを秘密として管理する

Queue IDを知る人は端末に通知を送れます。送信権限を与える認証情報として扱い、実IDを公開リポジトリ・Issue・ログ・スクリーンショット・プロンプト・サンプルの固定値に載せないでください。シェルトレース(set -x)、curlのverbose/trace出力、共有するターミナル録画は使わないでください。URLやプロセスの引数にIDが含まれるため、信頼できる端末でだけ実行し、プロキシやアクセスログへの記録も制限してください。

漏えいした場合は、アプリでQueue IDを再発行し、古いIDを使うすべてのローカル設定やActions secretsを更新してください。古い値を編集せず、アプリから新しい値をコピーします。202応答では古いIDがまだ有効かどうかを確認できません。

API契約・HTTPエラー・再試行

応答の意味と安全な再試行

通知とメッセージ履歴はベストエフォートです。HTTP 202はリクエストの受理を示し、Androidでの表示や履歴への保存を保証しません。無効・非アクティブ・古いQueue IDにも意図的に同じ202を返すため、IDの有効性も判断できません。履歴には端末で取得できたメッセージを最大100件保存します。履歴にないことだけでは、HTTP処理の失敗とは判断できません。

送信先はPOST https://api.queuering.org/q/{queueId}です。UTF-8のtext/plain; charset=utf-8、またはapplication/jsonを使います。JSONでは空でないbody文字列が必須で、titleは任意ですが、指定する場合は空白だけにしないでください。JSON構文も含めたリクエスト本文全体の上限は4096 bytesです。

HTTP応答と次に行うこと
結果対処
202Androidの通知権限・接続状態と、アプリの現在のQueue IDを確認します。通知が表示されないという理由だけで再送しないでください。
400リクエスト、Content-Type、JSON構文、必須フィールドを修正してから再送します。
413UTF-8本文を4096 bytes以下に短くします。JSONのエスケープも容量に含まれます。
429Retry-Afterがあれば、指定された秒数以上待ちます。なければ待ち時間を増やしながら、回数を制限して再試行します。短い間隔で繰り返さないでください。
503一時的に利用できません。障害を確認し、待ち時間を増やしながら、回数を制限して後で再試行します。
通信失敗・タイムアウト結果が不明な場合があります。接続状態を確認してから再送するか判断してください。

サンプルは接続タイムアウト10秒・全体タイムアウト30秒で1回だけ送信します。HTTPステータスとRetry-Afterを含む応答ヘッダーを出力し、自動では再試行しません。再送すると通知が重複する可能性があります。この例には冪等性キーはありません。再試行するのは通知だけにし、状態を知らせるためにバックアップ・デプロイ・agentの本体処理をやり直さないでください。通常のジョブログや監視を判断の根拠にしてください。

ほかのレシピを試す

すべてのレシピ · QueueRingのホーム