ログオフ
開発2026-06-28

App Store Connect API で iOS リリースを自動化する:版作成から『承認済みビルドの差し替え』の壁まで

.p8 鍵から ES256 の JWT を自作すれば、新バージョン作成・ビルド紐付け・リリースノート記入まで CLI で自動化できる。ただし API には越えられない壁が一つある——『リリース待ち(Pending Developer Release)』のロックだ。

iOS の提出は、xcodebuild archivealtool でアップロードするところまでは CLI で完結する。だがその先——新バージョンの作成、ビルドの紐付け、リリースノートの記入——を App Store Connect(以下 ASC)の Web 画面で手作業している人は多い。ここは App Store Connect API でほぼ全部自動化できる。ただし最後に一つだけ、API では越えられない壁がある。

1. ASC API は .p8 鍵 + ES256 の JWT で叩ける

事象

ASC API を使いたいが、認証が OAuth ではなく独自の JWT で、ライブラリを入れないと叩けないと思い込みがちだ。

解決策

専用ライブラリは要らない。発行した API キー(.p8 ファイル)から ES256 の JWT を Node 標準の crypto だけで自作できる。

ポイントは署名の出力形式だ。JWT が要求するのは r‖s を連結した固定長(IEEE P1363)形式で、crypto の既定(DER)ではない。dsaEncoding: 'ieee-p1363' を指定する。

import crypto from "node:crypto";

const b64url = (buf) =>
  Buffer.from(buf).toString("base64")
    .replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");

function makeToken({ keyId, issuerId, privateKey, now }) {
  const header = { alg: "ES256", kid: keyId, typ: "JWT" };
  const payload = {
    iss: issuerId,
    iat: now,
    exp: now + 60 * 15,          // 20 分以内(超えると 401)
    aud: "appstoreconnect-v1",
  };
  const signingInput =
    `${b64url(JSON.stringify(header))}.${b64url(JSON.stringify(payload))}`;
  const sig = crypto.sign(
    "sha256",
    Buffer.from(signingInput),
    { key: privateKey, dsaEncoding: "ieee-p1363" } // ← DER だと ASC が弾く
  );
  return `${signingInput}.${b64url(sig)}`;
}

あとは Authorization: Bearer <token> を付けて https://api.appstoreconnect.apple.com を叩くだけだ。exp は発行から最大 20 分。長めに振ると 401 になるので、ここでは 15 分にしている。

2. リリース準備を API で組み立てる

事象

ビルドのアップロードは済んだ。ここから先(版を作る → ビルドを紐付ける → リリースノートを書く)を Web 画面で毎回手でやっている。

解決策

3 回のリクエストで組み立てられる。順番が決まっている。

(1) 新しいバージョンを作るPOST /v1/appStoreVersions

POST /v1/appStoreVersions
{
  "data": {
    "type": "appStoreVersions",
    "attributes": { "platform": "IOS", "versionString": "1.0.1" },
    "relationships": {
      "app": { "data": { "type": "apps", "id": "<APP_ID>" } }
    }
  }
}

(2) アップロード済みビルドを紐付けるPATCH /v1/appStoreVersions/{versionId}/relationships/build

PATCH /v1/appStoreVersions/{versionId}/relationships/build
{ "data": { "type": "builds", "id": "<BUILD_ID>" } }

紐付けたいビルドの ID は GET /v1/builds?filter[app]=<APP_ID>&sort=-uploadedDate で取れる。processingStateVALID になってから紐付ける。

(3) リリースノート(whatsNew)を書くPATCH /v1/appStoreVersionLocalizations/{locId}

PATCH /v1/appStoreVersionLocalizations/{locId}
{
  "data": {
    "type": "appStoreVersionLocalizations",
    "id": "<LOC_ID>",
    "attributes": { "whatsNew": "軽微な不具合を修正しました。" }
  }
}

ローカライゼーションの ID は版から辿る(GET /v1/appStoreVersions/{versionId}/appStoreVersionLocalizations)。言語ごとに 1 レコードあるので、対象言語の ID に対して PATCH する。

ここまでで、残る手作業は輸出コンプライアンス等の申告と「提出」ボタンだけになる。

補足:版を作る前に必ず存在確認する

POST /v1/appStoreVersions は、同じバージョン番号の版が既にあると衝突する。スクリプトを二度走らせたとき、あるいは前回の版が中途半端に残っているときに事故りやすい。作る前に GET /v1/appStoreVersions?filter[app]=<APP_ID> で既存の版と状態を確認してから作るほうが安全だ。

なお、公開済みアプリの更新では versionString(マーケティングバージョン)自体を上げないとビルドが弾かれる。これは別記事「アップロードしたのに配信されない・弾かれる iOS ビルドの3つの原因」で扱った。

3. API が越えられない壁:「リリース待ち」のロック

ここからが本題だ。自動化を組んでいくと、API ではどうやっても動かせない状態に突き当たる。

事象

審査を通したバージョンを「手動でリリース」設定にしておくと、状態が PENDING_DEVELOPER_RELEASE(デベロッパによるリリース待ち) になる。この状態で「やっぱり別のビルドに載せ替えたい」と思っても、API は全方向で拒否してくる。

  • 新しい版を作ろうとする → 409(枠が埋まっている)
  • ビルドを差し替えようとする(PATCH .../relationships/build)→ 409(状態が不正)
  • 版を削除しようとする → 削除できるのは最初の版だけ。公開済みバージョンがある以上、消せない

API のどの入口も塞がっていて、八方塞がりに見える。

原因

PENDING_DEVELOPER_RELEASE は「審査に通った確定版」で、リリースの引き金を引く一歩手前の状態だ。確定版なので、API からの編集・差し替え・削除を一切受け付けない。新しい版を作る枠も、この版が占有している。

解決策

この状態を戻す手段は API には無い。ASC の Web 画面でしか操作できない。

版のページ上部に出る 「Cancel This Release(このリリースをキャンセル)」 を押す。すると状態が DEVELOPER_REJECTED(編集可能) に戻る。ここまで来れば、API でも Web でもビルドを差し替えて再提出できる。

PENDING_DEVELOPER_RELEASE   ← API では一切動かせない(409 / 削除不可)
        │  「Cancel This Release」(Web のみ)
        ▼
DEVELOPER_REJECTED          ← 編集可能。ビルド差し替え → 再提出

「キャンセル」という言葉が強く見えるが、アプリが取り下げられて公開停止になるわけではない。すでに公開中のバージョンはそのまま生きていて、この操作で戻るのは「リリース待ちだった新バージョンの承認」だけだ。承認が取り消されて編集可能な状態に戻る、それだけだ。

補足

  • ASC API のリクエストはどれも .p8 鍵さえあれば叩ける。processingState の確認(GET /v1/builds)にも同じ JWT を使い回せるので、一度署名関数を組んでおくと Web 画面を見に行く回数が減る
  • 自動化できる範囲とできない範囲の線引きを覚えておくと早い。版の作成・紐付け・メタデータの記入までは API、確定版(リリース待ち)の取り消しだけは Web。この一線だけは API に手段が無い

※ 本記事にはアフィリエイトリンクが含まれます。

開発 一覧へ