Jenkins - command line build iOS project - ios

I have an iOS project cloned from repo into my jenkins account. Xcode is not yet installed. I know command line scripts to build an iOS project including targets/configurations/profiles etc. Certificate and provisioning profile is installed in jenkins account. I am wondering if there is a way to build and create ipa without installing Xcode in jankins account. Does apple provide any developer tools for building and creating IPA through command line only?
Advance thanks

Every building option for iOS apps requires Xcode, but apple does provide tools for building via CLI. A ton has changed in the most recent iOS OS upgrade and there are incredible tools out there for CI/CD app delivery. What you end up using should really depend on what you want to maintain over time and how advanced your system needs to be.
To get Builds working in Jenkins
Step 1 : Install Xcode on the Jenkins node that will be doing the builds. You wont be using the Xcode UI but you will need it installed, there is currently no way to build IPAs without Xcode.
Step 2: Choose your build tool
You could write your own build scipts and manage provisioning profiles on the machine. xcodebuild is the CLI tool you are looking for. If you end up going down this route make sure to use xcpretty or you will loose your mind with giant build logs.
Fastlane is an amazing toolset for building mobile apps, it might change your life. Check out these examples and how to get started.
Apple has an xcode build server that Jenkins could possibly talk to.
The first two in this list do a good job of managing provisioning profiles out of the box, and that can save you major headaches down the road if you need to scale

Related

Running Fastlane Gym build in Rosetta

We have a new M1 MacMini that we want to use for CI/CD purposes. Our main issue is that we have a really old external dependency that doesn't allow us to build the app for the simulator on ARM architecture. We managed to make it build on this machine by running Xcode in Rosetta mode. So as long as we use Rosetta mode with Xcode we can run the app on the simulator with no issues.
Our problem is that we are using Fastlane gym to build the app in our CI/CD flow, so Xcode doesn't run in our flow. We did a lot of research but didn't manage to find a solution that fits our needs.
The question is: Can Fastlane gym run with Rosetta?

Is it possible to setup Continuous Integration & Continuous Deployment for iOS app development?

I am looking for a way to setup Centralized Continuous Integration and Continuous Deployment for iOS app development. Just like how we do it for Maven or Gradle builds.
I found couple of articles which explains how to achieve this, but for all them are using Xcode to build the iOS application. The key here is Xcode will run only on MacOS.
I found Jenkins Xcode plugin, but it clearly tells,
Obviously, the build machine has to be an OSX machine with XCode
developer tools installed.
Even if we are making one of the developer's OSX machine as Jenkins agent, we can't guarantee that developer's OSX machine will be always connected to Jenkins master. What if somebody else want to build the app and the OSX machine running Jenkins agent is not available?
I found fastlane, but that also seems to automate some of the manual steps like taking screenshots, code signing, releasing the app. It has to be run on only the developers machine if I am not wrong.
What is the generic approach people use to achieve this?
For CI/CD you can use remote build server like AppCenter from Microsoft (https://appcenter.ms/) or other.
And, obviously, without mac machine to build app you can't build your own system CI/CD. Unfortunately, developer can't build app without Apple Machine.
It is main problem for iOS development.
In this case, android is better.

Flutter: Building and distributing a .ipa File without Mac/Apple Developer Account?

I'm new to Flutter and Travis CI, so im having minor problems setting up the following. From what i read, it should be possible, but im not sure how exactly.
My current setup uses my existing Travis CI account, to build all my changes using flutter build ios --no-codesign. This generally works and should output a Runner.app-File.
My aim now is, to transform this File into a usable .ipa, which i can distriute to my personal iPhone/iPad via www.diawi.com.
I know that it is generally possible, to make Travis CI to commit results back to github, and i also know, that it should be possible, to build/create an .ipa from the .app file using the CLI of XCode.
Can someone help/hint me with building a full build.sh, which performs the flutter build, the xcode build, the ipa-extraction and the push of the .ipa to git?

Building an iOS app with Jenkins

I want to automate the iOS app building process that currently is totally manual on a desktop computer (Mac). A central build server Hudson/Jenkins, running on a Gnu/Linux machine, is already available inside the organization infrastructure.
Is it possible to build this iOS app with Jenkins, using tools like Jenkins distributed builds (and so configuring a Mac machine as a slave)?
Do you have any example, know any technique or alternative to do this?
Yes its possible. We are doing this and it works fine. You could configure a Xcode-slave within Jenkins by choosing the Xcode-plugin. There are tons of nice tutorials on the web.
Check out this one for starters.
I finally got my Jenkins Job up and running after toiling away for longer than I wanted using the only tutorials that I could find which all happened to be from 2015 or earlier unfortunately. So I posted a real quick checklist of stuff I did to successfully setup the Mac slave on a local Mac mini within my company. Similar to you #lifeisfoo my organization currently has a Jenkins instance running on an outside server.
The link for setting up a Mac slave as per 2018 is seen here.
Setting up jenkins slave on Mac OS
In terms of setting up a Jenkins Job after the node is successfully created and Launch Agent connects properly to your Mac slave from your Jenkins instance see below:
For the most part setting up a New Item a.k.a. New Job from the Manage Jenkins section is self explanatory
Most of the older tutorials are accurate in that you need some plugins Github, Keychains and Provisioning Profiles Management (still not 100% that you need this plugin though but still good to have and set it up) and others I downloaded and installed but never used including I did not use the Xcode plugin in the Build section of the Job setup.
Make up a project name, check Github project and add the url ending in .git/, restrict this project to the Node you created for the Mac slave, in Source Code Management we used Git and I added the url again (ending in .git without the "/" this time, created new credentials with my username and password, */main in the branches to build section, added Github hook trigger url for GITScm polling to my organization's Github account web hooks section
In Build I only used Execute Shell and cd into /Users/jenkins/path/to/file
Currently it is NOT a workspace so the commands are as follows in Execute Shell
xcrun xcodebuild -project ProjectName.xcodeproj \
-configuration Release \
-destination 'platform=iOS Simulator,name=iPhone 6s' \
-allowProvisioningUpdates \
CODE_SIGN_STYLE='Automatic'
PROVISIONING_PROFILE_SPECIFIER=${PROVISIONING_PROFILE}
CODE_SIGN_IDENTITY=${CODE_SIGNING_IDENTITY}
As of February 2018, I have changed it to workspace because of the need to include some cocoa pod SDKs hence I now use the below combination of "Execute Shell"s.
The below script is to run a pod install every time (because I added Pods/ to the gitignore file only pushing Podfile and Podfile.lock to the repository which Jenkins pulls from)
cd /Users/jenkins/Desktop/projectFileWhere.xcworkspaceExists
/usr/local/bin/pod install
The below is to run the project build in another "Execute Shell"
xcrun xcodebuild -workspace ProjectName.xcworkspace \
-scheme NameOfScheme \
-configuration Release \
-destination 'platform=iOS Simulator,name=iPhone 6s' \
-allowProvisioningUpdates \
CODE_SIGN_STYLE='Automatic'
PROVISIONING_PROFILE_SPECIFIER=${PROVISIONING_PROFILE}
CODE_SIGN_IDENTITY=${CODE_SIGNING_IDENTITY}
Note:
- I wasn't sure whether it was absolutely necessary but I made sure to clone the latest GitHub repo into my Mac slave machine into the same project directory where the .xcodeproj existed before.
- I also foolishly didn't realize at first that .xcworkspace was NOT getting pushed to my GitHub repo because build/*.xcworkspace was still in my gitignore file. Removed it, re-pushed to repo and cloned to Mac slave and it was all gravy baby
I saw many variations of CODE_SIGN_IDENTITY and some that specifically told me to add parameters like DEVELOPMENT_TEAM= and DISTRIBUTION_TEAM= but those weren't necessary.
Frankly speaking I don't know if -allowProvisioningUpdates nor CODE_SIGN_STYLE='Automatic' is necessary but its working for me.
I ended up going with the Execute Shell Build step and not the Xcode Plugin for Build parameters because I was able to more easily manipulate build parameters and test it against the errors I was getting in the console output of each build in my Jenkins instance. In the end there was also more and better documentation and help in trying to understand Xcodebuild with command line and that is essentially what Execute shell is doing hence I liked it better.
I wanted to write this post to point out what I finally did to make the job build and my issues in getting it to build were very easy to fix until this last one which was in that code signing couldn't find my provisioning profile for the certificate/team that I was using in Xcode's project file target and project:
I didn't use Fastlane or any other program. Just SSH connection into Mac slave.
Setup Xcode command line tools: xcode-select active developer directory error
1) In this Wiki I did what is stated in the paragraph directly under the title "Xcode project setup".
https://github.com/cyupa/JenkinsCI-iOS
2) You need to have both private and public key for a dev and distribution certificate on the Mac Slave in order to build through Jenkins to the Mac Slave. Need Provisioning Profiles on the Mac Slave for each of these accounts with the proper Bundle ID as well.
https://blog.noser.com/streamlining-ios-development-with-jenkins-and-wireless-app-distribution-2/
3) Move the keychains and certificates for both dev and distribution to Login or whatever other unique keychain you created but for each private key, right click (two finger tap) the private key and Get Info -> Access Control -> allow /usr/bin/codesign or all applications to access this item
4) In Build settings of the Xcode project on the Mac slave (make sure you've downloaded from your repo to the Mac slave and opened it once on the Mac Slave's Xcode app), change build settings to be automatic and/or just change it in General of the Target App and testing if you want.
5) The last piece of the puzzle to solve the problem that took me 2 days was to simply add my keychains to the security list so that Xcode could use the provisioning profiles for the certificates that it needed.
Not sure if what I suggested above regarding Access Control is necessary if you add the keychains to the security list but I kept it and its working for me. Maybe I'll experiment later and see what is actually needed and not needed but for now, this was the key. You may get "codesign failed with exit code 1" which is all the same thing. The terminal command to unlock is:
security list-keychains -s ~/Library/Keychains/{login, "any other keychains you want added to security list"}.keychain
Sooooo if you are seeing any build errors in Jenkins like.......
No profiles for 'com.organization.Target' were found: Xcode couldn't find any iOS App Development provisioning profiles matching 'com.organization.Target'
Code Signing Error: Code signing is required for product type 'Application' in SDK 'iOS 11.2'
.......then you know most likely its a keychain access thing and nothing else.
In hindsight I realize now that I saw this same advice in some other Stack posts and one or two other blog posts as linked below, but that wasn't my issue at the time so I totally forgot about it and now hate myself for not reading slower over these posts. Oh well. At least I'm getting a green circle now.
"User interaction is not allowed" trying to sign an OSX app using codesign
https://blog.noser.com/streamlining-ios-development-with-jenkins-and-wireless-app-distribution-2/

Can you upload a binary to iTunes connect using OS x server bot?

I am using Xcode 6.3.1 and an OS x Server.
is it possible to configure a bot to upload the binary to iTunes connect after successful build?
You can use Fastlane to upload your build directly to iTunes Connect, specifically using Deliver. You have to create an after integration script which will run a custom Fastlane lane where you need to call to deliver with the generated IPA file. Additionally you may need adding a before integration trigger in order to make some setup before the integration like installing CocoaPods dependencies and increasing the build number.
Recently I wrote a blog entry explaining the entire process of deploying your app to iTunes Connect using Mac Server 5, Xcode 7.2 and Fastlane. It may help you: https://blog.xmartlabs.com/2016/03/07/ci-with-xcode-server-and-fastlane/
Yes you can use application loader tool: altool --upload-app -f file -u username [-p password] [--output-format xml]
As described here: https://help.apple.com/itc/apploader/#/apdATD1E53-D1E1A1303-D1E53A1126
Prerelease and TestFlight distribution one click away make this a good idea in my opinion.
You should take look at Shenzhen which makes deploying to iTunes Connect really easy.
Then you just need two more scripts, one before to change the build number every time and one to execute Shenzhen on success.

Resources