GitHub ActionsでXcode 27を使う場合、runs-onに指定するrunnerラベルはxcode-27またはxcode-27-xlargeです。ただし、どちらもarm64専用であり、Intelベースのrunnerでは利用できません。
そのため、現在のworkflowがIntel向けの実行ファイル、バイナリフレームワーク、ネイティブ拡張などに依存している場合、ラベルを書き換えるだけでは移行できません。まずXcode 27用のジョブを追加してarm64互換性を確認し、Intel専用依存が残るジョブは既存runnerで継続するのが安全です。
2026年7月20日時点では、Xcode 27 runner imageはpublic previewです。公式発表には既存runnerからの強制移行期限は記載されていないため、リリース用CIを一度に切り替える必要はありません。(The GitHub Blog)
GitHub ActionsでXcode 27を使うrunnerラベル
Xcode 27 runner imageで利用できるラベルは次の2つです。
| runnerラベル | アーキテクチャ | 主な用途 |
|---|---|---|
xcode-27 | arm64 | 通常のビルド、単体テスト、互換性確認 |
xcode-27-xlarge | arm64 | 大規模プロジェクト、処理時間の長いビルド、並列処理を多用するテスト |
最初に試す場合は、通常のxcode-27を選べば十分です。
ビルド時間やメモリ使用量が問題になる場合は、xcode-27-xlargeを検討します。ただし、XLargeはlarger runnerに該当するため、組織やリポジトリでの利用可否、課金設定、利用上限を事前に確認してください。
GitHubのmacOS XLarge runnerはarm64のM2環境として提供され、5 CPU、14GB RAM、14GB SSDなどの仕様が案内されています。また、GitHub公式Actionはarm64 runnerに対応していますが、コミュニティ製Actionは対応していない可能性があります。(GitHub Docs)
最小構成のworkflow例
既存workflowのruns-onを書き換える最小例は次のとおりです。
name: Xcode 27 Build
on:
pull_request:
workflow_dispatch:
jobs:
build:
runs-on: xcode-27
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Check environment
run: |
echo "runner.arch=${{ runner.arch }}"
uname -m
xcodebuild -version
swift --version
- name: Verify arm64 runner
run: |
test "${{ runner.arch }}" = "ARM64"
- name: Build
run: |
set -o pipefail
xcodebuild \
-scheme YOUR_SCHEME \
-configuration Debug \
-sdk iphonesimulator \
build
YOUR_SCHEMEは、実際のXcodeプロジェクトで使用しているscheme名に置き換えます。
runner.archでは、実行中runnerのアーキテクチャを取得できます。GitHub ActionsではX86、X64、ARM、ARM64のいずれかが返されます。(GitHub Docs)
Xcode 27から変わるrunner imageの提供モデル
Xcode 27 runner imageでは、GitHub-hosted macOS runnerの提供モデルが変更されています。
従来はmacos-15やmacos-26のように、主にmacOSのバージョンを基準としてrunner imageを選択していました。新しいモデルでは、macOSではなくXcodeのメジャーバージョンを基準としてイメージを選択します。
| 従来の考え方 | Xcode 27以降の新しい考え方 |
|---|---|
| macOSのバージョンでrunnerを選ぶ | Xcodeのメジャーバージョンでrunnerを選ぶ |
macos-26などを指定する | xcode-27などを指定する |
| 1つのmacOS imageに複数のXcodeが存在することがある | 1つのimageで1つのXcodeメジャーバージョンをサポートする |
| 必要に応じてXcodeを切り替える | 必要なXcodeに対応するrunner imageを直接選ぶ |
GitHubは、各イメージを基盤OSではなくXcodeのメジャーバージョンに対応させ、1つのイメージで1つのXcodeメジャーバージョンをサポートすると説明しています。(The GitHub Blog)
この変更により、workflowを見ただけで「どのXcodeメジャーバージョンを使うか」が分かりやすくなります。
一方で、xcode-27というラベルが基盤OSや周辺ツールの完全固定を意味するわけではありません。Xcode以外のNode.js、Ruby、CocoaPods、Fastlane、Homebrewパッケージなどは、イメージ更新によってバージョンが変わる可能性があります。
公開時点のイメージ情報では、Xcode 27 betaがデフォルトとして登録されています。インストール済みソフトウェアとバージョンはrunner-imagesリポジトリで確認できます。(GitHub)
public previewであることの注意点
Xcode 27 runner imageは、正式提供ではなくpublic previewです。
GitHubのrunner-imagesリポジトリでは、Betaイメージは正式提供前の問題発見とフィードバック収集を目的としており、原則として週次で更新されます。また、Betaイメージ上で実行するworkflowは、GitHub Actionsの顧客向けSLAの対象外と説明されています。(GitHub)
そのため、現時点では次のような使い分けが適しています。
| ジョブ | 推奨するrunner |
|---|---|
| Xcode 27との互換性確認 | xcode-27 |
| Pull Request時の先行テスト | xcode-27を非ブロッキングで実行 |
| 正式リリースの署名・配布 | 現在安定稼働している既存runnerを維持 |
| 大規模なXcode 27ビルド | xcode-27-xlarge |
| Intel専用ツールを使用する処理 | 既存のIntel runnerを維持 |
public previewの段階では、Xcode 27ジョブだけをリリース可否の唯一の判定条件にするより、既存ジョブと並行運用する方が安全です。
Intelベースのジョブはそのまま移行できるのか
Intel runnerからXcode 27 runnerへの変更では、Xcodeのバージョンだけでなく、ホストCPUもx86_64からarm64へ変わります。
そのため、次のようなworkflowはラベル変更だけで移行できない可能性があります。
| 依存内容 | 移行判断 |
|---|---|
| Swiftのソースコードだけで構成 | 比較的移行しやすい |
| ソースからビルドできるSwift Package | arm64対応を確認して移行 |
| arm64を含むXCFramework | 基本的に移行可能 |
| x86_64専用のCLIツール | そのままでは実行できない |
x86_64専用の.frameworkや.dylib | arm64版またはUniversal版が必要 |
| ネイティブ拡張を含むRuby gemやNode.jsパッケージ | arm64版の有無を確認 |
| コミュニティ製GitHub Action | arm64対応状況を個別確認 |
/usr/localを固定したスクリプト | パスの修正が必要になる可能性が高い |
| Intel runnerのキャッシュを共有 | アーキテクチャ別に分離する |
重要なのは、runnerのアーキテクチャと、生成するアプリのアーキテクチャは別の問題だという点です。
arm64 runner上でも、設定と依存ライブラリが対応していれば、Intel向けまたはUniversal形式のmacOSアプリをクロスコンパイルできる場合があります。しかし、ビルド途中で実行するツールがx86_64専用であれば、そのツールの実行段階で失敗します。
また、Intel向けバイナリを生成できても、runner上でIntel向けテストバイナリを実行できるとは限りません。ビルドと実行テストは分けて判断する必要があります。
安全に移行するための手順
現在使っているrunnerラベルを確認する
まず、.github/workflows以下からruns-onを検索します。
grep -R "runs-on:" .github/workflows
次のようなラベルを使用しているジョブが移行対象です。
runs-on: macos-latest
runs-on: macos-26
runs-on: macos-26-intel
同時に、reusable workflow内のruns-onや、Organization共通workflowも確認してください。呼び出し元だけを見ていると、実際に利用しているrunnerを見落とすことがあります。
Intel依存を洗い出す
workflow、シェルスクリプト、ビルドツールから、次の記述を検索します。
grep -R -E "x86_64|amd64|/usr/local|arch -x86_64" .
特に確認すべき対象は次のとおりです。
- リポジトリに直接配置した実行ファイル
- 独自のコード生成ツール
- Swift Packageのbinary target
- CocoaPodsから取得するバイナリフレームワーク
- Fastlaneプラグイン
- Ruby gemのネイティブ拡張
- Node.jsパッケージがダウンロードするネイティブバイナリ
- GitHub Actionが内部で取得するCLIツール
実行ファイルのアーキテクチャはfileで確認できます。
file path/to/tool
Mach-Oバイナリに含まれるアーキテクチャはlipoでも確認できます。
lipo -info path/to/library.dylib
arm64が含まれていない場合は、arm64版への更新、Universal Binaryへの置き換え、ソースからの再ビルドが必要です。
Xcode 27ジョブを並行追加する
いきなり既存ジョブを置き換えるのではなく、Intelとarm64を並行実行します。
name: Xcode Compatibility
on:
pull_request:
workflow_dispatch:
jobs:
test:
strategy:
fail-fast: false
matrix:
include:
- runner: macos-26-intel
experimental: false
- runner: xcode-27
experimental: true
runs-on: ${{ matrix.runner }}
continue-on-error: ${{ matrix.experimental }}
steps:
- uses: actions/checkout@v6
- name: Show environment
run: |
echo "runner.arch=${{ runner.arch }}"
uname -m
sw_vers
xcodebuild -version
swift --version
- name: Build
run: |
set -o pipefail
xcodebuild \
-scheme YOUR_SCHEME \
-configuration Debug \
-sdk iphonesimulator \
build
この例では、既存のIntelジョブを正式な判定に残しつつ、Xcode 27ジョブを試験的に実行します。
continue-on-errorを設定しているため、Xcode 27ジョブだけが失敗してもPull Request全体をブロックしません。互換性問題を解消した後にexperimentalをfalseへ変更します。
キャッシュをアーキテクチャ別に分離する
Intel runnerで生成したキャッシュをarm64 runnerへ復元すると、ネイティブバイナリやビルド生成物が混在することがあります。
キャッシュキーには${{ runner.arch }}を含めてください。
key: dependencies-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/Package.resolved', '**/Podfile.lock') }}
次のようなキャッシュは特に分離が必要です。
- Swift Package Managerのビルド生成物
- CocoaPodsのビルド済みライブラリ
- DerivedData
- Ruby gemのネイティブ拡張
- Node.jsのネイティブモジュール
- 独自にコンパイルしたCLIツール
ソースコードやダウンロード済みアーカイブだけをキャッシュしている場合でも、展開後にアーキテクチャ依存ファイルが生成されないか確認します。
Homebrewのパスを固定しない
Intel環境を前提とした次のような記述は、arm64 runnerで問題になる可能性があります。
/usr/local/bin/tool
Homebrewのインストール先を直接書かず、brew --prefixを使います。
"$(brew --prefix)/bin/tool"
特定パッケージのパスを取得する場合は、次のようにします。
"$(brew --prefix openssl@3)/bin/openssl"
Xcode 27 imageのインストール済みソフトウェア情報でも、arm64向けHomebrew配下のパスが使われています。(GitHub)
simulatorを固定しすぎない
runner imageの更新により、インストールされるSimulatorやデバイス名が変わることがあります。
利用可能なSimulatorはジョブ内で確認できます。
xcrun simctl list devices available
次のように特定端末名を固定している場合は注意が必要です。
-destination 'platform=iOS Simulator,name=iPhone 17 Pro,OS=27.0'
Xcodeのbeta更新によってOSバージョンやSimulator構成が変わると、destinationが見つからず失敗します。
厳密な端末指定が不要であればOS=latestを使い、必要な場合のみ特定バージョンを固定します。
-destination 'platform=iOS Simulator,name=iPhone 17 Pro,OS=latest'
arm64移行で発生しやすいエラーと対処法
| エラー・症状 | 主な原因 | 対処法 |
|---|---|---|
Bad CPU type in executable | 実行ツールがx86_64専用 | arm64版またはUniversal版へ更新する |
incompatible architecture | ライブラリにarm64 sliceがない | arm64対応XCFrameworkなどへ置き換える |
Undefined symbols for architecture arm64 | リンク対象がarm64非対応 | 依存ライブラリの対応アーキテクチャを確認する |
| Actionの開始直後に失敗する | コミュニティAction内のバイナリが非対応 | arm64対応版へ更新するか別Actionへ変更する |
command not found | インストール済みツールやパスが従来imageと異なる | 必要なツールを明示的にインストールする |
| キャッシュ復元後だけ失敗する | Intel用キャッシュが混在 | キャッシュキーにrunner.archを追加する |
| Simulatorが見つからない | デバイス名やランタイムが変わった | simctl listで利用可能な環境を確認する |
xcode-27-xlargeが開始されない | larger runnerの権限、課金、同時実行数の問題 | Organization設定と利用上限を確認する |
GitHub公式Actionはarm64対応とされていますが、コミュニティActionについては互換性が保証されません。Action自体がJavaScriptやComposite形式でも、内部でx86_64専用ツールをダウンロードしていることがあります。(GitHub Docs)
xcode-27-xlargeを選ぶ際の注意点
xcode-27-xlargeは、ラベルの末尾がxlargeであることからも分かるように、macOS larger runner向けです。
通常のxcode-27から変更する前に、次の点を確認してください。
- Organizationまたはリポジトリでlarger runnerを利用できるか
- 課金情報が登録されているか
- GitHub Actionsの支出上限が0になっていないか
- 対象リポジトリにrunnerの利用権限があるか
- 同時実行数の上限に達していないか
- ジョブ開始までの待ち時間を許容できるか
larger runnerは、標準runnerよりも割り当てに時間がかかる場合があります。GitHubのドキュメントでは、有効な課金情報や0より大きい支出上限が必要になるケースも案内されています。(GitHub Docs)
また、arm64 macOS runnerには固定UUID・UDIDが割り当てられません。固定UDIDを前提に開発用プロビジョニングプロファイルを管理している場合は、署名方法を見直すか、Intel runnerを維持する必要があります。(GitHub Docs)
Intel runnerを維持すべきケース
次のいずれかに当てはまる場合、Intel runnerをすぐに廃止しない方が安全です。
- ベンダー提供ツールにarm64版がない
- x86_64専用のコード生成ツールを実行している
- 古いバイナリフレームワークを使用している
- Intel向けmacOSアプリの実行テストが必要
- 固定UDIDを利用する署名工程がある
- public previewを正式リリースの必須条件にできない
- コミュニティActionのarm64対応を確認できていない
この場合は、役割を分割します。
jobs:
xcode27-compatibility:
runs-on: xcode-27
continue-on-error: true
steps:
- uses: actions/checkout@v6
- run: ./scripts/build-and-test.sh
stable-release:
if: github.ref == 'refs/heads/main'
runs-on: macos-26-intel
steps:
- uses: actions/checkout@v6
- run: ./scripts/release.sh
Xcode 27では互換性確認を行い、正式な署名・配布は既存Intel runnerで継続します。
ただし、これは恒久対応ではありません。既存macOS imageには個別の廃止スケジュールが設定される可能性があるため、runner-imagesリポジトリのAnnouncementやGitHub Changelogを定期的に確認してください。GitHubは、イメージ廃止時に告知、段階的なbrownout、最終廃止という手順を取る方針を示しています。(GitHub)
Xcode 27 runnerへの移行判断
Xcode 27をCIで試すだけなら、最初に行う変更はruns-on: xcode-27の追加です。ただし、既存ジョブを直接置き換えるのではなく、Pull Requestで非ブロッキングの互換性テストとして並行実行します。
移行後は、次の順序で確認すると問題を切り分けやすくなります。
runner.archがARM64になっているか確認するxcodebuild -versionで実際のXcodeを記録する- x86_64専用の実行ツールを洗い出す
- バイナリフレームワークにarm64が含まれるか確認する
- GitHub Actionとネイティブ依存のarm64対応を確認する
- キャッシュをIntelとarm64で分離する
- Xcode 27ジョブを安定化してから必須チェックへ変更する
Xcode 27を使う公式な対応は、workflowをarm64対応にしたうえでxcode-27またはxcode-27-xlargeを指定することです。Intel専用依存をすぐに解消できない場合は、Xcode 27の互換性確認だけをarm64で実行し、既存Intel runnerを並行維持する構成が現実的です。

コメント