Recently, Jenkins+ Fastlane has been integrated into the company’s project to achieve continuous integration. This paper makes a record of the problems encountered, which will be listed at the end of the article and supplemented later. Record this.

Brief introduction:

Fastlane is a set of automation tools written in Ruby that combine different actions such as certificate management, build packaging, and so on. Thus forming a complete automated process. In addition, Jenkins is an open source automation server, which provides an automated platform for us to remotely pull codes and configure some information through Jenkins to realize automatic distribution, notification and other functions.

Fastlane installation and configuration

If you don’t have the Xcode command line tool installed,

xcode-select --install
Copy the code

Make sure gem Sources is https://gems.ruby-china.com/

localhost:Jenkins snailsleep$ gem sources
*** CURRENT SOURCES ***

https://gems.ruby-china.com/

Copy the code

If not please change:

Gem sources --remove currentsource
gem sources -a https://gems.ruby-china.com
Copy the code

Fastlane installation:

brew cask install fastlane
Copy the code

Check the version after installation

localhost:Jenkins snailsleep$ fastlane --version fastlane installation at path: / Library/Ruby/Gems/server/Gems/fastlane - 2.144.0 / bin/fastlane -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- [✔] 🚀 fastlane 2.144.0Copy the code

The next step is to CD into our project directory and execute

fastlane init
Copy the code

What do you want to do with Fastlane

app_identifier("* * *"."* * *"."* * *") # The bundle identifier of your app
apple_id("* * *") # Your Apple email address

team_id "* * *" # Developer Portal Team ID

# For more information about the Appfile, see:
# https://docs.fastlane.tools/advanced/#appfile
Copy the code

The main packaging script configuration is written in Fastfile. Different lanes are different tasks. We can create a new lane to do our packaging tasks (use *** instead of private content).

lane :qwer do ENV["FASTLANE_USER"] = "***" ENV["FASTLANE_PASSWORD"] = "***" cert( development: true, ) sigh( app_identifier: "com.***.***", readonly: false, cert_id: "***", development: true, ) sigh( app_identifier: "com.***.appwatchkitapp", readonly: false, cert_id: "***", development: true, ) sigh( app_identifier: "com.***.appwatchkitapp.watchkitextension", readonly: false, cert_id: "***", development: true, ) build_app( scheme: "***", export_method: "development", output_directory: "/Users/Shared/Jenkins/Home/workspace/IPAName", output_name: "IPAName", include_bitcode: false, configuration: "Debug", export_xcargs: "-allowProvisioningUpdates", destination: "Generic/platform = iOS") # upload can use dandelion and produce qr code, concrete https://www.pgyer.com/doc/view/fastlane # pgyer (api_key: "***", user_key: "***") endCopy the code

Since our project also includes watch, there are three app_identifiers, so we have carried out sighting for three times. The method for obtaining certid is posted at the end of this article.

Since we named the lane qwer, we can start packing by executing Fastlane qwer in the project directory

If it looks like this, you’ve packed successfully

Jenkins installation and configuration

Download the latest war package from Jenkins’ official website. Here I choose the Mac OS X version of LTS. After downloading, there will be a jenkins-2.204.2.pkg package

After the installation is successful, we will find the Jenkins folder in the Applications directory, which contains a jenkins.war file. We will go to this file directory to start Jenkins

    $ cd /Applications/Jenkins
    $ java -jar jenkins.war --httpPort=8080
    
Copy the code

Once Jenkins launches, we can go to the browser

    http://localhost:8080
Copy the code

We’ll see this interface

You need to enter the password. The password has been written in logs

Linux
By default logs should be made available in /var/log/jenkins/jenkins.log, unless customized in /etc/default/jenkins (for *.deb) or via /etc/sysconfig/jenkins (for */rpm)

Windows
By default logs should be at %JENKINS_HOME%/jenkins.out and %JENKINS_HOME%/jenkins.err, unless customized in %JENKINS_HOME%/jenkins.xml

Mac OS X
Log files should be at /var/log/jenkins/jenkins.log, unless customized in org.jenkins-ci.plist.
Copy the code

As described in the documentation, we go to /var/log/jenkins and find the jenkins.log file

After entering the Jenkins configuration home page for the first time, you will be asked whether you want to use the custom plug-in or the recommendation directly. Here you will directly select the one-click integration recommendation plug-in

After several retries, finally successful, will arrive at the following screen

Finally Jenkins is installed!

Here I select SSH Username with private key and fill in the private key (~/.ssh/id_rsa copy the private key content here), of course, the condition is to configure SSH in the code hosting platform, WHICH I have configured in Gitee.

In the “Build” TAB, you can add some scripts under “Add build Steps –Execute Shell”, as shown below

We can also upload packages and generate QR codes through the Dandelion Jenkins plugin, and notify everyone in the group using the enterprise wechat robot through the following script

curl 'Here is the Webhook address of the enterprise wechat group robot'
   -H 'Content-Type: application/json' \
   -d '{" msgtype ", "news", "news" : {" articles ": [{" title" : "iOS test package", "description" : "repair repair problem \ n * * * * * * problem", "url" : "***", "picurl" : "***", } ] } }'
Copy the code

✨ Possible problems and solutions

1. The bundle update is stuck after fastlane init

If you have changed your gem source as described at the beginning of this article, but it is still stuck, go to your project directory and find the Gemfile file

source "https://rubygems.org"

gem "fastlane"
Copy the code

Here we change the source again

source "https://gems.ruby-china.com"

gem "fastlane"
Copy the code

Then execute the bundle update in the current directory

Fastlane: Command not found

This is usually caused by Jenkins not setting the correct $PATH environment variable. The correct setting method is:

Run echo $PATH in the command line and record the output result. In Jenkins system Management – System Settings, find Environment variables and fill PATH in key. Fill in the value and save the output from the first step.

3. The PP file is clearly configured in FastFile, but you can’t find the PP file.

Such as:

Exit status: 70
[11:24:53]: No provisioning profile provided
[11:24:53]: Make sure to pass a valid provisioning for each required target
[11:24:53]: Check out the docs on how to fix this: https://docs.fastlane.tools/actions/gym/#export-options
Copy the code

Build_app add export_xcargs: “- allowoningupdates “(see lane section of fastfile in this article)

4. How to obtain certid?

require 'spaceship'

Spaceship.login('* * *')
Spaceship.select_team

Spaceship.certificate.all.each do |cert|
  cert_type = Spaceship::Portal::Certificate::CERTIFICATE_TYPE_IDS[cert.type_display_id].to_s.split("... "")[-1]
  puts "Cert id: #{cert.id}, name: #{cert.name}, expires: #{cert.expires.strftime("%Y-%m-%d")}, type: #{cert_type}"
end

Copy the code

Save the above script on your desktop, such as getCertid.rb, remember to change your developer account in Spaceship. Login, then CD it to your desktop on the command line and run

ruby getcertID.rb
Copy the code

Enter the developer password to get all certids

5. An error occurred during Jenkins startup because the port number was occupied

(base) localhost:Jenkins snailsleep$ java -jar jenkins.war --httpPort=8080
Running from: /Applications/Jenkins/jenkins.war
webroot: $user. Home /. Jenkins 07:49:53 2020-04-02. 939 + 0000 = 1] [id INFO org. The eclipse jetty. Util. Log. The log#initialized: Logging initialized @328ms to org.eclipse.jetty.util.log.JavaUtilLog
2020-04-02 07:49:54.051+0000 [id=1]	INFO	winstone.Logger#logInternal: Beginning extraction from war fileThe 2020-04-02 07:49:55. 387 + 0000 [id = 1] WARNING O.E.J.S.H andler. ContextHandler#setContextPath: Empty contextPathThe 2020-04-02 07:49:55. 442 + 0000 [id = 1] INFO org. Eclipse jetty. Server. The server# doStart: jetty - 9.4. Z - the SNAPSHOT; Built: the 2019-05-02 T00:04:53. 875 z; git: e1bc35120a6617ee3df052294e433f3a25ce7097; The JVM 1.8.0 comes with _242 - b08The 2020-04-02 07:49:55. 714 + 0000 [id = 1] INFO O.E.J.W.S tandardDescriptorProcessor#visitServlet: NO JSP Support for /, did not find org.eclipse.jetty.jsp.JettyJspServletThe 2020-04-02 07:49:55. 766 + 0000 [id = 1] INFO O.E.J.S.S.D efaultSessionIdManager#doStart: DefaultSessionIdManager workerName=node0The 2020-04-02 07:49:55. 767 + 0000 [id = 1] INFO O.E.J.S.S.D efaultSessionIdManager#doStart: No SessionScavenger set, using defaultsThe 2020-04-02 07:49:55. 769 + 0000 [id = 1] INFO O.E.J.S erver. Session. The HouseKeeper#startScavenging: node0 Scavenging every 660000ms2020-04-02 07:49:56.112+0000 [id=1] INFO Hudson#contextInitialized: Jenkins home directory: /Users/snailsleep/.jenkins found at: $user.home/.jenkinsThe 2020-04-02 07:49:57. 139 + 0000 [id = 1] INFO O.E.J.S.H andler. ContextHandler#doStart: Started w. @ 782 a4fff {Jenkins v2.204.5, /, file:///Users/snailsleep/.jenkins/war/, the AVAILABLE} {/ Users/snailsleep /. Jenkins/war}The 2020-04-02 07:49:57. 154 + 0000 [id = 1] INFO O.E.J.S erver. AbstractConnector# doStop: Stopped ServerConnector @ 723 ca036 {HTTP / 1.1, [HTTP / 1.1]} {8080} 0.0.0.0:The 2020-04-02 07:49:57. 155 + 0000 [id = 1] INFO O.E.J.S erver. Session. The HouseKeeper#stopScavenging: node0 Stopped scavenging2020-04-02 07:49:57.157+0000 [id=1] INFO Hudson#contextDestroyed: Shutting down a Jenkins instance that was still starting up
java.lang.Throwable: reason
	at hudson.WebAppMain.contextDestroyed(WebAppMain.java:388)
Copy the code

If the port number is occupied, change the port number:

$ cd /Applications/Jenkins
$ java -jar jenkins.war --httpPort=8080
Copy the code

6. Failed to start Jenkins because the Java version is incorrect

The 2020-02-27 16:50:30. 475 defaults (94179-3383577) The domain/default pair of (/ Library/Preferences/org. Jenkins - ci, HttpsKeyStore) does not exist 2020-02-27 16:50:30.486 defaults[94180:3383580] The domain/default pair of (/Library/Preferences/org.jenkins-ci, httpsKeyStorePassword) does not exist JENKINS_HOME=/Users/Shared/Jenkins/Home Jenkinscommand line for execution:
/usr/bin/java -Dfile.encoding=UTF-8 -XX:PermSize=256m -XX:MaxPermSize=512m -Xms256m -Xmx512m -Djava.io.tmpdir=/Users/Shared/Jenkins/tmp -jar /Applications/Jenkins/jenkins.war --httpPort=8080
OpenJDK 64-Bit Server VM warning: Ignoring option PermSize; support was removed in8.0 OpenJDK 64-bit Server VM Warning: Ignoring Option MaxPermSize support was removedin8.0 February 27, 2020 4:50:30 PM Main VerifyJavUncomfortable Uncomfortable: Running with Java Class Version 57which is not in the list of supported versions: [52, 55]. Run with the --enable-future-java flag to enablesuch behavior. See https://jenkins.io/redirect/java-support/ java.lang.UnsupportedClassVersionError: 57.0 at main.verifyJavUncomfortable (main.java :174) at main.main (main.java :142) Jenkins requires Java versions [8, 13 the from 11] but you are running with Java/Library/Java/JavaVirtualMachines/its - 13.0.2. JDK/Contents/Home java.lang.UnsupportedClassVersionError: 57.0 at main.java :174) at main.main (main.java :142) 2020-02-27 16:50:40.839 defaults[94183:3383671]Copy the code

Jenkins requires Java versions [8, 11] but you are running with Java 13 Jenkins requires Java version is 8 ~ 11, we need to go to the path/Library/Java/JavaVirtualMachines/its – 13.0.2. JDK/Contents/Home, put its – 13.0.2. JDK, delete Let’s install Java8

Install Java8

$ brew tap AdoptOpenJDK/openjdk
$ brew cask install adoptopenjdk8
Copy the code

OK! Done! Jenkins is fully up and running

7. Jenkins reported an error while running the project,need password

(see lane in the FastFile file in the article) Add the following to the packaging script, which is your developer account and password

    ENV["FASTLANE_USER"] = "* * *"
    ENV["FASTLANE_PASSWORD"] = "* * *"
Copy the code