View in English

  • メニューを開く メニューを閉じる
  • Apple Developer
検索
検索を終了
  • Apple Developer
  • ニュース
  • 見つける
  • デザイン
  • 開発
  • 配信
  • サポート
  • アカウント
次の内容に検索結果を絞り込む

クイックリンク

5 クイックリンク

ビデオ

メニューを開く メニューを閉じる
  • コレクション
  • トピック
  • すべてのビデオ
  • 利用方法

その他のビデオ

ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。

  • 概要
  • トランスクリプト
  • コード
  • Xcode Cloudワークフローの拡張

    Xcode Cloudをそれぞれの開発ニーズに適応させる方法を確認しましょう。開始条件、カスタムエイリアス、カスタムスクリプト、Webhook、App Store Connect APIを使用してテストと配信を自動化し、ワークフローを効率化する方法をご紹介します。

    関連する章

    • 0:00 - Introduction
    • 1:08 - Essential Workflow Concepts
    • 3:00 - Scale your workflows
    • 11:38 - Connect other systems
    • 12:33 - App Store Connect API
    • 16:35 - Webhooks
    • 20:33 - Wrap up

    リソース

    • Configuring start conditions
    • Configuring webhooks in Xcode Cloud
    • Environment variable reference
    • Forum: Developer Tools & Services
    • Sharing macOS and Xcode versions across Xcode Cloud workflows
    • Writing custom build scripts
      • HDビデオ
      • SDビデオ

    関連ビデオ

    WWDC23

    • Swift OpenAPI Generatorの紹介
    • Xcode Cloudでの実用的ワークフロー作成

    WWDC21

    • Xcode Cloudについて
  • このビデオを検索

    こんにちは Danielです 後半ではColinにも参加してもらいます ここでは Xcode Cloudのパワフルで 拡張性に優れた機能について説明します これらの機能はワークフローの スケーリングと拡張に役立ちます Xcode CloudはXcodeに組み込まれた 継続的インテグレーションおよび デリバリサービスであり App Store Connectでも利用できます Appleデベロッパ向けに設計されたもので 高品質なアプリの開発と提供を加速させます アプリのビルド 並列での自動テストの実行 テスターへのアプリの配信 優れたアプリの開発に役立つ ユーザーフィードバックの 確認と管理をサポートする 様々な クラウドベースのツールが用意されています

    このセッションでは Xcode Cloudワークフローの 拡張方法について説明します まず ワークフローの基本的な概念を 確認します 次に アプリの成長に応じてワークフローの スケーリングを行う方法を紹介します 最後に Xcode Cloud以外のシステムと 連携できるようにワークフローを拡張します

    では ワークフローの基本的な概念を 確認することから始めましょう 全てのApple Developer Programメンバーシップは 月25時間のビルド時間を提供します このセッションでは Xcode Cloudを初めて使用する方も ワークフローの柔軟性を高めたい方も 有益な情報が得られます

    先ほど触れたように Xcode Cloudには皆さんの開発作業に 役立つ様々な機能がありますが すべての出発点は シンプルなワークフローです ワークフローは4つの要素で構成されます 環境 開始条件 ビルドアクション ポストアクションです

    環境では ワークフローの 環境変数を定義します ここではワークフローの 実行時に使用するXcodeと macOSのバージョンも指定します 特定のバージョンを選択することも 最新リリースなどの エイリアスから選ぶこともできます

    開始条件では ワークフローを 実行するタイミングを指定します ブランチ プルリクエスト Gitタグのアップデートなど ソースコントロールイベントへの 対応を選択できます スケジュールを設定して 特定の日時にワークフローを 実行することもできます または 手動開始条件を選択すると 手動でのみ実行することができます

    ビルドアクションでは ソースコードに対して Xcode Cloudで何を行うかを記述します ワークフローに1つ以上の アクションを設定できます アプリのビルド

    テストの実行 分析 またはアーカイブを選択し アプリの配信に向けて準備できます 最後に ポストアクションでは ビルドアクションの 実行完了後の処理を定義します ビルド完了時にSlackで チームに通知する場合や アーカイブ済みアプリを公証したり TestFlightへ配信したりする場合などが 考えられます

    大抵の場合はシンプルな ワークフローだけで多くのことができます しかし ワークフローはパワフルです アプリの成長に応じて ニーズに合わせたスケーリングが可能です 私たちは最近 開発中のアプリに機能を追加して サービスからデータを 取得できるようにしました 既存のXcode Cloudワークフローは コードがメインブランチに プッシュされた時に開始されます 最新の変更をビルドした後 テストを実行し 最後に TestFlightのテスターに 変更が送信されます

    このテストスイートはユニットとUIのテストで 構成され モックデータを使用します アプリのUIとロジックを実際に 試すのに適しています しかし このアプリには サービスへの依存関係があるため テストサーバとやり取りする 統合テストをいくつか追加しました

    統合テストは 依存関係を持つアプリが 全体として正常に機能することを 確認するのに役立ちます ただし この統合テストを実行するには より多くの時間とリソースが必要になり ネットワーク状態など アプリで制御できない 問題の影響を受ける可能性があります 統合テストを実行するワークフローを 設定できるようにしたいのですが サーバに依存し 実際のネットワークリクエストを行うため このワークフローを実行するタイミングを より細かく制御できると便利です Xcode 15.1の新機能である 手動開始条件を使用すると ワークフローを 手動で開始するように設定できます その方法を見てみましょう まず 新しいテストプランを実行するだけの 新しいワークフローを作成します

    時間を節約するため 既存のワークフローを複製します

    ワークフローを表示するには Cloudのレポートナビゲータで アプリを副ボタンでクリックし を選択します

    ビューで 既存のワークフローを副ボタンでクリックし アクションを選択します ワークフローエディタに 新しいワークフローが表示されます このワークフローの名前を 「Integration Tests」に変更し は空白のままにします 次に 条件として追加し 既存の条件を削除します

    これでこのワークフローは 手動で指定した時だけ開始され 他のイベントでは開始されません デフォルトのオプションを そのまま使用すると 開始条件がすべての ブランチと関連付けられます ただし ブランチ PR またはGitタグを 選択して この開始条件を 関連付けるGit参照を 具体的に指定することもできます

    アクションを変更して IntegrationTestsテストプランを

    現時点では このワークフローの終了時に 何も実行する必要がないため ポストアクションを削除して をクリックします

    もちろん タブで指定された 様々なバージョンのXcodeや macOSを使用して ワークフローを実行するよう設定できます ただし 今回はどちらのワークフローも 必ず同じバージョンを使用して 実行する必要があります

    カスタムエイリアスは Xcode 15.3の新機能です Xcode Cloudの現行リリースにも 既にいくつかエイリアスがあり 利用可能な最新バージョンで ワークフローを実行するように指定できます さらに今回は チーム独自のエイリアスを 定義できるようになりました

    1つ以上のワークフローでエイリアスを 使用すると それらのワークフローは そのエイリアスで指定されたバージョンの XcodeまたはmacOSで実行されます つまり エイリアスを更新した場合 そのエイリアスを 使用しているすべてのワークフローが 更新後の値で実行されます 先ほど作成した新しいワークフローで この機能を使ってみましょう

    特定のアプリのカスタムエイリアスを すべて表示するには ナビゲータで アプリを副ボタンでクリックし を選択します

    新しいXcodeエイリアスを作成するため ボタンをクリックします カスタムエイリアスエディタが 表示されます ここにカスタムエイリアスの名前を入力し それに対応させるXcodeの バージョンを選択します ここでは「Team Preference」と名付け Xcode 15.3を選択します

    をクリックし macOSの エイリアスについても同様に設定します

    このエイリアスを ワークフローで使用するには ビューに戻って ワークフローを開き タブを表示します

    Xcodeバージョンのドロップダウンに 作成したカスタムエイリアスが表示されます これを選択し macOSについても同様にします

    カスタムエイリアスの作成と管理は この画面のバージョン選択 ドロップダウン または メニューのからでも 簡単に行えます 最後に 最初のワークフローに戻り 新しいエイリアスで使用する XcodeとmacOSのバージョンを更新します

    できました これでエイリアスの バージョンを新しく更新するたびに 両方のワークフローに その変更が適用されます

    カスタムエイリアスの使い方については こちらのドキュメントをご覧ください

    この統合テストはXcode Cloudで機能し 変更の必要はありませんが テストサーバがオンラインの場合にのみ 実行されるようにすると さらにスマートになります それには Xcode Cloudの もう1つの優れた機能を活用して プロジェクトに カスタムスクリプトを追加します

    リポジトリ内で カスタムスクリプトを定義して ビルドの特定のタイミングで 実行することができます

    リポジトリのクローンの作成後 xcodebuildの実行前または 実行後のいずれかのタイミングです

    カスタムスクリプトの詳細については 「Customize your advanced Xcode Cloud workflows」をご覧ください

    ワークフローで定義されている すべての環境変数に加え Xcode Cloudで用意されている環境変数も スクリプトで使用できます 今日はそのうちの2つを カスタムスクリプトで使用します

    使用可能な環境変数の一覧は ドキュメントの「Environment variable reference」ページをご覧ください

    Xcode Cloudでは すべてのカスタムスクリプトを プロジェクトのルートのci_scriptsフォルダに 格納する必要があります

    スクリプトのファイル名によって ビルドのどのタイミングで 実行されるかが決まります

    このシナリオでは テストの実行直前に スクリプトを実行します

    Xcodeのプロジェクトナビゲータで プロジェクトを副ボタンでクリックして スクリプトのフォルダを作成します

    このフォルダに 新しいスクリプトファイルを追加し ci_pre_xcodebuild.shという名前を付けて テストの前に実行されるようにします

    統合テストのためのアクションのみを 実行したいので ビルドアクションとworkflowIDの 環境変数をチェックする ロジックを追加します

    ここでスクリプトチェックを行い テストのビルトアクションを実行すること ワークフローとIDが 一致することを確認します ワークフローのIDを取得するには Cloudのレポートナビゲータに移動して ワークフローを副ボタンでクリックし を選択します

    IDをコピーしたら スクリプトに戻ってペーストします

    このブロック内で curlを使用してサーバの 健全性チェックエンドポイントを呼び出し エラー発生時には 詳細なエラーログを出力します

    set -e shellオプションを指定すると エラーの発生時に このスクリプトはただちに終了し ワークフローはそこで停止します サーバに到達不能な場合は このような対応が必要です

    Xcode Cloudのビルドは 一時的なタスクワーカーで実行されるため ホストが使用する IPアドレスの範囲は様々です Xcode Cloudとサーバが 通信できるようにするため ここでは 必要なIPアドレス範囲を サーバのファイアウォールの インバウンド許可リストに追加しています

    許可するIPアドレスの詳細については ドキュメントの「Requirements for using Xcode Cloud」ページをご覧ください ここでは手動開始条件を使用して 統合テスト用の 新しいワークフローを構築しました また カスタムエイリアスを使用し すべてのワークフローでmacOSと Xcodeのバージョンを一致させました さらに カスタムスクリプトを活用して テストを少しスマートにし テストサーバに到達不能な場合は 早期にエラーになるようにしました Xcode Cloudと他のシステムを連携させて ワークフローをさらに強化する 方法については Colinに説明してもらいます

    Daniel ありがとう ワークフローと そのスケーリング方法について 理解したところで 次は Xcode Cloud以外のシステムと 接続する方法を見ていきましょう

    Danielが説明したように このアプリはサービスに依存しています この新しい依存関係にはリスクが伴います 誰かがコード変更をサーバにプッシュすると アプリに問題が生じるためです

    このリスクを軽減するには 新しいIntegration Tests ワークフローを実行します このワークフローで生成される テスト結果により アプリが最新のサーバ変更に 対応しているかどうか確認できます 現時点では このワークフローは 手動でのみ実行されますが App Store Connect APIを使用すると テストサーバが変更されるたびに ビルドを自動的に開始できます

    App Store Connect APIにより Xcode Cloudに関連するタスクを含め App Store Connecの 様々なタスクを自動化できます これらのエンドポイントの詳細と その呼び出し方法については ドキュメントをご覧ください

    App Store Connect APIを使用して Integration Testsワークフローを実行するには 何が必要かを逆算で考えてみましょう

    CiBuildRunsエンドポイントにより 新しいXcode Cloudのビルドを作成できます

    この呼び出しでは 実行するワークフローの識別子と ビルドするgitReferenceを 指定する必要があります Integration Testsワークフローの IDはわかっていますが ビルドするブランチの gitReferenceofはわかりません これを確認するには ScmRepositoriesエンドポイントを使用します repositoryIDを使用して このエンドポイントを呼び出すことで そのリポジトリに関連付けられている すべてのブランチ タグ プルリクエストを 取得できます しかし まずワークフローで使用されている repositoryIDを知る必要があります これはCiWorkflowsリソースに含まれており workflowIDを使って照会できます

    このスクリプトでは 合計3つのAPI呼び出しを 行って必要なビルドを作成します

    OpenAPIを使用して App Store Connect APIを指定し コードジェネレータを使って 各エンドポイントの厳密に型指定された Swiftコードを作成できるようにします このデモでは 実装に重点を置いています ここで使用するオープンソースの コードジェネレーターの詳細については 「Meet Swift OpenAPI Generator」 をご覧ください ビルドを作成するには 3つのAPI呼び出しが必要になるため 便宜上 生成された APIクライアントで拡張を記述します

    ここで必要なのは workflowIDを引数に取り 関連付けられた CiWorkflowsリソースを取得し repositoryIDを返す関数です

    次に必要なのは このrepositoryIDを ビルドするgitReferenceIDに 変換する方法です これを行うには SCMRepositories エンドポイントを使用しますが それには リポジトリに関連付けられた すべてのgitReferencesをフェッチして 指定した名前を持つブランチの gitReferenceIDを返します

    最後に 新しいビルドを開始します そのために必要なのは workflowIDとgitReferenceIDで これらを ciBuildRunsエンドポイントに渡します

    それでは 改めて見ていきましょう まず repoID関数を呼び出しますが ここでIntegration Testsワークフローの workflowIDを指定します

    次に ビルドするブランチの名前を指定して branchIDを呼び出します ここでは「main」を使用します

    最後に workflowIDとgitReferenceIDを 使用してstartBuildを呼び出して スクリプトは完成です

    ただし App Store Connect APIで 開始されるビルドは手動と見なされるため ビルドする参照に対応する手動開始条件を 設定しておく必要があります 今回は Danielが既に あらゆるブランチに対応する 手動開始条件を このワークフローに設定しているので 問題はありません

    これでスクリプトが完成し 新しいサーバコードがプッシュされるたびに テスト結果を生成できるようになりました ここで終了でもよいのですが テスト結果に少し手を加えましょう

    ここまでの成果を プロダクション環境に接続して テスト環境での検証後に サーバの変更がデプロイされる ようにしたいと思います

    テスト結果を手作業でチェックし プロダクション環境に手動で デプロイすることもできますが もっと良い方法があります

    Xcode CloudのWebhook機能を利用すると テスト結果を デプロイメントサービスに接続し テストに合格したサーバの変更を自動的に プロダクション環境にプッシュできます

    Webhookにより ビルドイベントの発生時に サービスを対応させることができます そのため 開発プロセスで 利用している他のサービスやツールに Xcode Cloudを統合できます Webhookの詳細と 設定方法については ドキュメントをご覧ください

    Webhookを検知して対応する必要があるのは HTTPサーバのみです Swift on Serverを使用すると シンプルな プロジェクトを数ステップで作成できます それにはVaporまたは Hummingbirdフレームワークを使用します このデモでは 実装に焦点を当てるため Webhookを受信できるエンドポイントを持つ Vaporサーバが 既にセットアップされています Webhookを設定すると Xcode Cloudはエンドポイントに リクエストを送信します これは 様々なビルドイベントに関する 詳細情報を含むJSONペイロードで構成されます

    ここでは WebhookPayload構造体を定義し 対象となるフィールドを含めています このシナリオで必要なのは ワークフローID ビルドID ビルドの実行状況 ビルドの完了状態です

    この構造体を使用して Webhookリクエストをデコードすることで 簡単にペイロードからフィールドを 抽出できます

    次に ペイロードのワークフローIDと Integration Testsワークフローの ワークフローIDを比較するための ロジックを追加します

    類似したフィールドが2つあります これらはビルドイベントの状態を 示しています ExecutionProgressは ビルドが実行中か 完了したかを示します 一方 completionStatusは ビルドが成功したかどうかを示します if文を更新して 両方のチェックを行い ビルドが正常に 完了していることを確認します

    この文のボディでは 統合テストに合格したことを デプロイメントサービスに通知し buildIDを送信します このデプロイメントサービスでは 他のチェックと共にこの情報を使用することで サーバの変更を承認して プロダクション環境にデプロイします

    最後に ビルドイベントを Webhookに送信するよう Xcode Cloudに指示します これは App Store Connectの Xcode Cloudビューから行うことができます

    アプリを選択した状態でを開き タブをクリックします

    新しいWebhookを設定するため ボタンをクリックします

    名前を入力し リスナーのURLを追加します

    Webhookを設定したら Xcode Cloudを介して サーバの変更を接続するための 準備は完了です ここまでの作業を振り返りましょう

    新しいコード変更がサービスの テスト環境にデプロイされるたびに App Store Connect APIを呼び出して Integration Testsワークフローの ビルドを開始します これにより アプリとテストサーバの連携を 検証するテストが実行されます

    結果はWebhookリスナーによって処理され すべてのテストに合格すると 変更がプロダクション環境に デプロイされます

    すべてが合格の場合 コードのプッシュから プロダクション環境へのデプロイまで パイプラインが完全に自動化されます

    しかし アプリで問題が生じるような サーバ変更がプッシュされた場合は

    統合テストに不合格となり Webhookリスナーによって プロダクション環境への 変更のデプロイが中止されます これが私たちの求める動作です

    ここで取り上げているのは サーバのコード変更なので 変更をプッシュしたチームメンバーが 自分のマシンにXcodeを インストールしていない可能性があります しかし Xcode Cloudは App Store Connectに組み込まれているため その場合でも 各自のブラウザで 問題の確認と調査を行えます

    こちらは想定どおりに 実行できなかった場合の App Store Connectのビルドの結果です セクションを見ると IntegrationTestsアクションに 問題があったことがわかります

    セクションをクリックすると テストレポートが開きます

    App Store Connectからでも Xcodeを開いているかのように 確認などの操作を行えます テストステータスでフィルタリングしたり テストスイートで検索したり 各テストの詳細情報を表示したりできます ここでは サーバから返されたデータに 問題があったことがわかります

    さらに詳しい調査が必要な場合は サイドバーのをクリックして Xcodeのログやクラッシュレポートなど ビルドに関連する 様々なファイルをダウンロードできます このセッションでは様々なことを 取り上げましたが Xcode Cloudでワークフローを 拡張する方法のほんの一部に過ぎません

    ここでは手動開始条件 カスタムエイリアス カスタムスクリプトを使用して チームのワークフローを拡張し App Store Connect APIと Webhookを使って 他のシステムに統合しました

    「Create practical workflows in Xcode Cloud」や 「Meet Xcode Cloud」など 他のセッションもご覧ください Xcode CloudでチームのCIプロセスを 強化する方法について説明しています

    これらのコンセプトを実際のワークフローに 取り入れる方法について 何か新しいヒントを 得ていただけたらと思います ありがとうございました

    • 10:02 - Custom Script

      #!/bin/sh
      
      set -e
      
      if [[ $CI_XCODEBUILD_ACTION == "test-without-building" && $CI_WORKFLOW_ID == "82D89C93-B69C-46B5-A794-A2BCFD3EE487" ]]
      then
          curl https://example.com/health --fail
      fi
    • 14:01 - App Store Connect API - Client Extension

      extension Client {
          func repoID(workflowID: String) async throws -> String {
              return try await ciWorkflowsGetInstance(
                  path: .init(id: workflowID),
                  query: .init(include: [.repository])
              ).ok.body.json.data.relationships!.repository!.data!.id
          }
          
          func branchID(repoID: String, name: String) async throws -> String {
              return try await scmRepositoriesGitReferencesGetToManyRelated(
                  path: .init(id: repoID)
              )
              .ok.body.json.data
              .filter { $0.attributes!.kind == .BRANCH && $0.attributes!.name == name }
              .first!.id
          }
          
          func startBuild(workflowID: String, gitReferenceID: String) async throws {
              _ = try await ciBuildRunsCreateInstance(
                  body: .json(.init(
                      data: .init(
                          _type: .ciBuildRuns,
                          relationships: .init(
                              workflow: .init(data: .init(
                                  _type: .ciWorkflows,
                                  id: workflowID
                              )),
                              sourceBranchOrTag: .init(data: .init(
                                  _type: .scmGitReferences,
                                  id: gitReferenceID
                              ))
                          )
                      )
                  ))
              ).created
          }
      }
    • 14:43 - App Store Connect API - Main Function

      static func main() async throws {
          let client = try Client(
              serverURL: Servers.server1(),
              configuration: .init(dateTranscoder: .iso8601WithFractionalSeconds),
              transport: URLSessionTransport(),
              middlewares: [AuthMiddleware(token: ProcessInfo.processInfo.environment["TOKEN"]!)]
          )
          
          let workflowID = "82D89C93-B69C-46B5-A794-A2BCFD3EE487"
          let repoID = try await client.repoID(workflowID: workflowID)
          
          let branchName = "main"
          let branchID = try await client.branchID(repoID: repoID, name: branchName)
          
          try await client.startBuild(workflowID: workflowID, gitReferenceID: branchID)
      }
    • 17:09 - Webhook Handler Implementation

      struct WebhookPayload: Content {
          let ciWorkflow: CiWorkflow
          let ciBuildRun: CiBuildRun
          
          struct CiWorkflow: Content {
              let id: String
          }
          
          struct CiBuildRun: Content {
              let id: String
              let executionProgress: String
              let completionStatus: String
          }
      }
      
      func routes(_ app: Application) throws {
          let deploymentService = ExampleDeploymentClient()
          let workflowID = "82D89C93-B69C-46B5-A794-A2BCFD3EE487"
          
          app.post("webhook") { req async throws -> HTTPStatus in
              
              return HTTPStatus.ok
          }
      }

Developer Footer

  • ビデオ
  • WWDC24
  • Xcode Cloudワークフローの拡張
  • メニューを開く メニューを閉じる
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    メニューを開く メニューを閉じる
    • アクセシビリティ
    • アクセサリ
    • App Extension
    • App Store
    • オーディオとビデオ(英語)
    • 拡張現実
    • デザイン
    • 配信
    • 教育
    • フォント(英語)
    • ゲーム
    • ヘルスケアとフィットネス
    • アプリ内課金
    • ローカリゼーション
    • マップと位置情報
    • 機械学習
    • オープンソース(英語)
    • セキュリティ
    • SafariとWeb(英語)
    メニューを開く メニューを閉じる
    • 英語ドキュメント(完全版)
    • 日本語ドキュメント(一部トピック)
    • チュートリアル
    • ダウンロード(英語)
    • フォーラム(英語)
    • ビデオ
    Open Menu Close Menu
    • サポートドキュメント
    • お問い合わせ
    • バグ報告
    • システム状況(英語)
    メニューを開く メニューを閉じる
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles(英語)
    • フィードバックアシスタント
    メニューを開く メニューを閉じる
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(英語)
    • News Partner Program(英語)
    • Video Partner Program(英語)
    • セキュリティ報奨金プログラム(英語)
    • Security Research Device Program(英語)
    Open Menu Close Menu
    • Appleに相談
    • Apple Developer Center
    • App Store Awards(英語)
    • Apple Design Awards
    • Apple Developer Academy(英語)
    • WWDC
    Apple Developerアプリを入手する
    Copyright © 2025 Apple Inc. All rights reserved.
    利用規約 プライバシーポリシー 契約とガイドライン