command fails on jenkins, but works on terminal - jenkins

I'm working on using fastlane screengrab/snapshot to take screenshots of my android and ios app. When I run them locally on terminal, they work perfectly, but when I run them from jenkins, they fail. I'm using macOS.
Android:
/Users/shared/Library/Android/sdk/tools/emulator -avd Pixel_API_22 &
fastlane screengrab
(These 2 are in a .sh)
The first line failed: PANIC: Cannot find AVD system path. Please
define ANDROID_SDK_ROOT
iOS:
fastlane snapshot
it failed while trying to build a test because of an provisioning profile error:
xcodebuild -showBuildSettings -scheme UITests -project ./abc.xcodeproj
(this is a command that fastlane snapshot execute automatically)
Again, they both run smoothly on terminal (I ran them in the same workspace as junkins)

Double-check the environment settings after executing your job in Jenkins: you might see differences with the same environment settings as seen with your user account in command-line (where it is working)
The username might be different (if your Jenkins server/agent runs with another account).
The OP Son Nguyen confirms the PATH issue:
the developer who set up jenkins put a wrong path to android sdk, so I was able to run the android part by fixing the path.
And the OP adds:
fastlane was installed in /usr/local/bin while jenkins was in /User/myUser: So, somehow they didn't work well together.
I reinstalled fastlane in /User/myUser and it worked.

This got it working for me.
I had to include this at the top of my script :
#!/bin/zsh
source ~/.zshrc
and my .zshrc had this:
export PATH="$PATH:"/usr/local/bin/
export SSL_CERT_FILE=/etc/ssl/cert.pem # for openssl error
export ANDROID_HOME=/Users/jenkins/Library/Android/sdk

Related

Self Hosted Agent on macOS not working with Azure Pipeline

This is an issue I've been facing for the past week.
I have an M1 Mac Mini setup as a self-hosted agent to run iOS related builds/archives through Azure Pipelines.
I'm able to build/archive locally on the machine itself using terminal. Mobile provisioning and code signing are setup and working fine.
When I run the agent interactively using run.sh, I am able to run the pipeline successfully. When I try running the agent as a launchd service using ./svc.sh install -> ./svc.sh start, it always fails with the same error:
** ARCHIVE FAILED **
The following build commands failed:
ValidateEmbeddedBinary /Users/<user>/Library/Developer/Xcode/DerivedData/<project>/Build/Intermediates.noindex/ArchiveIntermediates/<app-name>/BuildProductsPath/Debug-iphoneos/<app-name>.app (in target '<app-name>' from project '<project>')
(1 failure)
##[error]Bash exited with code '65'.
The command I'm using to archive is
xcodebuild -workspace ~/repos/<project>/<project>.xcworkspace -scheme <app-name> -allowProvisioningUpdates clean archive -archivePath build/<app-name> -destination generic/platform=iOS
Again, this command works when I run it locally and when I run the agent interactively.
I removed app/project names for privacy reasons.
I've searched high and low as to why this error is occurring and I've tried virtually all suggestions to fix it. For the life of me I don't know why the command would work locally and when the agent is run interactively, but does not work when the agent is run as a launchd service.
Edit: I’ve noticed a pattern: the archive fails with that error after every successful run. In other words the command successfully archives but when I run it again, it fails. If I run it once more, it’s successful. This occurs when running it through Azure Pipelines and locally via terminal. I have no words!

Flutter iOS command line build with --profile flag fails but release mode works (both on real device)

I've had this issue for a while now and now that Flutter 2.5 is out, have much more of a need to fix it. I'm trying to build Flutter in profile mode to take advantage of the shader SkSl warmup and reduce runtime jank on iOS (https://flutter.dev/docs/perf/rendering/shader).
The crux of the problem: I get a "No Provisioning Profile was found for your project's Bundle Identifier or your device." error when building to a real device with the "--profile" flag, but building in release mode works fine. To illustrate this:
Working: flutter run --flavor prod -t "lib/main.dart"
Not working: flutter run --profile --flavor prod -t "lib/main.dart" --cache-sksl --purge-persistent-cache
According to the Flutter documentation, the profile flag runs in a slightly modified release mode, so I'm not sure why the build fails.
A couple more details:
I'm using Fastlane Match for provisioning profiles. There's a corresponding "Profile-prod" configuration in XCode which uses the same provisioning profile and bundle identifier as the main production release configuration.
I also have dev and stage build flavors which build to the device fine using a command such as flutter run --flavor stage -t "lib/main_stage.dart"
I've also tried flutter run --profile --cache-sksl --purge-persistent-cache as explicitly mentioned in the documentation but that also fails with the same error
Any suggestions are appreciated!

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/

Xcode command line install to device

I am trying to install an app from XCode onto my device from the command line. I have tried several of the "xcodebuild" command line options which do build, clean, install, etc fine. I have also searched for various solutions.
I was able to execute this command but it just builds to a folder.
xcodebuild install -scheme "My App" -destination 'platform=iOS,id=mydeviceid'
I am able to take that folder from my hard drive and sync to the physical device using iTunes so all the build steps are being completed successfully. However, it does not "run" on the device like when Build and Run are executed in XCode.
There are some 3rd party solutions but I can't believe there isn't some native xcodebuild switch to do that. Does anyone have suggestions?
Thank you
There is no native xcodebuild switch to install to a device.
You need to fallback to third-party options:
$ brew install ideviceinstaller
ios-deploy
You can try to use Apple Configurator 2 (available in the App Store) and install the cfgutil command line tool.
.
Ignore the fact that ^ says "Uninstall Automation Tools...", if you haven't installed already, it will say "Install Automation Tools...".

Showing the build command Xcode uses

Is there a way to see the xcodebuild command that Xode uses for building?
I have created a library file with Xcodebuild command from Terminal. But there are some differences between the files generated from terminal and Xcode UI.
I use this behavior to switch to the log when building starts.
.
In the log you can find all the commands Xcode is executing.

Resources