概要
iOSアプリ開発のCI/CDを行うときは、xcode buildやfastlaneでビルドやテストを行うと思います。その際にプロジェクト(ワークスペース)が参照しているSwift Packageがなかなか狙い通りに解決されなかったため、備忘録として残します。
とりあえず結果
結論としてはxcodebuildやfastlaneのパッケージ解決の方法では難しいことがわかりました。Package.resolvedやDerivedDataを削除しても謎のファクターXを参照して、古いリビジョンを解決してしまいます。
最新リビジョンを取得するワークアラウンド
そのプロジェクトがSPMでない場合でも、Package.swiftを用意し、そこにSPMのパッケージを書きます。
で、アップデートして、Package.resolvedを移動させます。
// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "Hoge",
platforms: [
.iOS(.v14),
],
dependencies: [
.package(name: "Hoge", url: "https://xxxxxxxxx",
.branch("master"))
]
)
swift package update
mv Package.resolved Hoge.xcworkspace/xcshareddata/swiftpm/
bundle exec fastlane tests
この場合、Package.resolvedを参照してほしいので、fastlaneの場合は、disableAutomaticPackageResolutionを有効にします。
run_tests(..,
xcargs: "-disableAutomaticPackageResolution",
...
)
これで最新版をなんとか解決できました!
パッケージ解決に関与してそうなパラメータ
Package.resolved
XXX.xcodeproj/xcshareddata/swiftpm/Package.resolved
というパスにあるファイルです。基本的にこのファイルがある場合は、このファイルに記載されているリビジョンのものがチェックアウトされますが、無視する設定もできるようです。
DerivedData
いわゆるビルド時の中間ファイルです。これがあると最新を取得してきてくれないことがあります。 このパスは指定することができるようで、fastlaneだとcloned_source_packages_path
というパラメータで指定することができます。xcodebuildだとclonedSourcePackagesDirPath
というパラメータです。
resolvePackageDependencies
xcodebuild
コマンドに渡すパラメータです。このパラメータの挙動を正確に把握していないのですが、プロジェクトAがSwiftPackageBとSwiftPackageCをxcodeproj
で参照しており、SwiftPackageBがSwiftPackageCを参照していた場合、プロジェクトAが参照するプロジェクトCのバージョンは、プロジェクトBのPackage.Swiftのバージョンになる、という挙動をしました。
というところまでは調べたのですが、ファクターXがなんなのかが結局わかりませんでした。