In the last version of the project, the boss said to pack Android on the server, so that everyone can enjoy the fun of packing, then came this article ~Jenkins automatic packaging, has been used for a period of time, but some time ago fell into the king valley, so I have been too lazy to write an article, now finally back to the status and started to masturbate. Although Jenkins has written many more articles, I think this one will give you almost everything you need. I use Jenkins+Git+Gradle to achieve automatic packaging

The installation

IO. Click on the Download Jenkins button and two versions will pop up: LTS Release (long term support) and Weekly Release (Weekly update). First of all, I would like to talk about these two versions. I think they are similar to the update of MIUI, one development version and one stable version. You can choose by yourself, and there is almost no difference in function. Click the “sharp corner” and the operating system will pop up. You can choose the corresponding operating system to install, or you can directly download the 2.xx.X. ar package and put it in the Webapps directory of Tomcat (some functions of Tomcat will be introduced in detail below), create a Jenkins folder and put it in it.

I chose the version of Windows installation, first installed version and war version I have tried, functionality is no difference, the main difference lies in the directory, install the version of the specified installation directory later almost all the things will be generated under the corresponding folder, such as Jobs (that is, the storage project directory), not in the other disk generating extra folder, When you put the war version in the Tomcat directory and open it in a browser, everything will be generated on drive C. Jenkins folder. I’m a bit obsessive myself and like to keep directories clean and not generate extra folders. Another reason is that the installer can be independent of Tomcat. Even if Tomcat is not installed on the machine, the installer can still boot with the local IP :port after installation. You can choose your own version.

Because the installation part is relatively simple, I will not see the above picture.

The plug-in

1. Access the management plug-in

Which brings us to one of Jenkins’ greatest strengths: plugins. Jenkins has a great selection of Plugins, almost any Plugins you want, if you can find them.

To enter Jenkins for the first time, enter a key to enter Jenkins. The next… Pictured above,





setup.png

Generally, select the first option, and the recommended plug-ins will be automatically installed. Note: not all plug-ins can be successfully installed, and some installation failure does not affect, and all the installation can proceed to the next step.

But, sometimes the following happens when you click





setup_error.png

The Retry button is still incorrect, so don’t panic. Choose the second option in the first image. The recommended plug-in is selected by default. But, some cases will still appear the error page above, so the solution is: enter the self-selection page, clear the options, that is, do not select all, and then click the install button to enter the next page.

The next page is to create a user page, where it is recommended to create a user. The “Continue as Admin” button below also provides access to the home page, but it is still very troublesome to create a user later, so it is recommended to create a user.

Once the user is created, you can go to the home page. Choose System Administration -> Administrative Plug-ins -> Optional Plug-ins to start installing the plug-ins we need.

2. List of plug-ins

Note: The main plugins are listed in the list, while Jenkins’ plugins have dependencies. Installing a plugin may require installing the plugins it depends on first, otherwise the installation will fail. In the optional plug-ins check list plug-ins can be, dependent plug-ins will automatically download, is not great.

  • Git plugin
  • Gradle Plugin
  • Email Extension Plugin
  • description setter plugin
  • build-name-setter
  • user build vars plugin
  • Post-Build Script Plug-in
  • Branch API Plugin
  • SSH plugin
  • Scriptler
  • Dynamic Parameter Plug-in
  • Git Parameter Plug-In

    configuration

    With the plugins installed, we’re ready to configure Jenkins, and packing is one step closer.

1.Global Tool Configuration

Go to Global Tool Configuration in system administration options. If the above plug-in is successfully installed, you will see three sections here, as shown in the figure





Global_Tool_Configuration.png

JDK, Git, Gradle. Configure the paths of these three.

  • JDK: alias = arbitrary, JAVA_HOME=JDK directory
  • Git: alias = any, Path to executable=Git installation directory \bin\git.exe
  • Gradle: alias = any, GRADLE_HOME=Gradle download directory \Gradle\ Gradle -2.xx Configure as many Gradle files as possible

The Gradle directory can be the default Gradle directory downloaded by Android Studio, under the user directory. Gradle \wrapper\dists folder, but the directory is not very clean; You can also go to www.androiddevtools.cn to find gradle resources to download the common gradle version, put it in a specified folder, and configure the path.

2. Global properties

ANDROID_HOME not found ANDROID_HOME not found ANDROID_HOME not found So go to Administration > System Settings > Global Properties and select Environment Variables and add





android_home.png

Remember to change the path inside the value to the native SDK directory.

Note: The key here needs to be the same as the key in the Android SDK directory in the native environment variable

packaging

1. Create projects

Now that we are closer to packing, we will start to create a new project. Click “New” on the home page to enter the interface below





create.png

Give your project a name, then choose to build a free-style software project, and click OK to enter the project configuration screen.

2. Configure the project

Go directly to the Source Management TAB or scroll down to source Management, as shown in the figure below.





source_manage.png

Select the Git option, and the interface shown in the above picture will appear. Configure the URL of the Git project. I tested the Github project and selected HTTP as the transport protocol, so I need to select the Credentials option and pass.





credentials.png

Select the default Username with password for the Kind type, then enter the Git account Username and password in Username and Pasword respectively, then scroll down to the bottom and click Add, then select the passes we added in the Credentials section.

Then scroll to the Build Tab, click Add Build Step, and select Invoke Gradle Script as shown:





build.png

Then configure the Gradle version at build time and the tasks that need to be executed, as shown in the following figure:





build1.png

This task is to clean the project and then package the Release versions of all channels. This is Gradle’s command without further details. Then click the Save button and you’re ready to pack.

3. Start building

Click save to enter the project interface, as shown in the picture:





project.png

Click “Build Now” in the left menu bar to start building the project. At this time, the Build Task list will appear in the Build History section. Click “Enter” to view the Build details page, as shown in the figure





project_build.png

Click Console Output to view the log for the build Output. All information is displayed. The log displays Finished: SUCCESS.

After success, return to the project address and click on workspace to view the APK generation under the Build directory of the app.

That’s the simplest configuration for Jenkins packing, and I know you’re looking for more than that.

Customize the desired functionality

1. Parameterized build

When we package, most of the time, we do not want to simply pack a single version of the package, we want to configure parameters to meet some requirements, such as different versions of the package according to the channel, according to the Tag, etc., let’s talk about Jenkins parametric build.

The options that need to be configured in our project are: version (Release or Debug), version number, channel package, and package by Tag. We also need to add the packing route, AS or Jenkins, and a time stamp. With all the parameters listed, let’s configure Jenkins’ parameterized build

Select the configuration from the Jenkins project home page, enter the configuration page, and select the parametric construction process in the General TAB, as shown in the figure below:





General.png

Now you can add parameters. Let me list the parameters in the table below:

Parameter names The parameter types Parameter Value List
BUILD_TYPE Choice Release or Debug
IS_JENKINS Choice true
PRODUCT_FLAVORS Choice Xiaomi, Wandoujia, etc
BUILD_TIME Dynamic Parameter The 2016-12-21-11-11
APP_VERSION Choice 1.0.0, 1.0.1, etc
GIT_TAG Git Parameter Tag1.0.0 etc.

Here is a screenshot of my configuration:





build_type.png





product_flavor.png





app_version.png





is_jenkins.png





build_time.png





git_tag.png

The Tasks attribute is set to:

clean assemble${PRODUCT_FLAVORS}${BUILD_TYPE} --stacktrace --debugCopy the code

${PRODUCT_FLAVORS} and &{BUILD_TYPE} correspond to the options listed above. The configuration is shown as follows:





build2.png

If you are curious, you must have noticed the option in the red box. This option is required for APP_VERSION, IS_JENKINS, and BUILD_TIME because these three parameters need to be injected into the same configuration of the Android project. The option in the red box allows us to hack into the gradle.properties file to replace the values, and the build.gradle file can reference the gradle.properties file directly, so it has an intrusive effect. Gradle. properties and build. Gradle files for the main project are as follows:

//gradle.properties # Project-wide Gradle settings. # IDE (e.g. Android Studio) users: # Gradle settings configured through the IDE *will override* # any settings specified in this file. # For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html #  Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings.org.gradle.jvmargs=-Xmx1536m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit #http://www.gradle.org/docs/current/userguide/multi_project_builds.html #sec:decoupled_projects #org.gradle. Parallel =true APP_VERSION=1.0.1 IS_JENKINS=true BUILD_TIME= "//build.gradle apply plugin: 'com.android.application' def getDate() { def date = new Date() def formattedDate = date.format('yyyy-MM-dd-HH-mm') Return formattedDate} def verCode = 14 Android {compileSdkVersion 25 buildToolsVersion "25.0.0" defaultConfig { applicationId "com.zyyoona7.autobuildtest" minSdkVersion 15 targetSdkVersion 23 testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true versionCode verCode versionName APP_VERSION } SigningConfigs {signingConfig {// Since Jenkins package uses the local KeyStore // and the Jenkins package uses the server KeyStore // the two paths are different If ("true".equals(IS_JENKINS)){storeFile file(" KeyStore path on server ")}else {storeFile file(STORE_FILE_PATH)} keyAlias KEY_ALIAS keyPassword KEY_PASSWORD storePassword STORE_FILE_PASSWORD } } buildTypes { release { minifyEnabled true zipAlignEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' signingConfig signingConfigs.signingConfig } debug { } } dexOptions { javaMaxHeapSize "2g" } Placeholder = [UMENG_CHANNEL_VALUE: "wandoujia"] } xiaomi { manifestPlaceholders = [UMENG_CHANNEL_VALUE: Variants. All {variant -> variants. Outputs. Each {output -> def newName Def timeNow def outDirectory If ("true".equals(IS_JENKINS)) {//Jenkins package output to server path timeNow = BUILD_TIME //BUILD_PATH to server output path outDirectory = BUILD_PATH // autobuildtest-v1.0.1 -xiaomi-release.apk newName = 'AutoBuildTest-v' + APP_VERSION + '-' + Varie.productflavors [0]. Name + '-' + Varie.buildType. name + '.apk'} else { outDirectory = output.outputFile.getParent() if ('debug'.equals(variant.buildType.name)) { newName = "AutoBuildTest-v${APP_VERSION}-debug.apk"} else {// autobuildtest-v1.0.1 -xiaomi- release-apk newName = 'AutoBuildTest-v'  + APP_VERSION + '-' + variant.productFlavors[0].name + '-' + variant.buildType.name + '.apk' } } output.outputFile = new File(outDirectory+'/'+timeNow, newName) } } } dependencies { compile fileTree(dir: 'libs', include: [' *. Jar ']) androidTestCompile (' com. Android. Support. The test. The espresso: espresso - core: 2.2.2 ', {exclude group: 'com.android.support', module: 'support - annotations'}) compile' com. Android. Support: appcompat - v7:25.0.0 'testCompile junit: junit:' 4.12 '}Copy the code

So when Jenkins is packing, these three parameters will change as the choice changes.

Use the configuration for the GIT_TAG parameter. Simply change the Branch reference from source management to the $GIT_TAG reference parameter name, as shown below:





git_tag_use.png

After the Parameters are configured, take a look at the main page. Now the Build with Parameters option is changed to Build with Parameters.





build_with_parameters.png

Tip:

  • If any version of GIT_TAG is selected, it cannot be unselected and can only be refreshed.
  • In addition, when using GIT_TAG, it is better to select the tag version greater than or equal to the version that supports Jenkins packaging, because the previous version of the code did not add attributes that need to be invaded

Pack on time

I didn’t use this function in the project due to space, so please refer to the part of configuring to build trigger using Jenkins to build iOS/Android Continuous Integration packaging platform.

3. Build naming

Each time you Build, the Build History module looks like this:





build_history.png

Each build only shows the number (#xx), which is not pretty, what if we want it to show more information? For example, add the builder’s name, app version built, type built, etc. See the picture below:





set_build_name.png

After the configuration is finished, it is packaged again and looks like this, as shown in the picture:





build_history1.png

Is not very Nice, of course, we can also play according to the needs of ~

4. Configure the download address for Tomcat

After the package is put on the server, we have to configure the download environment to download, first of all, the installation of Tomcat, Tomcat installation will not be introduced in detail here, if you are not familiar with it, please Google or Baidu, the following content is based on the Tomcat environment, my Tomcat version is 8.0+.

Here is how to use Tomcat to configure the download address. First go to the conf folder in the Tomcat directory, then open the server. XML file and add the code shown in the following figure:





erver.png

<! -- docBase is the absolute path to the apK file folder. DocBase ="C://android/downloadApk" crossContext="true" path="/downloadApk"/>Copy the code

After adding this sentence, start the Tomcat service, open a browser, type IP:Port/downloadApk, and you can access it. Click on the file you want to download.

5. Qr code download

Qr code to download function, most is now online via a dandelion or fir. Im to generate a qr code, both are closed platforms, I experienced a dandelion, need to upload files dandelion website then they returned to generate qr code, always feel funny to elsewhere, so I decided to generate its own qr code and then on the download address folder, Display by link.

First to install python environment in the computer, see www.cnblogs.com/yuanzm/p/40… Install PIL (Python Imaging Library) to install Python, if already installed continue to see. The qrcode library is used to generate the qrcode. I will not introduce how to use the library, but I will just say how Jenkins executes python.

Add Python environment variables to Jenkins’ environment variables, as mentioned earlier in this article. Go to System Administration -> System Settings and add Python environment variables as shown in the figure below:





python.png

Note: The key name needs to be the same as the key name in the system environment variable on the computer.

Then open the project configuration page and click Add Build Step in the Build section, as shown in the picture:





add_build.png

Enter the qrcode project usage command in the edit box





python_build.png

Note: the download address needs to concatenate itself, and the generation path also needs to concatenate itself.

In this way, after each packaging, a corresponding TWO-DIMENSIONAL code will be generated in the folder that generates APK. Just scan it and download it

6. Operation after construction

After the construction is completed, I hope to put the download address and qr code in the Build History section for easy download, so let’s set it up and open the project configuration page, as shown in the figure:





build_after.png

Add to the Description input box

<! -- Need to replace link address -->! [] (HTTP: / 192.168.1.88:8088 / downloadApk / ${BUILD_TIME} / qrcode. PNG) < br > < a Href = "HTTP: / / http://192.168.1.88:8088/downloadApk/$/ AutoBuildTest - v ${BUILD_TIME} {APP_VERSION} - ${PRODUCT_FLAVOR} - ${BUILD_TYPE}. A > </a>Copy the code

7. Email notifications

What if I want to notify the person who needs to download the package? Jenkins comes with the Email function, but it doesn’t work very well, so I chose the Email Extension Plugin to implement the Email function (it is in the list of plug-ins). Enter the system Management -> System Settings page, as shown in the figure:









mail.png

Email format:

$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS! $BUILD_NUMBER<br> Build status: ${CAUSE}<br> Build address: ${CAUSE} < A HREF = "${BUILD_URL}" > ${BUILD_URL} < / A > < br > build output logs: <a Href = "HTTP: / / http://192.168.1.201:8090/job/$/ ${PROJECT_NAME} {BUILD_NUMBER} / console" > http://192.168.1.201:8090/job/${PROJECT_NAM E /${BUILD_NUMBER}/console</a><br> < a href = "http://192.168.1.88:8088/downloadApk" > http://192.168.1.88:8088/downloadApk < / a > < br > < br > qr code to download:! {BUILD_TIME} [] (http://192.168.1.88:8088/downloadApk/$/ qrcode. PNG) < br > recent CHANGES to: < br > ${CHANGES, showPaths = false, format = "% a: \"%m\"<br>", pathFormat="\n\t- %p"}Copy the code

Note: please modify the corresponding address, about the recent changes to refer to stackoverflow.com/questions/7…

The final effect looks like this:





mail1.png

Errors encountered

1.AAPT Err (Facade for 26390200):build-tools/23.0.1/ AAPT: /lib/libc.so.6: version ‘glibc_2.11’ not found /23.0.1/ AAPT)

Lib /libc.so.6 is the C library of Linux system. Because the Linux system of our company’s server is too old, glibc_2.5 is supported at most. So the decision was made to deploy to Windows servers. Check the version of glibc_2.xx that your Linux operating system supports before deploying to a Linux server. Android build-Tools 25.0.0 requires glibc_2.14.

Local.properties: sdK. dir not found or ANDROID_HOME not found

I am sorry that I only recorded the general error because I did not record it in time. Moreover, after the configuration, the error did not appear again, so I can only see the general error. This error is mainly the configuration of the Android SDK path to ANDROID_HOME environment variable is not configured. Windows configure the environment variables above; Name ANDROID_HOME: Value is the Android SDK path. Alternatively, configure Jenkins’ Environment variables with the same name and value as above, add the Environment variables TAB under System Administration -> System Settings -> Global properties, and add the Environment variables

conclusion

Jenkins packing is not difficult, the hardest part is installing the plugins, because the company network is not very good, it takes at least half a day to install the plugins

If you use Jenkins on a Linux system and a Mac, the setup is almost the same, but the required file format is pretty much the same.

Because the space is quite large, I hope you can read more feedback, have any questions can also leave a message.

reference

Build iOS/Android continuous integration packaging platform using Jenkins to play with Android automatic packaging and delivery