potatotips #77で「RenovateによるiOSライブラリーの自動更新」という発表をしました&いくつかの補足
発表資料はこちらです 👇
発表の中では時間の都合で触れられなかったところをいくつか補足しようと思います。
CocoaPodsでRealmを使っているとPodfile.lock
が更新できない件
Renovateの実行環境はDockerコンテナの中のUbuntuです。Renovateは Podfile
を書き換えた後に pod install
を実行してPodfile.lock
を更新します。CocoaPodsはLinuxで動くのか?と思われるかもしれませんが、pod
gem(や依存の xcodeproj
)もLinuxで問題なく動作するようです。ほとんどのライブラリーは問題ないのですが、Realmのpodspecには少し特殊なところがあります。
s.prepare_command = 'sh scripts/setup-cocoapods.sh'
podspecのprepare_command
でスクリプトを実行しています。そのスクリプトではrealm-coreをダウンロードしているのですが、その先頭でset -euo pipefail
としており、bashではなくshだとエラーになってしまいます。
build.sh: 13: set: Illegal option -o pipefail
さらにここをbashで実行したとしてもスクリプト内部でxcode-select
コマンドが使われているので、どちらにせよ詰んでしまいます。
ここで我々ができることは、発表のSwiftPMの箇所で「Package.resolved
の更新に非対応」でも触れた
- PRに自分で追いコミットをするか、もしくは
- CIで(例えばGitHub Actionsで)更新するワークフローを用意する
という感じになりそうです。
on: pull_request: paths: - Podfile jobs: precheck: runs-on: ubuntu-latest outputs: files_changed: ${{ steps.file_changes.outputs.files }} steps: - uses: actions/checkout@v3 - id: file_changes uses: trilom/file-changes-action@v1.2.4 update: runs-on: macos-latest needs: precheck if: contains(fromJson(needs.precheck.outputs.files_changed), 'Podfile.lock') == false steps: - ...
CocoaPodsとXcodeGenを併用しているとPodfile.lock
が更新できない件
XcodeGenを使用していると、通常生成したXcodeプロジェクトはリポジトリにコミットせず、CIでも初期セットアップでコマンドを実行してXcodeプロジェクトを生成すると思います。これがRenovateでは困ったことになります。Renovateの実行時に任意の初期化処理を挟むことができず(そもそも実行環境にXcodeGenも存在しない)、Xcodeプロジェクトが存在しないままだとpod install
の実行に失敗してしまうためです。
これを回避する手段として、CocoaPodsの:integrate_targets
という設定を使用できます。Podfile
のルートではinstall!
というオプションを設定することができます。その引数に :integrate_targets => false
と指定することで、Xcodeプロジェクトへの組み込みステップが省略されるため、Xcodeプロジェクトがなくても pod install
を実行できるようになります。
この設定をRenovateでの実行時だけ有効にするように、以下のようにハックします。
is_running_in_renovate = ENV['HOME'] == '/home/ubuntu' if is_running_in_renovate # Renovateでの実行時にはXcodeGenが実行できず、xcodeprojが存在しないので `:integrate_targets => false` とする。 install! 'cocoapods', :integrate_targets => false else install! 'cocoapods' end
ただこの設定には注意点があり、:integrate_targets => false
だとアプリが使用しているSwiftのバージョンをXcodeプロジェクトから抜き出すことできなくなり、ライブラリー側のビルド設定のSWIFT_VERSION
が設定されなくなってしまいます。
これも回避策があり、Podfile
内の各ターゲットで current_target_definition.swift_version = '5.0'
と明示的に定義してしまえば問題ありません。
target 'FooBarApp' do # https://github.com/CocoaPods/CocoaPods/issues/8653#issuecomment-488767262 current_target_definition.swift_version = '5.0' ... end
おわりに
モバイルアプリ開発でもどんどんRenovateを活用していきたいですね!!
その他の方の発表資料はconnpassのページからどうぞ!