接続からビルドまで

最初のiOSビルドパイプラインを動かす

まず接続を確認し、次にツールチェーンを固定してからCIを導入します。実際の作業順に沿って、専用物理Macを繰り返し使えるビルドノードに設定しましょう。仮想マシンではなく、macOSのGUIとコマンドラインの両方を利用できます。

ホストをお持ちの方は、下の「利用開始とログイン」から始めてください。機種を検討中なら、まず単一ジョブでビルドを検証してから並列数を決めましょう。

利用開始とログイン

注文とホストの認証情報を確認し、初回SSH接続を行ってログイン用の公開鍵を追加します。

初回接続の手順を見る

リモート接続

スクリプトやCIにはSSHを、Xcodeやシミュレーター、GUIの操作にはVNC画面共有を使用します。

接続設定を見る

CIの導入

self-hosted runnerを登録し、ツールチェーンのラベルを確認して、まず各ホストの同時ビルド数を1に設定します。

runnerを設定

請求と更新

請求期間、追加オプション、有効期限を確認します。注文、支払い、更新の状況はコンソールの表示をご確認ください。

請求ガイドを見る
まず接続を確認

利用開始後の最初の1時間に行う4つのこと

以下は推奨する作業順であり、利用開始や対応にかかる時間を保証するものではありません。まずコンソールでサービスが利用可能か確認し、該当インスタンスに表示されたアドレス、ポート、ユーザー名を使用してください。例からホストの認証情報を推測しないでください。

  1. インスタンスを確認

    コンソールにログインし、該当サービスの詳細で機種、ノード、利用期間を確認します。ホスト番号を控えてください。トラブルシューティング、更新、チケットでサービスを特定する際に使用します。接続先と初期認証情報は、権限のあるアカウントでのみ確認できます。

  2. 初回SSHログイン

    コンソールに表示された情報をローカルの接続パラメーターに入力します。初回接続時はホスト鍵のフィンガープリントを確認してください。信頼できる確認手段がない場合は、検証を省略せず、先にチケットでお問い合わせください。接続後、システムとユーザーの情報を確認します。

  3. ログインパスワードを変更

    対話型SSHセッションで実行します passwd。プロンプトに従って現在のユーザーのパスワードを変更してください。パスワードをコマンド引数、リポジトリ、チャット、ビルドログに記載しないでください。現在のセッションは維持し、別のセッションを開いて新しい認証情報でログインできることを確認します。

  4. ログイン用の公開鍵を追加

    自分のPCで専用鍵を生成し、公開鍵のみをホストに追加してください。公開鍵でログインできることを確認してから、パスワード認証の設定を変更します。SSHサービスの設定を変更する際は、ホストに接続できなくならないよう、利用可能なセッションを維持してください。

ローカル接続パラメーターとホスト側の確認
ssh -p "$MAC_SSH_PORT" "$MAC_USER@$MAC_HOST"

whoami
sw_vers
uname -m
xcode-select -p
df -h
passwd

接続前にローカルで MAC_SSH_PORT、MAC_USER、MAC_HOSTを設定します。値はコンソールで確認してください。ほかのコマンドはログイン後のホストで実行します。xcode-select -p で現在の開発ツールのパスを確認できます。

ホスト側 · コピーした公開鍵を追加
install -d -m 700 "$HOME/.ssh"
touch "$HOME/.ssh/authorized_keys"
chmod 600 "$HOME/.ssh/authorized_keys"
printf '%s\n' "$LOGIN_PUBLIC_KEY" >> "$HOME/.ssh/authorized_keys"

まず LOGIN_PUBLIC_KEY に公開鍵の全文を設定してから、追加コマンドを実行してください。秘密鍵をアップロードしたり、同じ公開鍵を重複して追加したりしないでください。接続タイムアウト、認証失敗、ホスト鍵の変更はそれぞれ別の問題です。チケットでは状況を区別して記載してください。

再現可能な環境を整える

Xcodeを固定してシミュレーターを準備

最新バージョンへすぐに更新するのではなく、まずプロジェクトで必要なXcode、SDK、runtimeを記録します。OSとXcodeの互換性によってインストールできるバージョンが決まります。既存プロジェクトでは、まずローカルでビルドに成功した構成を使い、アップグレードは別途検証してください。

ホストに xcodesがまだインストールされていない場合は、チームで承認されたソフトウェア導入手順に従って準備してください。特定のバージョンをインストールする際は、正規に入手した、プロジェクトの要件に合うローカルのXcodeインストーラーを使用します。以下の XCODE_VERSION と XCODE_XIP は、それぞれ確認済みのバージョン番号とインストーラーの絶対パスを表します。インストール中の対話操作を無人実行のビルドタスクに含めないでください。

ホスト側 · 開発ツールのインストールと確認
xcodes installed
xcodes install "$XCODE_VERSION" --path "$XCODE_XIP"
xcodes installed

export DEVELOPER_DIR="$XCODE_APP/Contents/Developer"
xcodebuild -version
xcodebuild -showsdks
xcrun simctl list runtimes

XCODE_APP にはインストール後の実際のアプリケーションパスを指定してください。CIでは、複数タスクがシステム全体の設定を奪い合わないよう、タスク環境で DEVELOPER_DIRを設定するのがおすすめです。システムのデフォルトのツールチェーンを切り替える必要がある場合は、 sudo xcode-select --switch "$XCODE_APP/Contents/Developer"を実行し、その後 xcodebuild -versionで再確認してください。

選択したXcodeを初回起動し、必要なコンポーネントを準備します。GUIはリモート接続で操作できます。次にXcodeのコンポーネント設定で目的のruntimeをインストールします。 xcrun simctl list devices availableを実行し、テスト対象に合ったシミュレーターを選びます。まず対話的に一度起動し、起動完了を待ってから最小限のテストタスクを実行してください。実機向けのアーカイブとシミュレーターのテストは別の手順です。runtimeがないことをアーカイブ用ツールチェーンの障害と誤認しないでください。

CIログの冒頭でツールチェーンを確認し、少なくともXcodeのバージョン、SDK一覧、コミットIDを出力してください。Xcodeを変更したらキャッシュキーを再生成し、サードパーティー依存関係、署名、エクスポートの手順も検証します。runnerのラベルだけを変更しても、実際のツールパスを確認しなければビルド環境の一貫性は保証できません。

まず単一ジョブから始める

ホストをself-hosted runnerとして登録

同じ物理ノード上のタスクは、CPU、メモリ、ディスク、ユーザー環境を共有します。まずは各ホストで一度に実行するビルドを1つにしてください。アーカイブ、署名、クリーンアップが安定してから、実際のピーク使用量を見て並列数を増やすか、独立したノードを追加しましょう。

GitLab Runner:ラベルとexecutorを確認

プロジェクトのrunner設定でプロジェクトrunnerを作成し、認証トークンを用意して、 macos、arm64、ios-archive の3つのラベルを設定します。インスタンスのURLと認証トークンを一時的に GITLAB_URL、GITLAB_RUNNER_TOKENに設定し、専用のビルドユーザーでshell executorを登録します。完了後、一時的なトークン変数を削除してください。

GitLab Runner · 登録と並列数の設定
gitlab-runner register \
  --non-interactive \
  --url "$GITLAB_URL" \
  --token "$GITLAB_RUNNER_TOKEN" \
  --executor "shell" \
  --description "armrdp-ios-archive"

unset GITLAB_RUNNER_TOKEN
gitlab-runner verify

runnerが実際に使用する config.toml で、全体の concurrent = 1を設定し、該当runnerには limit = 1を設定します。インストール済みバージョンに応じたサービス管理方法でrunnerを起動してください。対話的な検証に成功しても、バックグラウンドサービスが稼働しているとは限りません。

プロジェクト側 · .gitlab-ci.ymlのアーカイブタスク
ios_archive:
  tags:
    - macos
    - arm64
    - ios-archive
  script:
    - xcodebuild -version
    - xcodebuild archive -workspace "$IOS_WORKSPACE" -scheme "$IOS_SCHEME" -destination 'generic/platform=iOS' -archivePath "$CI_PROJECT_DIR/output/App.xcarchive"
  artifacts:
    paths:
      - output/App.xcarchive
    expire_in: 7 days

プロジェクト変数に実際の IOS_WORKSPACE と IOS_SCHEMEを設定し、次のセクションの署名準備を先に完了してください。ここではアーカイブのみを行い、エクスポートやアップロードは含みません。成果物を7日間保存する設定は一例です。チームの保管ポリシーに合わせて変更してください。証明書、秘密鍵、一時Keychainをartifactsに含めないでください。

GitHub Actions:runnerプロセスは同時に1つのタスクを実行

リポジトリ設定に記載されたrunnerのインストール手順から、macOS ARM64用プログラムを入手し、展開したディレクトリに移動します。 REPOSITORY_URL には現在のリポジトリURLを、RUNNER_TOKEN には今回の登録用トークンを設定してください。タスクが誤ったツールチェーンに割り当てられないよう、登録設定とワークフローの両方に同じラベルを指定します。

GitHub Actions · ホスト登録
./config.sh \
  --url "$REPOSITORY_URL" \
  --token "$RUNNER_TOKEN" \
  --name "armrdp-ios-archive" \
  --labels "macos,arm64,ios-archive" \
  --work "_work"

unset RUNNER_TOKEN
./run.sh
プロジェクト側 · GitHub Actionsワークフロー
name: iOS archive
on:
  workflow_dispatch:

permissions:
  contents: read

concurrency:
  group: ios-archive
  cancel-in-progress: false

jobs:
  archive:
    runs-on: [self-hosted, macos, arm64, ios-archive]
    env:
      DEVELOPER_DIR: ${{ vars.DEVELOPER_DIR }}
      IOS_WORKSPACE: ${{ vars.IOS_WORKSPACE }}
      IOS_SCHEME: ${{ vars.IOS_SCHEME }}
    steps:
      - uses: actions/checkout@v4
      - name: Archive
        run: |
          xcodebuild -version
          xcodebuild archive \
            -workspace "$IOS_WORKSPACE" \
            -scheme "$IOS_SCHEME" \
            -destination 'generic/platform=iOS' \
            -archivePath "$RUNNER_TEMP/App.xcarchive"

リポジトリ変数にツールパス、workspace、schemeを設定します。この例は環境を先に検証できるよう手動実行にしています。署名用の認証情報を持つrunnerを、信頼できない外部コードにそのまま公開しないでください。runnerプロセスは同時に1つのタスクを実行します。concurrency は同じグループ内のワークフロー実行も制御しますが、ホスト単位のリソース制限ではありません。

検証後は、ダウンロードしたプログラムに付属するサービススクリプトで常駐実行を設定し、サービスユーザーと手動テストのユーザーが同じであることを確認してください。署名の準備をあるユーザーで行い、サービスを別のユーザーで実行すると、手動ビルドには成功してもCIから証明書やプロビジョニングプロファイルを参照できないことがあります。

認証情報とコードを分離

ビルドユーザーの署名環境を準備

配布証明書、対応する秘密鍵、プロビジョニングプロファイルは、プロジェクトで使用するチームとBundle Identifierに一致している必要があります。まず管理されたタスクで署名を検証し、その後に無人実行のフローに組み込んでください。エクスポートの失敗を隠すために署名チェックを無効にしないでください。

自動化タスク専用のビルドKeychainを用意し、パスワードはCIの保護されたシークレット変数から渡します。証明書をインポートした後は、必要な署名ツールにのみアクセスを許可してください。すべてのアプリケーションに秘密鍵へのアクセスを許可しないでください。以下の確認コマンドでは、現在のユーザーが有効な署名IDを参照できるか確認できます。ただし、プロビジョニングプロファイル、エクスポート設定、プロジェクト設定がすべて一致していることの証明にはなりません。

ホスト側 · 署名IDとプロビジョニングプロファイルの場所を確認
security list-keychains -d user
security find-identity -v -p codesigning
printf '%s\n' "$HOME/Library/MobileDevice/Provisioning Profiles"
printf '%s\n' "$HOME/Library/Developer/Xcode/UserData/Provisioning Profiles"

プロビジョニングプロファイルの保存場所はXcodeのバージョンによって異なる場合があります。現在のツールチェーンが実際に参照するパスを確認してください。インポート後、有効期限、アプリID、署名の種類を確認します。アーカイブに成功してエクスポートに失敗した場合は、Xcodeを繰り返し再インストールするのではなく、エクスポート設定の方式、チームID、プロビジョニングプロファイルのマッピングを重点的に確認してください。

チームでfastlane matchを使用している場合は、既存の暗号化証明書リポジトリとアクセス方針を引き継いでください。検証時は bundle exec fastlane match appstore --readonlyを使用して既存の署名情報を読み込み、ビルドノードがチームの証明書を誤って変更しないようにします。リポジトリのアクセス認証情報、復号パスワード、Keychainパスワードは個別に管理してください。本番署名用の変数は、保護されたブランチまたは管理された手動タスクでのみ使用できるようにします。

タスクの終了後、一時ファイルを削除して一時Keychainをロックします。ログには必要なエラーコードと実行結果のみを残し、秘密鍵の内容、証明書のパスワード、登録トークン、シークレット変数の値は出力しないでください。専用物理マシンでリソースを分離していても、プロジェクト内の認証情報には最小権限を適用してください。

キャッシュは再生成できるデータとして扱う

追加ボリュームを確認してDerivedDataを移行

+1TB SSDまたは+2TB SSDを追加できます。注文情報とホスト側の両方で増設完了を確認してから、データ移行を進めてください。ボリューム名、マウントパス、ファイルシステムは実際の提供情報に従い、別のホストのディスク識別情報をそのまま使わないでください。

実行します diskutil list と df -hを実行し、容量とマウントポイントを確認してください。正体の分からないディスクに対して、消去やパーティション作成のコマンドを実行しないでください。ビルドユーザーが書き込めるキャッシュディレクトリを作成し、小さなファイルで読み書きをテストします。再起動後のマウント動作を確認してから、常駐runnerで新しいパスを使用してください。

移行前に新しいタスクの受付を停止し、実行中のアーカイブと署名が完了するまで待ちます。DerivedDataは再生成できるキャッシュなので、書き込み中の可能性がある旧キャッシュをコピーするのではなく、新しい場所で再生成するのがおすすめです。以下では明示的に -derivedDataPathを指定するため、ユーザーディレクトリ全体を追加ボリュームに移す必要はありません。

ホスト側 · マウントとビルドキャッシュの場所を確認
diskutil list
df -h

test -d "$BUILD_VOLUME" && test -w "$BUILD_VOLUME"
mkdir -p "$BUILD_VOLUME/DerivedData/$CACHE_KEY"

xcodebuild archive \
  -workspace "$IOS_WORKSPACE" \
  -scheme "$IOS_SCHEME" \
  -destination 'generic/platform=iOS' \
  -derivedDataPath "$BUILD_VOLUME/DerivedData/$CACHE_KEY" \
  -archivePath "$BUILD_VOLUME/Archives/$BUILD_ID/App.xcarchive"

実行前に BUILD_VOLUME を、書き込み可能と確認済みのマウントディレクトリに設定してください。CACHE_KEY はリポジトリ、Xcodeのバージョン、ビルド設定ごとに分けます。BUILD_ID には現在のタスクを一意に識別する値を指定し、別のタスクがアーカイブを上書きしないようにしてください。並列タスクで同じ書き込み可能なDerivedDataディレクトリを共有しないでください。

まずキャッシュを使わずに一度ビルドし、次のタスク以降のキャッシュヒット率とディスク使用量の増加を確認します。アーカイブ、シミュレーターデータ、依存関係キャッシュにはそれぞれ保管ポリシーを設定し、削除前に使用中のタスクがないことを確認してください。ビルド成果物はチーム管理の成果物ストレージに別途保存し、ホストのキャッシュを唯一のバックアップにしないでください。利用期間の終了前にエクスポートし、バックアップを読み取れることも確認します。

問題を再現できる情報を伝える

エラーだけでなく、手順もチケットに記載しましょう

ホスト、注文、支払いに関するお問い合わせは、対象サービスを特定できるようコンソールにログインしてチケットを送信してください。ログインできない場合は、メールで support@armrdp.comまでご連絡ください。どちらも正式なお問い合わせ窓口です。

問題の種類に応じて情報を追加してください。パスワード、秘密鍵、支払い情報の全桁は送信しないでください。
項目記入する内容用途
ホスト番号または注文番号コンソールに表示される番号と現在のノード対象サービスを特定し、別のインスタンスとの取り違えを防ぐ
発生時刻開始・終了時刻、タイムゾーン、現在も継続中かどうかサービスの記録とタスクログの時刻を照合
問題の種類接続タイムアウト、認証失敗、ビルド失敗、署名失敗、請求状況ネットワーク、ツールチェーン、請求の問題を切り分ける
再現手順実行順序、最小限のコマンド、期待した結果と実際の結果追加確認に必要なやり取りを減らす
環境とログXcodeのバージョン、runnerのサービスユーザー、エラー前後の機密情報を伏せたログバージョンや権限との関連を確認する
業務への影響単一タスクとホスト全体のどちらに影響するか、代替のビルド方法があるか影響範囲と現在の対応状況を伝える

返信までの時間と解決までの時間は別です

チケットの対応状況と返信時刻は、コンソールに記録された内容をご確認ください。初回返信を障害の解決と同一視しないでください。接続の問題ではホストの状態や接続経路の確認が必要な場合があり、ビルドの問題ではタスクログと再現手順が必要です。支払いの問題は注文や取引記録との照合が必要です。状況ごとに異なるため、解決までの時間を一律に示すことはできません。

対応を待つ間に新たな証拠があれば、同じチケットに追加し、経過時間や影響の拡大の有無を記載してください。状況を変える可能性のある再インストール、ディスク消去、一括削除などを繰り返さないでください。エラーがCIでのみ発生する場合は、同じユーザーでの対話実行とサービス実行の違いが分かる情報を残します。署名に関する場合は、機密情報を伏せたエラー情報のみを共有してください。

請求、更新、有効期限前の確認

サービスは日、週、月、四半期単位の前払いです。注文を確認する際は、機種、ノード、利用期間、追加オプションをあわせて確認してください。更新、自動更新の設定、支払い結果は、コンソールの現在の設定と実際の結果をご確認ください。支払いを送信しただけでは注文が有効になったとは限りません。支払い画面のスクリーンショットだけでサービス状況を判断しないでください。

お支払いはUSDT-TRC20、Visa / Mastercard / Amex(Stripe)のみご利用いただけます。すべて米ドル建てです。実際に利用できる決済ゲートウェイは、バックエンドの表示をご確認ください。暗号資産で支払う場合は、ネットワーク、送金先、金額を確認してください。調査が必要な場合は、注文番号と取引IDをお知らせください。ウォレットの秘密鍵やカード情報の全桁は送信しないでください。

有効期限前に新しいビルドの受付を止め、コードの変更、アーカイブ成果物、必要な設定をエクスポートし、自分のストレージから復元できることを確認します。継続利用する場合は、更新後に新しい有効期限を再確認してください。利用を終了する場合は、有効期限後のホストを長期保管場所として使用しないでください。

まず1つのschemeで安定したビルドを実現

1台・1タスクから始めてツールチェーン、署名、成果物を検証し、その後runnerを増やしましょう。専用物理Macは日単位で利用でき、料金は1日$21.1からです。実際の空き状況はコンソールでご確認ください。