iOS CI (Jenkins + Phabricator + Slack)
Install Jenkins with brew install jenkins
in the shell
Then start Jenkins, enter 127.0.0.1:8080
in the browser
Install the xcode
related plugins in Jenkins
The steps are available in other blogs, Google “ios ci continuous integration“, for example:
- Setting up CI Environment with Jenkins+Github+Testflight on Mac
- Continuous Integration of iOS Projects with Travis CI
The versions may be a bit outdated, but it should do.
For our use, we have Phabricator installed locally on a Mac instead of a server since it’s an iOS project, so setting up the private key is sufficient. We don’t need to worry about Jenkins and Phabricator callback interaction.
In addition, we encountered several problems:
jenkins.plugins.slack.ActiveNotifier hudson.model.listeners npe
Sending test messages worked fine.
I spent two hours trying to resolve it, but I didn’t know what the problem was. After a good night’s sleep, it was back to normal the next day…
It seems that I know the reason now, the Project Channel can’t be empty.
ResourceRules.plist
On the first day, it complained that ResourceRules.plist was incorrect, so I added it to both the project and Jenkins configuration.
Custom xcodebuild arguments $(SDKROOT)/ResourceRules.plist
The next day, it complained that it couldn’t find ResourceRules.plist, but removing it in Jenkins made it work. Really strange.
iPhone Developer: no identity found
swift-stdlib-tool failed with exit code 1
I downloaded various certificates from developer.apple.com, but none of them worked.
Without any other options, I directly opened the project under ~/.jenkins/jobs/****
with Xcode to compare. I found that there was an additional certificate in the keychain, and then it succeeded.
Also, we haven’t purchased the enterprise account yet, and Jenkins doesn’t have an account system, so we continue to wait for the pit.
DUNS (Dun & Bradstreet Number)
The enterprise account was stuck here before, and Apple’s email response was delayed, so we must call Apple customer service. It was resolved within one or two days.
Bundle Identifier
Previously, the company account had occupied .alpha
and .beta
, and the enterprise account couldn’t create the same certificate. So I had to either delete the original account or change the ID.
When I tried to delete it, I realized that the app needed to be in a few specific states. Official documentation: TransferringAndDeletingApps
Since beta was already used for TestFlight and it hadn’t been uploaded to the App Store, I emailed Apple and got the following response:
Currently, your app does not have at least one approved version.
…
So I had to change the ID.
Over-the-Air Distribution
I finished all the preparations and quickly exported it, but I found that after Xcode 6, exporting an IPA only gave me an .ipa file without an accompanying .plist file. I had to write it myself (fortunately, Jenkins can generate it automatically). It looks something like this: plist (change the corresponding value in the $ $
placeholders)
Then, $ python -m SimpleHTTPServer
, open it with Safari on the iPhone, but… it still didn’t work…
Later, I found out that the server must be https…
Build Number
targets -> Build Phases -> + New Run Script Phase
1 | buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}") |
In this way, when the scheme is release, the build will automatically increment by 1.
PS:
Actually, this can be written in the shell of the Jenkins build step, then push it to origin/master and upload the *.ipa file to the server.
OS X Server
Pit, I will organize it when I have time.
DistributionProvisioningProfiles
Directly specifying the path for the downloaded *.mobileprovision
file didn’t work, so I had to manually package it.
1 | xcodebuild -exportArchive -exportFormat IPA -archivePath "$Yourarchive" \ |
Summary:
It was a path full of pits.
Translated by gpt-3.5-turbo