GitHub Actions: xcode-installで追加したiOSをキャッシュする
GitHub Actionsを使って継続的にUITestを実行する際、古いiOSや特定のiOSで動作確認をしたい場合があります。しかし、GitHub ActionsのmacOS環境にインストールされているXcodeには複数のiOSが用意されていません。[1] 代わりにxcode-install
がプリインストールされているため、xcversion simulators --install
を用いて任意のiOSをインストールすることができます。
ただ、Simulator用のiOSは圧縮された状態でも5GB前後(展開すると10GBを超えるものも)あるため、xcode-install
でインストールするにも10分から20分ほどかかります。また、xcode-install
にキャッシュする仕組みはないため、workflow実行のたびにxcode-install
でインストールすることになり非効率です。
そこで、今回はGitHub Actions公式のactions/cacheを用いてxcode-install
で追加したiOSをキャッシュする方法を検討しました。(なぜか前例が全然出てこなかった)
actions/cacheの仕様
- 1リポジトリあたり最大で10GBまでキャッシュ可能
- 10GBを超える場合は古いキャッシュから消されていく
- 1週間以内に使われなかったキャッシュは随時消されていく
- actions/upload-artifactとは違い保存と取り出しが高速(恐らく別サーバーのストレージにアップロードするわけではないため)
キャッシュする仕組みの要点
- Simulator用のiOSの実体は
iOS バージョン.simruntime
という名前のディレクトリ - 後から追加した
simruntime
は/Library/Developer/CoreSimulator/Profiles/Runtimes
に格納される- ここにあるsimruntimeが読み込まれて自動的にiOS Simulatorで使えるようになる
-
simruntime
は単体で10GBを超えるほど大きいためそのままではキャッシュできない- zipで圧縮してファイルサイズを小さくしてからキャッシュする
actions/cache
の上限を踏まえると、一つのリポジトリでキャッシュ運用できるiOSは1バージョンだけとなりそうです。特にSwift Package Manager
やCocoaPods
などでライブラリを使っておりそれもキャッシュするとなると上限の10GB以内に複数のiOSをキャッシュすることはできないでしょう。
Workflowの例
Xcode 13.2.1にiOS 14.5をインストールする例を示します。[2]
name: Dispatch Workflow
on:
workflow_dispatch:
jobs:
setup-ios-14:
name: Setup iOS 14.5 to Xcode 13.2.1
runs-on: macos-11
timeout-minutes: 30
env:
DEVELOPER_DIR: "/Applications/Xcode_13.2.1.app/Contents/Developer"
RUNTIMES_DIR: "/Library/Developer/CoreSimulator/Profiles/Runtimes"
steps:
- name: Checkout
uses: actions/checkout@v2
# Zipがキャッシュしてあれば取り出す
- name: Cache simruntime
id: cache-simruntime
uses: actions/cache@v2
with:
path: ios_14.5_simruntime.zip
key: ${{ runner.os }}-simruntime
# キャッシュから取り出したZipを展開
- name: Unzip simruntime
if: steps.cache-simruntime.outputs.cache-hit == 'true'
run: |
sudo mkdir -p ${RUNTIMES_DIR}
sudo unzip ios_14.5_simruntime.zip -d ${RUNTIMES_DIR}
# xcode-installを用いて指定のiOSをインストール
- name: Install simruntime
if: steps.cache-simruntime.outputs.cache-hit != 'true'
run: |
xcversion simulators --install='iOS 14.5'
ls -d ${RUNTIMES_DIR}/* | xargs -Ipath du -s -m "path"
# この段階で追加したiOSが使えるようになる
- name: List up simulators
run: |
xcrun xctrace list devices 2>&1 | \
grep -v Apple | \
sed -r "s/Simulator //g"
# ワークフローのJobが終わる前に指定のパスにZipを用意しておくとキャッシュしてくれる
- name: Zip simruntime
if: steps.cache-simruntime.outputs.cache-hit != 'true'
working-directory: ${{ env.RUNTIMES_DIR }}
run: |
ls -1 -d * | head -n 1 | \
xargs -Ipath zip -r ${{ github.workspace }}/ios_14.5_simruntime.zip "path"
ポイント
-
actions/cache
の@v2
を使う-
@v3
は2GB以上を一度にキャッシュできない不具合がある?[3]
-
- 初回のWorkflow実行時間はiOSをインストールするのとZipで圧縮するので非常に時間がかかる
- 2回目以降はキャッシュから取り出すのとUnzipで展開する時間しかかからないので時短できる
- キャッシュがあった場合となかった場合でやるべき処理を分岐している
if: steps.cache-simruntime.outputs.cache-hit == 'true' if: steps.cache-simruntime.outputs.cache-hit != 'true'
-
xcversion simulators --install
を一度もしていない場合/Library/Developer/CoreSimulator/Profiles/Runtimes
のディレクトリは存在しない -
/Library
の下にディレクトリを作ったりUnzipでファイルを展開する場合はsudo
が必要
iOSをインストールするJobと使うJobを分ける場合
name: Dispatch Workflow
on:
workflow_dispatch:
env:
DEVELOPER_DIR: "/Applications/Xcode_13.2.1.app/Contents/Developer"
RUNTIMES_DIR: "/Library/Developer/CoreSimulator/Profiles/Runtimes"
jobs:
# iOSを追加するフェーズ
setup-ios:
name: Setup iOS 14.5 to Xcode 13.2.1
runs-on: macos-11
timeout-minutes: 40
strategy:
fail-fast: false
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Cache simruntime
id: cache-simruntime
uses: actions/cache@v2
with:
path: ios_14.5_simruntime.zip
key: ${{ runner.os }}-14.5-simruntime
- name: Install simruntime
if: steps.cache-simruntime.outputs.cache-hit != 'true'
run: |
xcversion simulators --install='iOS 14.5'
ls -d ${RUNTIMES_DIR}/* | xargs -Ipath du -s -m "path"
- name: Zip simruntime
if: steps.cache-simruntime.outputs.cache-hit != 'true'
working-directory: ${{ env.RUNTIMES_DIR }}
run: |
ls -1 -d * | head -n 1 | \
xargs -Ipath zip -r -q -7 ${{ github.workspace }}/ios_14.5_simruntime.zip "path"
# 追加したiOSを利用するフェーズ
use-installed-ios:
name: Use installed iOS
runs-on: macos-11
needs: [setup-ios]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Cache simruntime
id: cache-simruntime
uses: actions/cache@v2
with:
path: ios_14.5_simruntime.zip
key: ${{ runner.os }}-14.5-simruntime
# キャッシュが存在していなかったら何もできないので失敗扱い
- name: Exit if cache does not exist
if: steps.cache-simruntime.outputs.cache-hit != 'true'
run: exit 1
- name: Unzip simruntime
run: |
sudo mkdir -p ${RUNTIMES_DIR}
sudo unzip -q ios_14.5_simruntime.zip -d ${RUNTIMES_DIR}
- name: Look up simulators
run: xcrun xctrace list devices 2>&1 | grep -v Apple
Author And Source
この問題について(GitHub Actions: xcode-installで追加したiOSをキャッシュする), 我々は、より多くの情報をここで見つけました https://zenn.dev/kyome/articles/a202cec702a1fe著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol