Issue
I'm having an issue why trying to build a KMM project using a Jenkins pipeline and fastlane for the iOS part.
Kotlin version: 1.5.31
XCode version: 13.1
Fastlane version: 2.198.1
Ruby version: 2.6.3p62
When executing these steps locally it breaks as well. The Error that fastlane throws is import shared: no such module 'shared'
I figured out that if you run pod install && fastlane xcode_build
the build brakes, but if you repeat it a second time it succeeds and creates the project.app file in the DerivedData folder of XCode.
The Jenkinsfile is working correctly on another iOS project which is not a KMM one.
Here is the Jenkinsfile
pipeline {
options {
buildDiscarder(logRotator(numToKeepStr: '5', artifactNumToKeepStr: '5'))
}
environment{
FIREBASE_APP = 'some-app'
FIREBASE_TOKEN = 'some-token'
YOUR_CRED = credentials('KeychainPassword')
PROJECT_NAME = 'project'
}
agent any
stages {
stage("Build and Deploy") {
parallel {
stage("iOS") {
agent { label 'ios' }
stages {
stage('Unlock Keychain') {
steps {
sh 'security unlock-keychain -p ${YOUR_CRED} /Users/chocho/Library/Keychains/login.keychain'
}
}
stage("Build") {
steps {
dir("${PROJECT_NAME}-ios"){
sh "pod install"
sh "fastlane xcode_build"
}
}
}
stage("Archive") {
steps {
sh "cp -r ~/Library/Developer/Xcode/DerivedData/${PROJECT_NAME}-ios*/Build/Products/Debug-iphonesimulator/${PROJECT_NAME}-ios.app ./"
sh "zip -r simulator.zip ./${PROJECT_NAME}-ios.app"
archiveArtifacts artifacts: 'simulator.zip', fingerprint: true
}
}
stage('Clean'){
steps{
sh "rm -rf ~/Library/Developer/Xcode/DerivedData/${PROJECT_NAME}*"
}
}
stage("Upload") {
// when { branch 'develop' }
steps {
dir("${PROJECT_NAME}-ios/fastlane"){
sh "fastlane test_flight_develop build_number:${BUILD_NUMBER}"
}
}
}
}
post {
always {
sh "rm -rf ~/Library/Developer/Xcode/DerivedData/${PROJECT_NAME}-ios*"
cleanWs()
}
}
}
stage("Android") {
agent { label 'ios' }
stages {
stage("Clean") {
when { branch 'develop' }
steps {
sh './gradlew clean'
}
}
stage("Build") {
when { branch 'develop' }
steps {
sh "./gradlew assembleRelease -Pandroid.injected.version.code=${BUILD_NUMBER}"
}
}
stage("Archive") {
when { branch 'develop' }
steps {
sh "cp ${PROJECT_NAME}-android/build/outputs/apk/release/${PROJECT_NAME}-android*.apk ./${PROJECT_NAME}-android.apk"
archiveArtifacts "${PROJECT_NAME}-android.apk"
}
}
stage("Upload") {
when { branch 'develop' }
steps {
sh "firebase appdistribution:distribute \
${PROJECT_NAME}-android.apk \
--token ${FIREBASE_TOKEN} \
--app ${FIREBASE_APP} \
--groups 'group'"
}
}
}
post {
always {
cleanWs()
}
}
}
}
}
}
}
And here is the Fastfile that I use for fastlane
default_platform :ios
platform :ios do
lane :xcode_build do
xcodebuild(
scheme: schemeAndTarget,
workspace: schemeAndTarget + '.xcworkspace',
xcargs: "-configuration 'Debug' -sdk 'iphonesimulator15.0' -destination 'generic/platform=iOS Simulator'")
end
end
And here is the Podfile
target 'project-ios' do
use_frameworks!
platform :ios, '14.5'
pod 'shared', :path => '../shared'
pod 'R.swift', '5.4.0'
pod 'SwiftLint', '0.45.0'
end
My question is, since I'm not competent enough with KMM. Why is it doing that? How am I intended to build the project for CI/CD, if the above is not a competent way of doing it.
Solution
so I figured it out. If anyone has the same issue, the fix for this current problem is that you have to run a gradle task in the root directory of the project, before building the iOS part.
./gradlew generateDummyFramework
In my case with Jenkins I added sh './gradlew generateDummyFramework
before the sh 'pod install'
shell command in the Build stage. This fixed the issue in question.
The problem was caused from Cocoapods not being able to access the framework file, hence pod install
can't configure the framework correctly. The reason for the build to fail on the first build but not on the second is because the framework file is generated when you run a build in XCode. After that Cocoapods can configure the file correctly.
If anyone has a different answer I'm eager to know about it!
Answered By - K.Г.
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.