T-CREATOR

GitHub Actions を macOS ランナーで使いこなす:Xcode/コード署名/キーチェーン設定

GitHub Actions を macOS ランナーで使いこなす:Xcode/コード署名/キーチェーン設定

iOS アプリや macOS アプリを GitHub Actions で CI/CD パイプラインに組み込む際、macOS ランナーの利用は避けて通れません。しかし、Xcode のビルド設定、コード署名証明書、キーチェーンアクセスといった macOS 特有の要素を正しく設定しなければ、ビルドエラーが頻発します。

本記事では、GitHub Actions の macOS ランナー上で Xcode ビルドを成功させるために必要な、Xcode バージョン管理、コード署名証明書とプロビジョニングプロファイルの設定、そしてキーチェーンへの登録プロセスを体系的に解説します。初めて macOS ランナーを使う方でも、この記事を読めば、確実に iOS/macOS アプリのビルド・デプロイ環境を構築できるようになるでしょう。

背景

macOS ランナーが必要な理由

GitHub Actions では、Linux や Windows、macOS といった複数の OS 環境でワークフローを実行できます。iOS や macOS アプリの開発では、Xcode が必須となるため、macOS ランナーの利用が前提です。

macOS ランナーは以下の特徴を持ちます。

  • Xcode プリインストール: 複数バージョンの Xcode がインストール済み
  • シミュレータ利用可能: iOS シミュレータや macOS アプリのテストが実行可能
  • コード署名対応: Apple の証明書やプロビジョニングプロファイルを使ったコード署名に対応

iOS/macOS アプリビルドの特殊性

iOS や macOS アプリのビルドには、単なるコンパイル以上の複雑な手順が必要です。

  • コード署名: アプリの配布やデバイスへのインストールには、Apple から発行された証明書とプロビジョニングプロファイルが必須
  • キーチェーン管理: 証明書は macOS のキーチェーンに登録する必要がある
  • Xcode バージョン: プロジェクトが特定の Xcode バージョンに依存している場合、適切なバージョンを選択しなければビルドが失敗する

下図は、GitHub Actions 上で iOS/macOS アプリをビルドする際の主要ステップとコンポーネントの関係を示しています。

mermaidflowchart TD
  runner["GitHub Actions<br/>macOS ランナー"] --> xcode_select["Xcode バージョン選択"]
  xcode_select --> keychain_create["一時キーチェーン作成"]
  keychain_create --> import_cert["証明書インポート"]
  import_cert --> import_profile["プロビジョニング<br/>プロファイルインポート"]
  import_profile --> build["Xcode ビルド実行"]
  build --> archive["アーカイブ生成"]
  archive --> export["IPA エクスポート"]
  export --> deploy["配布/デプロイ"]

図の要点:

  • macOS ランナー上で Xcode バージョンを選択し、キーチェーンに証明書を登録してからビルドを実行します
  • 最終的に IPA ファイルを生成し、App Store や TestFlight へ配布します

課題

証明書とプロビジョニングプロファイルの管理

iOS/macOS アプリのコード署名には、以下のファイルが必要です。

#ファイル種類説明
1証明書 (.p12)Apple Developer Program で発行された証明書を含むファイル
2プロビジョニングプロファイル (.mobileprovision)アプリの配布方法やデバイスを定義したファイル
3パスワード.p12 ファイルのパスワード

これらの機密情報を GitHub リポジトリに直接コミットすると、セキュリティリスクが発生します。GitHub Secrets を活用して、安全に管理する必要があります。

キーチェーンアクセスの自動化

macOS では、コード署名に使う証明書をキーチェーンに登録する必要があります。しかし、GitHub Actions のような CI 環境では、デフォルトのキーチェーンがロックされていたり、アクセス権限が不足していたりして、証明書のインポートに失敗することがあります。

以下の図は、証明書をキーチェーンに登録する際の典型的な問題と、その対処フローを示しています。

mermaidflowchart LR
  start["ビルド開始"] --> check_keychain{"デフォルト<br/>キーチェーンは<br/>利用可能?"}
  check_keychain -->|No| create_temp["一時キーチェーン作成"]
  check_keychain -->|Yes| use_default["デフォルト<br/>キーチェーン使用"]
  create_temp --> unlock["キーチェーン<br/>アンロック"]
  use_default --> unlock
  unlock --> import["証明書インポート"]
  import --> set_default["検索リストに追加"]
  set_default --> build_success["ビルド成功"]

図の要点:

  • デフォルトキーチェーンが利用できない場合、一時キーチェーンを作成してアンロックします
  • 証明書をインポート後、検索リストに追加することでビルドプロセスから参照可能になります

Xcode バージョンの選択

GitHub Actions の macOS ランナーには、複数の Xcode バージョンがプリインストールされています。しかし、プロジェクトが特定のバージョンに依存している場合、適切なバージョンを明示的に選択しなければなりません。

誤ったバージョンを使用すると、以下のようなエラーが発生します。

  • Error: The project requires Xcode 14.0 or later
  • Error: Unsupported Swift version
  • Error: Missing SDK or framework

解決策

GitHub Secrets への証明書とプロファイルの登録

機密情報は GitHub Secrets に登録することで、安全に管理できます。以下の手順で登録します。

1. 証明書を Base64 エンコード

証明書ファイル (.p12) を Base64 形式にエンコードします。

bashbase64 -i certificate.p12 -o certificate_base64.txt

2. GitHub Secrets に登録

リポジトリの「Settings」→「Secrets and variables」→「Actions」から、以下の Secrets を追加します。

#Secret 名内容
1CERTIFICATE_BASE64Base64 エンコードした証明書
2CERTIFICATE_PASSWORD証明書のパスワード
3PROVISIONING_PROFILE_BASE64Base64 エンコードしたプロビジョニングプロファイル

3. ワークフローで Secrets をデコード

GitHub Actions のワークフロー内で、Base64 エンコードされた証明書とプロビジョニングプロファイルをデコードして利用します。

yaml- name: 証明書とプロビジョニングプロファイルをデコード
  run: |
    echo "${{ secrets.CERTIFICATE_BASE64 }}" | base64 --decode > certificate.p12
    echo "${{ secrets.PROVISIONING_PROFILE_BASE64 }}" | base64 --decode > profile.mobileprovision

このステップでは、GitHub Secrets に保存された Base64 形式のデータをデコードし、ファイルとして復元しています。

一時キーチェーンの作成とアンロック

CI 環境では、デフォルトキーチェーンがロックされていることが多いため、一時キーチェーンを作成して証明書をインポートします。

1. 一時キーチェーンを作成

以下のコマンドで、一時キーチェーンを作成します。

bashsecurity create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
  • -p "$KEYCHAIN_PASSWORD": キーチェーンのパスワードを設定します(環境変数から取得)

2. キーチェーンをアンロック

作成した一時キーチェーンをアンロックします。

bashsecurity unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain

アンロックしないと、証明書のインポート時にパスワード入力を求められてビルドが停止します。

3. キーチェーンのタイムアウトを無効化

キーチェーンが自動ロックされないよう、タイムアウトを無効化します。

bashsecurity set-keychain-settings build.keychain

デフォルトでは一定時間でキーチェーンがロックされるため、この設定が必要です。

4. キーチェーンを検索リストに追加

ビルドプロセスから一時キーチェーンを参照できるよう、検索リストに追加します。

bashsecurity list-keychains -d user -s build.keychain
  • -d user: ユーザー領域のキーチェーンを対象にします
  • -s build.keychain: build.keychain を検索リストに設定します

証明書のインポート

一時キーチェーンに証明書をインポートします。

bashsecurity import certificate.p12 \
  -k build.keychain \
  -P "${{ secrets.CERTIFICATE_PASSWORD }}" \
  -T /usr/bin/codesign

各オプションの意味は以下の通りです。

  • -k build.keychain: インポート先のキーチェーンを指定
  • -P "${{ secrets.CERTIFICATE_PASSWORD }}": 証明書のパスワードを指定
  • -T ​/​usr​/​bin​/​codesign: codesign コマンドからのアクセスを許可

アクセス制御の設定

証明書にアクセス制御を設定し、パスワード入力なしで利用できるようにします。

bashsecurity set-key-partition-list \
  -S apple-tool:,apple: \
  -s \
  -k "$KEYCHAIN_PASSWORD" \
  build.keychain
  • -S apple-tool:,apple:: Apple のツールからのアクセスを許可
  • -s: パスワード入力を不要にする

プロビジョニングプロファイルのインストール

プロビジョニングプロファイルを所定のディレクトリにコピーします。

bashmkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp profile.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/

Xcode は ~​/​Library​/​MobileDevice​/​Provisioning Profiles​/​ ディレクトリからプロビジョニングプロファイルを自動的に読み込みます。

Xcode バージョンの選択

GitHub Actions では、xcode-select コマンドで使用する Xcode バージョンを切り替えられます。

1. インストール済み Xcode バージョンの確認

macOS ランナーにインストールされている Xcode バージョンは、GitHub の公式ドキュメントで確認できます。

yaml- name: インストール済み Xcode バージョンを確認
  run: ls /Applications | grep Xcode

2. Xcode バージョンを選択

使用する Xcode バージョンを明示的に指定します。

bashsudo xcode-select -s /Applications/Xcode_14.2.app

このコマンドで、Xcode 14.2 がアクティブになります。

3. 選択されたバージョンを確認

正しく選択されたか確認します。

bashxcodebuild -version

出力例:

Xcode 14.2
Build version 14C18

具体例

ここでは、実際の GitHub Actions ワークフローファイルを使って、iOS アプリのビルドとアーカイブを自動化する手順を示します。

ワークフロー全体の構成

以下は、macOS ランナー上で iOS アプリをビルドするワークフローの全体像です。各ステップがどのように連携するかを図で確認しましょう。

mermaidflowchart TD
  checkout["1.コードチェックアウト"] --> xcode["2.Xcode バージョン選択"]
  xcode --> decode["3.証明書/プロファイル<br/>デコード"]
  decode --> keychain_setup["4.キーチェーン設定"]
  keychain_setup --> import_cert["5.証明書インポート"]
  import_cert --> import_profile["6.プロファイル<br/>インストール"]
  import_profile --> dependencies["7.依存関係<br/>インストール"]
  dependencies --> xcode_build["8.Xcode ビルド"]
  xcode_build --> archive_step["9.アーカイブ"]
  archive_step --> export_ipa["10.IPA エクスポート"]
  export_ipa --> cleanup["11.クリーンアップ"]

図の要点:

  • コードチェックアウトから始まり、Xcode バージョン選択、証明書/プロファイルの設定、ビルド、アーカイブ、IPA エクスポートという流れで進みます
  • 最後にキーチェーンのクリーンアップを行い、機密情報を削除します

ワークフローファイルの作成

.github​/​workflows​/​ios-build.yml というファイルを作成します。

ワークフローのトリガー設定

プルリクエストやプッシュ時にワークフローを実行するよう設定します。

yamlname: iOS ビルド

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

この設定により、main ブランチへのプッシュやプルリクエスト作成時にワークフローが自動実行されます。

ジョブの定義

macOS ランナーを使用するジョブを定義します。

yamljobs:
  build:
    runs-on: macos-13

    env:
      KEYCHAIN_PASSWORD: temporary_password
  • runs-on: macos-13: macOS 13 の最新イメージを使用
  • env: 環境変数として一時キーチェーンのパスワードを定義

ステップ 1: コードのチェックアウト

リポジトリのコードをチェックアウトします。

yamlsteps:
  - name: コードをチェックアウト
    uses: actions/checkout@v4

actions​/​checkout@v4 アクションを使用して、最新のコードを取得します。

ステップ 2: Xcode バージョンの選択

プロジェクトに適した Xcode バージョンを選択します。

yaml- name: Xcode バージョンを選択
  run: |
    sudo xcode-select -s /Applications/Xcode_14.2.app
    xcodebuild -version

Xcode 14.2 を選択し、バージョンを確認しています。

ステップ 3: 証明書とプロファイルのデコード

GitHub Secrets からエンコードされた証明書とプロビジョニングプロファイルをデコードします。

yaml- name: 証明書とプロビジョニングプロファイルをデコード
  run: |
    echo "${{ secrets.CERTIFICATE_BASE64 }}" | base64 --decode > certificate.p12
    echo "${{ secrets.PROVISIONING_PROFILE_BASE64 }}" | base64 --decode > profile.mobileprovision

Base64 形式のデータをデコードし、ファイルとして保存します。

ステップ 4: 一時キーチェーンの作成と設定

一時キーチェーンを作成し、アンロックして検索リストに追加します。

yaml- name: 一時キーチェーンを作成
  run: |
    security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
    security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
    security set-keychain-settings build.keychain
    security list-keychains -d user -s build.keychain

このステップで、ビルドプロセスから証明書にアクセスできる環境が整います。

ステップ 5: 証明書のインポート

一時キーチェーンに証明書をインポートし、アクセス制御を設定します。

yaml- name: 証明書をインポート
  run: |
    security import certificate.p12 \
      -k build.keychain \
      -P "${{ secrets.CERTIFICATE_PASSWORD }}" \
      -T /usr/bin/codesign
    security set-key-partition-list \
      -S apple-tool:,apple: \
      -s \
      -k "$KEYCHAIN_PASSWORD" \
      build.keychain

証明書のインポートとアクセス制御設定により、コード署名が可能になります。

ステップ 6: プロビジョニングプロファイルのインストール

プロビジョニングプロファイルを Xcode が参照するディレクトリにコピーします。

yaml- name: プロビジョニングプロファイルをインストール
  run: |
    mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
    cp profile.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/

Xcode は自動的にこのディレクトリからプロファイルを読み込みます。

ステップ 7: 依存関係のインストール(CocoaPods の例)

CocoaPods を使用している場合、依存関係をインストールします。

yaml- name: 依存関係をインストール
  run: |
    cd ios
    pod install

プロジェクトが CocoaPods を使用していない場合は、このステップをスキップできます。

ステップ 8: Xcode ビルドの実行

xcodebuild コマンドでアプリをビルドします。

yaml- name: Xcode ビルドを実行
  run: |
    xcodebuild \
      -workspace ios/YourApp.xcworkspace \
      -scheme YourApp \
      -configuration Release \
      -sdk iphoneos \
      -archivePath build/YourApp.xcarchive \
      archive

各オプションの意味:

  • -workspace: ワークスペースファイルを指定(CocoaPods 使用時)
  • -scheme: ビルドするスキームを指定
  • -configuration Release: リリースビルドを実行
  • -sdk iphoneos: iOS デバイス向けビルド
  • -archivePath: アーカイブの出力先
  • archive: アーカイブを作成

ステップ 9: IPA ファイルのエクスポート

アーカイブから IPA ファイルをエクスポートします。

yaml- name: IPA をエクスポート
  run: |
    xcodebuild \
      -exportArchive \
      -archivePath build/YourApp.xcarchive \
      -exportPath build \
      -exportOptionsPlist ExportOptions.plist

ExportOptions.plist は、エクスポート設定を記述したファイルです。以下のような内容になります。

ExportOptions.plist の作成

xml<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>method</key>
    <string>app-store</string>
    <key>teamID</key>
    <string>YOUR_TEAM_ID</string>
    <key>uploadSymbols</key>
    <true/>
    <key>compileBitcode</key>
    <false/>
</dict>
</plist>
  • method: 配布方法(app-store, ad-hoc, enterprise, development)
  • teamID: Apple Developer チーム ID

このファイルをリポジトリのルートに配置しておきます。

ステップ 10: アーティファクトのアップロード

生成された IPA ファイルを GitHub Actions のアーティファクトとして保存します。

yaml- name: IPA をアップロード
  uses: actions/upload-artifact@v4
  with:
    name: YourApp.ipa
    path: build/YourApp.ipa

アーティファクトとして保存することで、ワークフロー実行後にダウンロードできます。

ステップ 11: クリーンアップ

機密情報を含むファイルとキーチェーンを削除します。

yaml- name: クリーンアップ
  if: always()
  run: |
    security delete-keychain build.keychain
    rm -f certificate.p12
    rm -f profile.mobileprovision

if: always() により、ビルドが失敗しても必ずクリーンアップが実行されます。

よくあるエラーと対処法

iOS/macOS アプリのビルド時によく遭遇するエラーと、その解決方法を表にまとめます。

#エラーコードエラーメッセージ発生条件解決方法
1Error: errSecInternalComponentUser interaction is not allowedキーチェーンがロックされているキーチェーンをアンロックし、set-key-partition-list でアクセス制御を設定
2Error: Code signing failedNo certificate for team 'XXXXX' matching 'iPhone Distribution'証明書が正しくインポートされていない証明書のインポート手順を再確認し、security find-identity で確認
3Error: Provisioning profile not foundNo profiles for 'com.example.app' were foundプロビジョニングプロファイルが正しく配置されていない~​/​Library​/​MobileDevice​/​Provisioning Profiles​/​ にファイルが存在するか確認
4Error: Xcode version mismatchThe project requires Xcode 14.0 or later古い Xcode バージョンが選択されているxcode-select で適切なバージョンを選択

エラー 1 の解決手順

  1. キーチェーンをアンロック: security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain
  2. アクセス制御を設定: security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PASSWORD" build.keychain
  3. ビルドを再実行

エラー 2 の解決手順

  1. インポートされた証明書を確認: security find-identity -v -p codesigning
  2. 証明書の有効期限を確認
  3. 証明書を再インポート

エラー 3 の解決手順

  1. プロビジョニングプロファイルの配置先を確認: ls ~​/​Library​/​MobileDevice​/​Provisioning\ Profiles​/​
  2. ファイル名と UUID を確認: security cms -D -i profile.mobileprovision
  3. 正しいプロファイルを再配置

まとめ

GitHub Actions の macOS ランナーを使った iOS/macOS アプリのビルド環境構築では、Xcode バージョン管理、コード署名証明書のインポート、キーチェーン設定が重要な要素となります。

本記事では、以下の内容を解説しました。

  • 証明書とプロビジョニングプロファイルの安全な管理: GitHub Secrets と Base64 エンコードを活用
  • 一時キーチェーンの作成と設定: CI 環境での自動化に対応したキーチェーン管理
  • Xcode バージョンの選択: プロジェクトに適したバージョンの明示的な指定
  • 完全なワークフロー例: 実際に動作する GitHub Actions ワークフローファイル

これらの手順を実践することで、iOS/macOS アプリの CI/CD パイプラインを確実に構築できます。初回のセットアップには時間がかかるかもしれませんが、一度構築すれば、安定した自動ビルド環境を維持できるでしょう。

エラーが発生した場合は、キーチェーンのアンロック状態、証明書のインポート結果、プロビジョニングプロファイルの配置先を順に確認してください。

関連リンク