Automating the building of Android and iOS apps with Jenkins

Automating the building of Android and iOS apps with Jenkins

background

As business needs evolve, the complexity of engineering will gradually increase, and the practice of automation will become increasingly strong. In fact, engineering automation has always been our goal, which can effectively improve our production efficiency, minimize the probability of human errors, and achieve some complex business needs.

The scenario is as follows: every time the company's testers need to test a new version, they need the developers to package it and put it on FTP. The testers then copy it from FTP to the local computer (or use the ES file manager on the phone) and install it. Especially in the week leading up to the release, a new version is required almost every day. This has two effects: first, it interrupts the development progress of the developers; second, the developers' packaging efficiency is low, especially for iOS. If things go wrong, they will always be packaged incorrectly (probably due to certificate issues).

To solve this problem, we must realize the automated construction of mobile applications. Specifically, we use the continuous integration (CI) system Jenkins to automatically detect and pull the latest code, automatically package the Android apk and iOS ipa, and automatically upload them to the internal test distribution platform Dandelion. (Next, the tester only needs to open one (or more) fixed URLs and scan the QR code to download the latest version...)

environment

Because you want to compile iOS, choose Mac OSX 10.11.1.

Regardless of the operating system, the Jenkins configuration is the same.

Install Jenkins

Official website address: http://jenkins-ci.org/

  1. // Install using brew
  2. brew install jenkins
  3. // Start, just run jenkins to start the service
  4. Jenkins

By default, visit http://localhost:8080/ to enter the Jenkins configuration page.

Install Jenkins related plugins

Click System Management > Manage Plugins > Optional Plugins to search for the following plugins to install

  • GIT plugin
  • SSH Credentials Plugin
  • Gradle plugin – Android only
  • Xcode integration – iOS only

Create a new job

On the main page, click New->Build a free-style software project.

For similar projects, you can select -> Copy Existing Item. Enter the first character of the other job in the task name to be copied and there will be an intelligent prompt.

Configure git repository

If the git plug-in is installed, Git will appear in the source code management. After selecting it:

Repositories -> https://github.com/openproject/ganchai, if it is ssh, you also need to configure Credentials.

Branch -> */master, select a branch code to compile.

as follows:

[[180854]]

If it is a private repository (such as git://xxxxx.git), click Credentials – Add, a dialog box pops up, and it is easiest to configure sshkey:

Configure automatic pull of *** code

In the build trigger, there are two strategies for automatically pulling code and compiling:

1. Set Poll SCM, set a timer, check for code updates regularly, compile if there are updates, otherwise do not compile (I am using this for now).

2. You can also set Build periodically to execute compilation tasks periodically.

Regarding the format of the timer, I can only quote a slightly more reliable description from the Internet:

This field follows the syntax of cron (with minor differences). Specifically, each line consists of 5 fields separated by TABor whitespace:
 
MINUTE HOUR DOM MONTH DOW
 
MINUTE Minutes within the hour (0-59)
HOUR The hour of the day (0-23)
DOM The day of the month (1-31)
MONTH The month (1-12)
DOW The day of the week (0-7) where 0 and 7 are Sunday.
 
To specify multiple values ​​for one field, the following operators are available. In the order of precedence,
 
   * '*' can be used to specify all valid values.
   * 'MN' can be used to specify a range, such as "1-5"
   * 'MN/X' or '*/X' can be used to specify skips of X''s value through the range, such as "*/15" in the MINUTE field for "0,15,30,45" and "1-6/2" for "1,3,5"
   * 'A,B,...,Z' can be used to specify multiple values, such as "0,30" or "1,3,5"
 
Empty lines and lines that start with '#' will be ignored as comments.
In addition, @yearly, @annually, @monthly, @weekly, @daily, @midnight, @hourly are supported.

Here are two examples:

  1. // every minute  
  2. * * * * *
  3. // every 5 minutes past the hour  
  4. 5 * * * *

Configuring gradle – android specific

iOS friends please pass by.

If the gradle plugin is installed successfully, the Invoke Gradle script shown below should appear. Configure it:

${WORKSPACE} indicates the workspace directory of the current job, which is mainly used to store code. For more environment variables, please refer to the appendix at the end of this article.

In this way, the corresponding apk can be automatically generated under the build/outputs/apk of the app under the project.

Compilation failed? There are two possible issues to solve:

1.gradle does not configure environment variables.

For example, I configure GRADLE_HOME in /etc/profile:

  1. export GRADLE_HOME= '/home/jay/.gradle/wrapper/dists/gradle-2.2.1-all/c64ydeuardnfqctvr1gm30w53/gradle-2.2.1'  
  2. export PATH=$GRADLE_HOME/bin:$PATH

2. Cannot find the sdk definition in local.properties.

Because local.properties is generally not added to the version library, you need to manually copy it to the Project directory under ${WORKSPACE} (refer to your own Android Studio project structure).

Regarding the definition of local.properties, record it here for backup:

  1. sdk.dir=xx/xx/android-sdk

Recompiling will usually succeed, of course, when those third-party libraries need to be re-downloaded, the compilation may be very slow.

Configure Xcode – iOS only

Android students please pass by.

After installing the Xcode plug-in, you can see the following interface and configure:

There are two things to note here.

  1. sign
  2. Requires a Shared Schema file.

Upload to Dandelion platform

There are instructions in the official website document to upload the key code of the app through the Linux platform

  1. curl -F "file=@/tmp/example.ipa" -F "uKey=" -F "_api_key=" http://www.pgyer.com/apiv1/app/upload

Specifically,

  1. # First consider ${version} as v1.0
  2. curl -F "file=@/home/xxx/release/ganchai-release-${version}-0101-dev.apk" -F "uKey=231xxxxe6" -F "_api_key=0xxxx499" -F "publishRange=2" http://www.pgyer.com/apiv1/app/upload

This completes uploading an app to Dandelion.

In fact, we may face more complex scenarios, such as the ${version} above, and the version is defined in build.gradle as follows:

  1. ext {
  2. compileSdkVersion = 22
  3. buildToolsVersion = "23.0.1"  
  4. minSdkVersion = 10
  5. targetSdkVersion = 22
  6. versionCode = 1111
  7. versionName = "v1.2.0.0"  
  8. }

We have to find a way to read the versionName and then spell out the final file name, so that the next time the version is upgraded, the app can be dynamically uploaded to Dandelion.

  1. # Use the sed command to read, use cut to cut, and finally dynamically read versionName
  2. version=`sed -n '21,1p' ${WORKSPACE}/xxx/build.gradle | cut -c20-27`

This is the APK upload process for Android. Correspondingly, iOS is uploading ipa. The method is the same and will not be repeated here.

summary

After automating the work of developers releasing versions, it is convenient for testers to pull and build the latest version at any time, and it also frees developers from the work of releasing versions themselves. In a word, good!

appendix

The environment variables defined in Jenkins are:

  1. The following variables are available to shell scripts
  2.   
  3. BUILD_NUMBER
  4. The current build number, such as   "153"  
  5. BUILD_ID
  6. The current build id, such as   "2005-08-22_23-59-59" (YYYY-MM-DD_hh-mm-ss)
  7. BUILD_DISPLAY_NAME
  8. The display name   of the current build, which is something like   "#153"   by   default .
  9. JOB_NAME
  10. Name   of the project of this build, such as   "foo"   or   "foo/bar" . ( To strip off folder paths from a Bourne shell script, try:${JOB_NAME##*/})
  11. BUILD_TAG
  12. String of   "jenkins-${JOB_NAME}-${BUILD_NUMBER}" . Convenient to put into a resource file, a jar file, etc for easier identification.
  13. EXECUTOR_NUMBER
  14. The unique number that identifies the current executor (among executors of the same machine) that's carrying out thisbuild. This is the number you see in the "build executor status" , except that the number starts from 0, not 1.
  15. NODE_NAME
  16. Name   of the slave if the build is   on a slave, or   "master" if run on master
  17. NODE_LABELS
  18. Whitespace-separated list of labels that the node is assigned.
  19. WORKSPACE
  20. The absolute path of the directory assigned to the build as a workspace.
  21. JENKINS_HOME
  22. The absolute path of the directory assigned on the master node for Jenkins to store data.
  23. JENKINS_URL
  24. Full URL of Jenkins, like http://server:port/jenkins/ (note: only available if Jenkins URL set   in system configuration)
  25. BUILD_URL
  26. Full URL of this build, like http://server:port/jenkins/job/foo/15/ (Jenkins URL must be set )
  27. JOB_URL
  28. Full URL of this job, like http://server:port/jenkins/job/foo/ (Jenkins URL must be set )
  29. SVN_REVISION
  30. Subversion revision number that's currently checked out   to the workspace, such as   "12345"  
  31. SVN_URL
  32. Subversion URL that's currently checked out   to the workspace.

<<:  What Master brings to the world: Is it "out of control" or evolution?

>>:  Android easily implements RecyclerView suspension bar

Recommend

Brand marketing promotion: 6 tricks for brand naming!

01 The success of a big brand can cover up many i...

2019 traffic growth inventory!

2019 has not been an easy year, so today we will ...

Can bidding hosting improve the quality of corporate marketing?

Can bidding hosting improve the quality of corpor...

5 ways to improve user retention

1. User Retention and Churn 1. What is user growt...

How much does it cost to rent a G-port server in Zhengzhou?

How much does it cost to rent a G-port server in ...

Why doesn’t the iPhone 6 have a sapphire screen?

An article recently published by foreign media di...

How to bid for Google promotion keywords? These 4 points must be mastered!

For the most important keyword level in Google pr...

Why is your information flow not converted? Where did the traffic go?

The world is so big that there are all kinds of s...

Still worried about AirPods being lost? A brooch can help

Apple's first truly wireless earphone product ...