Background description
Based on project requirements, a unified packaging platform is being built within the team to package iOS and Android projects. and in order to facilitate the distribution of test packages within the team, we hope to generate a two-dimensional code after packaging, experience users (products, operations, testing and other people) through the mobile phone scan QR code can be directly installed test package.
This requirement has a certain universality, basically all the development of the application team may be used, so I will complete the process of implementation of the requirements to form this article, and really do 零基础上手,到手即飞、开箱即用
, I hope to be helpful to everyone.
First of all, let us show you the overall effect after the completion of platform construction:
The main functions of the platform are 3 points:
- The GitHub warehouse is checked periodically, and if there is an update, the build package is executed automatically;
- After the successful construction, the two-dimensional code is generated according to IPA/APK, and the two-dimensional code can be displayed in the History building list, and the corresponding version can be installed directly by scanning the QR code by mobile phone.
- In the Build results page, the results of the build (Artifact, such as,,, and so on) are displayed
.ipa
.app
.apk
info.plist
for download by users who need it.
Next, this article begins to introduce the complete realization process of the platform construction in detail.
Installing Jenkins
Jenkins relies on the Java Runtime environment, so you need to install Java first.
There are several ways to install Jenkins, you can run an installation package that corresponds to the system type, you can get the image through Docker, or you can run the war
package directly.
I personally prefer to run war
the package directly, just download jenkins.war
it and run the following command to start Jenkins.
$ nohup java -jar jenkins_located_path/jenkins.war --httpPort=88 &
If not specified httpPort
, the default port for Jenkins is 8080.
Jenkins Plugin
Jenkins has a lot of plugins that can be extended to a variety of functions.
For the built-in ios/android continuous integration packaging platform, I used the following several plugins.
- GIT Plugin
- SSH Credentials Plugin
- Git Changelog Plugin: Get the Commit log submitted by the repository
- Build-name-setter: Used to modify build name
- Description Setter Plugin: Used to modify build description information, add display QRCode in Description information (QR code)
- Post-build Script Plug-in: Implement some additional functionality by executing a script after compilation
- Xcode Integration:ios dedicated (optional)
- Gradle plugin:android Special (optional)
The installation method is also relatively simple, directly in the Jenkins plug-in management page search the above plug-ins, click Install.
Create a project (JOB)
In Jenkins, the build project exists as a job, so you need to create a job for each project. Sometimes, there may be multiple branches in a project that are being developed at the same time, in order to build separately, you can create a job for each branch.
There are several ways to create a job, and you only need to create Freestyle project
a type.
Main page
, New Item
Freestyle project
For a continuous integration packaging platform, each package consists of 4 steps: Trigger build, pull to replace code, execute build, post-build process. Corresponding to the configuration of these items in each job.
Configuring the Git Code repository
To build a project, it is essential to configure the project's code warehouse. Because our project is currently hosted in the GitHub private warehouse, it needs to Git
be configured here.
In the 【Source Code Management】
configuration section, the option appears if the previous GIT plugin
installation was successful Git
.
When configuring the GIT code warehouse, there are three items that must be configured: The warehouse URL address ( Repository URL
), the Warehouse permission check method ( Credentials
), and the Code branch () that the current job needs to build Branches to build
.
When configured Repository URL
, either select HTTPS URL
or SSH URL
both. However, it is important to note that the Credentials
correspondence, that is to Repository URL
say:
- If
Repository URL
it is in HTTPS URL
the form, then the Credentials
GitHub username and password 2FA(two-factor authentication)
Personal access token
will Personal access token
be used, and if it is on GitHub, you'll need to create one in GitHub and enter the password Enter as the password.
- If
Repository URL
This is the case, then you SSH URL
need to create a key pair on the server where Jenkins is located, SSH
Add the public key to GitHub SSH keys
, and then, Credentials
when you fill it out, select SSH Username with private key
the check method to populate GitHub Username, SSH private key, and SSH
the creation of a key pair Passphrase
.
If the concept of git permissions check is still vague, you can refer to the "easy to read git permissions check."
When configured Branches to build
, you can take many forms, including branch names ( branchName
), tagName
, and commitId
so on. The name of the branch is the most commonly used, for example, if you are building a branch, fill it out if you are master
refs/heads/master
building a develop
branch refs/heads/develop
.
In addition to the above required configuration for git, sometimes the default configuration items for Jenkins may need to be modified depending on the actual situation of the project.
A more common scenario is to clone
modify the configuration.
In the default configuration of Jenkins, the clone
code pulls all historical versions of the code, and the default timeout period is only 10 minutes. This results in some projects, because the code itself is relatively large, the historical version is more, plus the network environment is not particularly good, Jenkins simply can not pull out all the code within 10 minutes, timeout after the task will be automatically terminated (Error status code 143).
The solution to this problem is also very simple, it is just two ideas, or less pull point code (do not get the historical version), or increase the time-out period. The corresponding configuration is in Advanced clone behaviours
:
Shallow clone
: No historical version is available after checking.
Timeout (in minutes) for clone and fetch operation
: Overrides the default time-out period after configuration.
Configuring Build Triggers
The code warehouse is configured, meaning that Jenkins has access to the GitHub code repository and can pull the code successfully.
When does Jenkins execute the build?
This requires the configuration of the build trigger policy, the build trigger, and the configuration item in the 【Build Triggers】
column.
Triggers support multiple types and are commonly used:
- Build on a regular basis (build periodically)
- Build based on commit (build when a-change is pushed to GitHub)
- Periodically detect code updates and build them if they are updated (Poll SCM)
The selection of the build trigger is a composite option, and if you select more than one type, any of the types that meet the build criteria will perform the build work. If none of the types are selected, Jenkins Job
no automatic build is performed, but the build can be triggered by a manual click 【Build Now】
.
The format of the timer (Schedule) is summarized as follows:
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 is Sunday.
In general, you need to specify multiple values, which can take the following operator (priority top-down):
*
Fit all valid values, if not specified, to *
occupy a position;
M-N
Suitable for the range of ranges, for example, 7-9 means 7/8/9 are satisfied;
M-N/X
or */X
: x as the interval;
A,B,C
: Enumerates multiple values.
In addition, in order to prevent multiple tasks from triggering the build at the same time, the characters can be used in conjunction with the specified time period H
. H
after adding a character, Jenkins randomly selects a point in time for the starting moment, and then adds a set interval to calculate the subsequent point in time. Until the next cycle, Jenkins will again randomly select a point in time as the starting point, and so on.
For ease of understanding, a few examples are listed:
H/15 * * * *
: Represents every 15 minutes, and the start time is uncertain, this hour may be :07,:22,:37,:52
, the next one hours may be :03,:18,:33,:48
;
H(0-29)/10 * * * *
: Represents every 10 minutes in the first half hour, and the start time is uncertain, this hour may be :04,:14,:24
, the next one hours may be :09,:19,:29
;
H 23 * * 1-5
: A time between 23:00 to 23:59 on weekdays;
How configuration is built
When the trigger policy is configured, Jenkins automatically executes the build according to the set policy. But how to perform the build operation also requires that we set it up by configuring the Build method.
The common building method is to install the corresponding plug-in according to the concrete type of the building object, and then adopt the corresponding construction method. For example, if you build Android
an application, you can choose it after installation, and then build it, and Gradle plugin
if you build the Invoke Gradle script
Gradle
iOS
app, after you install the Xcode integration
plugin, you can choose and Xcode
then choose Xcode
to build.
The advantage of this approach is that it is simple to operate, UI visualized, and can be quickly met in situations where the scenario is not complex. However, the disadvantage is that depending on the functionality of the plugin, if the scene is more complex, a single plug-in may not meet the requirements, need to install additional plugins. Also, some plugins may have some problems, such as poor compatibility with certain operating system versions or Xcode versions, and we are more passive when problems arise.
I personally prefer another way of writing a packaged script, customizing the implementation of all the build functions in the script, and then executing it in Execute Shell
. The flexibility of this approach is higher, the need to build a variety of scenarios can be met, the problem can also be self-rapid repair.
Also, for iOS apps, there is a point that requires additional attention, which is the configuration of the developer certificate.
If you build with a Xcode integration
plug-in, the configuration is complex, you need to import the development certificate into Jenkins and fill in multiple configuration items. However, if you are building with a packaged script, the situation is much simpler. As long as the developer certificate is installed on the computer that Jenkins is running, and the package command works in the shell, there is no problem in executing the packaging script in Jenkins.
Post-build processing
When the build is complete, the generated compilation results (IPA/APK) are located in the specified directory. However, if you want to install files directly in the phone ipa/apk
is also troublesome, not only in the distribution of the test package will need to transfer several 10 trillion installation packages, experience users at the installation also need to connect the phone with the computer through the cable, and then use the PP helper or pea pod and other tools to install.
At present, a more elegant way is to use or the platform 蒲公英(pgyer)
fir.im
, ipa/apk
upload files to the platform by the platform to generate two-dimensional code, and then only need to the two-dimensional code link distribution, experience the user through the mobile phone scanning two-dimensional code can be achieved rapid installation, the efficiency has been greatly improved.
Upload the installation package file to generate the QR code
Whether 蒲公英
or not fir.im
, there is a corresponding Jenkins plug-in, installed after the plug-in can be implemented in the Post-build
installation package upload.
In addition to using the Jenkins plugin, fir.im
It also supports the way the command is uploaded, and 蒲公英
also supports HTTP Post
the way the interface is uploaded.
I personally recommend using a command or interface upload method and making calls in the build script. Flexibility is on the one hand, the greater advantage is that if the upload failed to retry, which is not very stable network environment is extremely necessary.
After Jenkins successfully completes the installation package upload, the pgyer/fir.im
platform generates a QR code image and returns the URL link address of the image in the response.
Show two-dimensional code image
Two-dimensional code image of the URL link has, then how to display the QR code image in the history of the Jenkins project list?
There is another plugin that needs to be used here description setter plugin
. After installing the plug-in, there 【Post-build Actions】
will be more features in the column description setter
, you can set up after the completion of the configuration of the second build of the description information. This descriptive information is not only displayed on the build page, but also in the history build list.
With this premise, to display the two-dimensional code image in the history of the construction of the list seems to be possible, the intuitive way is to use HTML
the img
label, will be
written to the build description information.
The idea of this approach is correct, but doing so will not achieve the results we expect.
This is because Jenkins for security reasons, all descriptive information by Markup Formatter
default is a Plain text
pattern, in this mode does not parse the build description information in the HTML encoding.
To change it is also easy,--- Manage Jenkins
Configure Global Security
and change Markup Formatter
the setting Safe HTML
to just.
After changing the configuration, we can HTML
insert the image in the tag that is used in the build description information img
.
Another point needs to be added. If you are using a 蒲公英(pyger)
platform, you will find that each time you upload the package to return the QR code image is a short link, the magic is that the short connection is actually fixed (for the same account). This short connection always points to the most recently generated QR code image, but for the unique URL address of the QR code picture, the platform does not return in response. In this case, it doesn't make sense to save a URL link to a QR code image after each build.
The way to do this is, each time after the installation package is uploaded, the QR code image is downloaded and saved locally by a short link of the returned QR code image, and then the Jenkins address of the image is referenced in the build description information.
Collect compilation results (artifacts)
Each time the build is completed, the compilation generates more files, but not all of the files are what we need.
In general, we may only need some of these files, such as .ipa/.app/.plist/.apk
, and so on, we can collect this part of the file separately and display it on the build page so as to download it when needed.
To implement such a feature, you need to add a new one in the 【Post-build Actions】
column Archive the artifacts
and then specify the path to the Files to archive
outcome file in the regular expression.
Once setup is complete, Jenkins will Console Output
search for matches in the set regular expression in, and will collect the files if they are successfully matched.
Summarize
This paper mainly introduces the basic concept and implementation process of how to use Jenkins to build ios/android continuous integration packaging platform. For the execution commands involved, the build script (build.py), and the detailed configuration of Jenkins, the length of the space and the reading experience are not detailed in this article.
To achieve the real 开箱即用
, I drew the Jenkins configuration file and build script out to form a set of templates that only need to be imported into Jenkins and then modify a small amount of configuration information for a specific project to run this set of continuous integration packaging platforms. Implements the exact same functional effect as the article at the beginning of the illustration.
Using Jenkins to build ios/android continuous integration packaging platform "turn"