iOS・Androidの審査提出作業を5秒で終わるようにしてみた
はじめに
こんにちは!カウシェで Mobile Engineering を担当している @p です。
カウシェ Advent Calendar 2025 の12日目を担当します。
カウシェのラクラクiOS・Android審査出しのワークフローを紹介します。
アプリの審査提出作業は、毎回それなりに手間がかかります。公開比率の設定や段階的リリース、リリースノートの準備など、多くの操作が必要で、ヒューマンエラーが発生しやすい作業でもあります。提出ボタンを押し忘れて審査に出ていなかった、というケースも起こり得ます。
カウシェでは週に2回のリリースも珍しくありません。この頻度で提出作業を手動で繰り返すのは効率的とは言えません。そこで、GitHub Actions に必要な情報を渡すだけで iOS / Android のビルドアップロードから審査提出までを自動化し、作業時間を大幅に削減できる仕組みを導入しました。
どこまで自動化できるのか
結論: 審査提出までなら全部自動化できます🚀
3つ入力してポチるだけ

審査提出はGitHub Actionsを実行するだけでstoreのコンソールへログインすることなく完了できます。
GitHub Actions に渡す情報は次の3つです。
- app version number
- release note URL:Slack通知用
- release date:Slack通知用
これらを入力すると、ワークフローが以下の処理を全自動で実行します。
- iOS → App Store Connect へのアップロード、審査提出、段階的リリース設定
- Android → Play Console へのアップロード、Production + 内部テストへの審査提出
- Slack への成功 / 失敗通知 (結構大事)
開発者が行うのは、ワークフローを起動するだけです。
iOS審査提出の自動化
fastlane の pilot と deliver
iOS では fastlane を使い、TestFlight へのアップロードから App Store 審査提出までを自動化しています。主要部分を抜粋すると次のようになります。
(証明書などのストアへの接続は割愛しています。)
# iOSアプリを審査提出するlane
lane :submit_for_review do
create_temporary_keychain
build_prod
api_key = create_api_key
# TestFlightへのアップロード
pilot(
api_key: api_key,
skip_waiting_for_build_processing: false, # ビルド処理完了を待つ
app_identifier: "com.xxx.yyy",
groups: ["Internal"], # 配布テスターグループ
changelog: "Test flight", # 変更点
notify_external_testers: true # 外部テスター通知
)
# App Store Connect 審査提出
deliver(
api_key: api_key,
app_identifier: "com.xxx.yyy",
submit_for_review: true, # 審査提出を有効化
automatic_release: false, # 手動でリリース
phased_release: true, # 段階的リリースを有効化
skip_screenshots: true,
skip_binary_upload: true, # binary はすでに pilotにて済み
release_notes: {
"ja" => "更新内容..."
}
)
slack(message: "Successfully submitted!")
end
submit_for_review: true により審査提出まで自動化でき、phased_release: true で段階的リリースの設定も完了できます。
各パラメータについては こちらを参照することをお勧めします。
Android の自動化
Google Play Developer Publishing API(Edits API)を直接利用する
Android の場合は、Bitrise や GitHub Actions 標準の Google Play Deploy ステップだけでは「製品版 へアップロードした同一バージョンを 内部テスト版といったInternal Track にも追加する」といった運用が基本的にサポートされていません。
そこで、今回は BitriseのDeploy AndroidステップとGoogle Play Developer Publishing API(Edits API) を直接利用し、製品版 + 内部テスト版 のアップロード・提出を自動化しています。
Edits API とは
Google Play Developer Publishing API の Edits は、Play Console 上で行う複数の変更をまとめて適用できる仕組みです。これにより、次のような操作を API から実行できます。
- APK / AAB のバージョン情報登録
- トラック(internal / closed / production など)の更新
- リリースノート設定
- ストア掲載情報(ロケール別)の更新
- Edits API は次のようなフローで動作します。
+--------------------+
| 1. Edit を作成 | ← 現在の Play Console 状態のコピーが作成される
+--------------------+
|
v
+--------------------+
| 2. Edit を操作 | ← トラック更新、バージョン設定、リリースノート追加など
+--------------------+
|
v
+--------------------+
| 3. Edit を commit | ← 変更をまとめて反映
+--------------------+
|
v
+--------------------+
| 4. 反映完了 |
+--------------------+
複数の変更を安全にまとめて反映できるため、Production と Internal Track の両方に同じバージョンを登録する、といった用途で非常に役立ちます。
一方で最初にEditを作成しなければ編集できないため知らないとハマります。
実装:Production と同じバージョンを Internal Track に追加する
今回はgoogle-play-deployを利用してProduction Trackにアップロード済みの AAB と同じバージョンを Internal Track にも登録しています。
大まかな流れ
1 google-play-deployを利用してproduction Trackにアップロード・審査提出する
2 Publishing APIを利用して内部テスト版 Internal Trackにも同じアプリを公開する
1もPublishing APIを使って最初から最後までAPIを叩いてもいいのですが、parameter指定など大変なため利用できるところまで提供されているstepを使います。
- google-play-deploy@3:
title: Deploy to production track
inputs:
- service_account_json_key_path: "$BITRISEIO_PLAY_CONSOLE_SERVICE_ACCOUNT_JSON_KEY_URL"
- package_name: com.xxx.yyy
- app_path: "$BITRISE_AAB_PATH"
- track: production # Production 製品版
- user_fraction: 0.50 # 50%で公開
- status: inProgress # 段階的なリリース中であることを示す
- whatsnews_dir: "$PROJECT_LOCATION/release_notes"
- script@1:
title: Deploy to internal track
inputs:
- content: |-
# Publishing APIを叩いて内部テスト版 Internal Trackにも公開
./scripts/deploy-to-internal-track.sh \
--service-account-path "$SERVICE_ACCOUNT_FILE" \
--package-name "com.xxx.yyy" \
--version-code "$VERSION_CODE" \
--version-name "$VERSION_NAME" \
--release-notes-file "./release_notes/whatsnew-ja-JP"
#!/usr/bin/env bash
# 0. サービスアカウントで認証しアクセストークンを取得する
# 適切なroleを付与したサービスアカウントが必要となります
gcloud auth activate-service-account --key-file="$SERVICE_ACCOUNT_JSON_PATH"
# Google Play Publishing APIに必要なスコープを指定してアクセストークンを取得
ACCESS_TOKEN=$(gcloud auth print-access-token --scopes=https://www.googleapis.com/auth/androidpublisher)
# 1. Edit を作成
EDIT_RESPONSE=$(curl -s -X POST \
-H "Authorization: Bearer $ACCESS_TOKEN" \
"https://androidpublisher.googleapis.com/androidpublisher/v3/applications/$PACKAGE_NAME/edits")
# Edit作成時に含まれるedit_idが以降必要
EDIT_ID=$(echo "$EDIT_RESPONSE" | jq -r '.id')
# 2. Internal track のリリース情報を更新
curl -X PUT \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{
\"releases\": [
{
\"versionCodes\": [$VERSION_CODE],
\"status\": \"completed\", # 完全公開完了であることを示す
\"releaseNotes\": [{ \"language\": \"ja-JP\", \"text\": \"更新内容\" }]
}
]
}" \
"https://androidpublisher.googleapis.com/androidpublisher/v3/applications/$PACKAGE_NAME/edits/$EDIT_ID/tracks/internal"
# 3. Commit して変更を反映
curl -X POST \
-H "Authorization: Bearer $ACCESS_TOKEN" \
"https://androidpublisher.googleapis.com/androidpublisher/v3/applications/$PACKAGE_NAME/edits/$EDIT_ID:commit"
このように Edits API を利用することで、Production にアップロードした AAB を Internal Track にも簡単に追加できます。認証周りの設定は必要ですが、標準ワークフローのみでは対応できないユースケースをカバーできる点が大きなメリットです。
Edit更新時にstatusというパラメータがありこれを変更することで、公開状態を管理できます。
- inProgress: 提出時に段階的な公開中である
- completed: 提出時に100%公開完了である
失敗・成功通知

wf実行したのに審査提出まで完了していなかったというミスを防ぐために
成功・失敗通知をSlackに設定しておくことをお勧めします。
まとめ
実際に運用してみた感想としては、失敗率も低く十分CI・CDとしての信頼度も申し分なく、作業負担が大きく減りました。
また毎回Store ConnectとPlay Consoleへログインしなくてもいいのは非常に嬉しいです。
ぜひ皆さんもお試しください😆
おまけ(自動化できなかったこと)
Androidの審査完了通知を受け取る方法は2025/12時点提供されていないようで、Slackに審査完了を通知したかったのですが断念しました。😭
iOSはメール経由でSlackへ転送することが可能です。
カウシェは採用強化中です!
現在、エンジニア・デザイナー・QAエンジニア・PdMなど、プロダクト開発に関わる方中心に様々なポジションで募集しております。
▼募集ポジションはこちら
▼採用ページはこちら
▼カジュアル面談希望はこちら
技術の力で大きなインパクトを生みたい方、プロダクト系の職種はほぼ全方位で採用中なので、ぜひカジュアルにお話ししましょう!
Discussion