Android continuous integration with Jenkins and Docker, jenkinsdocker
About Docker
What Docker, why do we need to toss Docker, instead of directly installing the various environments required to run appilication on the server?
This problem is similar to the reason why a virtual machine is needed. I need to run my code on a clean and non-interfering machine to ensure consistency of the Code test runtime environment, reduce the impact of other unknown factors on the code. Compared with the vmvm, Docker has its own characteristics. For example, the startup speed is fast. You can save Docker as an image separately and upload it for use by others. You can even directly put your code in Docker and directly deliver the environment and code together to the customer. The customer only needs to install this Docker and can directly use this application after running it.
Develop, Ship and Run Any Application, Anywhere
Docker is a platform for developers and sysadmins to develop, ship, and run applications. docker lets you quickly assemble applications from components and eliminates the friction that can come when shipping code. docker lets you get your code tested and deployed into production as fast as possible.
Provision
My goal is to build a CI server that can run Android. For the purpose of saving money, I use the local Vagrant to start the Ubuntu virtual machine to replace the real server. The general idea is:
1. Start the Ubuntu Virtual Machine and install Docker Jenkins
Before installing Docker, you must first have a Linux machine to enter. If you already have a clean Linux server, go directly to the Docker installation step.
Before installing Vagrant, you should install VirtualBox Virtual Machine on your computer. After VirtualBox is installed, see Vagrant Installation Guide.
After Vagrant is successfully installed,vagrant init ubuntu/trusty64It can help you quickly install a Ubuntu14.04 virtual machine. It will be slightly slower during the first installation, because Vagrant will help you generate the Vagrantfile file and download the image.
Do not start Vagrantfile immediately after it is generated, because we want to access Vagrant through localhost, and then access Docker through Vagrant. Because Jenkins uses port 8080 by default, if Vagrant's port 8080 can be forwarded to Jenkins in Docker Container. Localhost: 8080 can be forwarded to port 8080 of Vagrant Ubuntu, and then port 8080 of Vagrant can be forwarded to port 8080 of Docker.localhost:8080Access Jenkins. Therefore, the Vagrantfile configuration is as follows: add port forwarding. Because my local port 8080 is occupied by other programs, I forward the local port 8088 to the virtual machine's port 8080:
# Create a forwarded port mapping which allows access to a specific port # within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
#config.vm.network :forwarded_port, guest: 80, host: 8080 config.vm.network :forwarded_port, guest: 8080, host: 8088
If you have already started vagrant up and changed Vagrantfile to make the forward_port take effect, you must firstvagrant suspendPause vagrant and then usevagrant reloadReload Vagrantfile to make the configuration take effect.
After Vagrant Ubuntu Initialization is complete, it is still in this folder with Vagrantfile,vagrant upCan directly start this Ubuntu server.
We can go tovagrant sshGo to Ubuntu, and then install Docker on this clean Ubuntu machine:
$sudo apt - get the update
$sudo apt-get install docker.io
$source/etc/bash_completion. D/docker. IO
// the above method installed Docker version 1.0.1, if you want to use a higher version of Docker1.3.3
$echo deb http://get.docker.com/ubuntu docker main > / etc/apt/sources list. D/docker. List
$apt - key adv - keyserver pgp.mit.edu - 36 a1d7869245c8950f966e92d8576a8ba88d21e9 recv - keys
$apt - get the update
$apt-get install -y lxc-docker-1.3.3
Note:vagrant destroyWill shut down and re-format the ubuntu machine. If you just want to simply stop the machine, usevagrant suspend
After Docker is successfully installed, start the official Jenkins image:
docker run --name androidJenkins -p 8080:8080 -v /var/jenkins_home jenkins
After the installation is complete, accesshttp://localhost:8088/If you can see the Jenkins interface, it indicates that Jenkins has been installed successfully.
After entering, you will find that you have not logged on or registered the portal. Then you will see the solution on stackoverflow: System Management-Configure Global Security-enable Security-Jenkins proprietary user database, allow user registration-any user can do anything. Register a common user name and email address, and then you can directly log on to Jenkins.
2. Install the Android runtime environment in Jenkins Docker
Since Jenkins has been set up, we need to install the Android running environment based on Jenkins. For how to install the Android running environment through command lines in Ubuntu, refer to this article.
The main process for installing the Android runtime environment is:
Here, I will install the Android SDK API version 21 and Build Tools version 21.1.2.
To enable the Jenkins Android environment to be used next time, we create a new image based on Jenkins by creating a Dockerfile. The specific steps are as follows:
Configure Dockerfile
FROM jenkins
MAINTAINER Ming Gong, gongmingqm10@gmail.com
USER root
RUN apt-get update && apt-get -y install libstdc++6 lib32z1 lib32stdc++6 expect
RUN wget --progress=dot:giga http://dl.google.com/android/android-sdk_r24.1.2-linux.tgz RUN mv android-sdk_r24.1.2-linux.tgz /opt/ RUN cd /opt && tar xzvf ./android-sdk_r24.1.2-linux.tgz
ENV ANDROID_HOME /opt/android-sdk-linux/ ENV PATH $ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$PATH RUN echo $PATH RUN echo "y" | android update sdk -u --filter platform-tools,android-21 RUN echo "y" | android update sdk -u --all --filter 5 RUN chmod -R 755 $ANDROID_HOME RUN apt-get install -y git-core RUN android update sdk --no-ui
Whereandroid update sdk -u --all --filter 5It is mainly used to update build-tools. Run 'android list sdk-all' on a machine in the android environment to view all the SDK information, find the latest version of build-tools, and then use the latest version provided.
After Dockerfile is successfully configured, we first go to the Vagrant virtual machine,mkdir /var/jenkins_homeAnd grant all Permissionschmod 777 /var/jenkins_home. /Var/jenkins_home can be mapped to the jenkins_home directory in Docker, so that we can directly back up jenkins data.
Build Dockerfile
After the preparation is complete, build Dockerfile and switch to the current directory where Dockerfile is located,
vagrant@ubuntu-14: sudo docker build -t gongmingqm10/jenkins-android:latest .
...
Successfully built 184c7dad595a
Push Image
The output information is the new image ID generated through Dockerfile. After the build, we need to commit and push the image to the repository of docker hub.
vagrant@ubuntu-14:~/test$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
gongmingqm10/jenkins-android latest 184c7dad595a 11 minutes ago 188.3 MB
Through docker images, we can see that the latest image has been generated. In this step, we need to first start the image, then get the container ID, and then PUSH the container.
Start the image first:
vagrant@ubuntu-14:~/test$ sudo docker run -t -i -d gongmingqm10/jenkins-android:latest
...
vagrant@ubuntu-14:~/test$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 43fcce2388fc gongmingqm10/jenkins-adnroid:latest /bin/bash 17 seconds ago Up 16 seconds determined_lumiere
vagrant@ubuntu-14:~/test$ sudo docker commit -m "Add Android Config" -a "Ming Gong" 43fcce2388fc gongmingqm10/jenkins-android:latest 75f1b93aedc4b57426b75c96ce69170016b3c0b0b6283cda5562f8464bbfd2f4
vagrant@ubuntu-14:~/test$ sudo docker push gongmingqm10/jenkins-android
The first push may prompt you to enter your own Docker Hub user name and password.
Run jenkins-android
sudo docker run --name jenkinsAndroid -p 8080:8080 -v /var/jenkins_home:/var/jenkins_home gongmingqm10/jenkins-android
We use jenkinsAndroid as the container name. Note that this name cannot be the same as the used container name. After running once, you can usesudo docker ps -aView All container, and find the ID of the jeniner named jenkinsAndroid. Start:
sudo docker start f6b88bdad68f
Access Jenkins
In the first part, we directly started Jenkins for access using Jenkins's official Repository. After this part, we built the Dockerfile and added some Android runtime environments, the objective is to provide the necessary runtime environment for Android Test. Accesslocalhost:8088You can access Jenkins with an Android environment. Register the user and log on. This part is complete.
4. Configure Android Build in Jenkins
Accesslocalhost:8088To go to the Jenkins console. To enable Jenkins to run unit and function tests on Android, install the following plug-ins:
git plugin: Clone code from git repo
android emulator plugin: Android can help us generate or start the Android Virtual Machine During function testing.
build monitor view: The current Build status is displayed in full screen mode. It is suitable for projection to the large screen to help everyone understand the build status in real time.
When building the Functional test, I want to directly start the AVD that has been created in the container through android emulator pligin. Errors always occur during running:
$ /opt/android-sdk-linux/tools/emulator -no-boot-anim -ports 9731,9732 -avd Nexus_5_API_21 -no-snapshot-load -no-snapshot-save -no-window
emulator: ERROR: Could not load OpenGLES emulation library: libX11.so.6: cannot open shared object file: No such file or directory
emulator: WARNING: Could not initialize OpenglES emulation, using software renderer.
emulator: warning: opening audio output failed
$ /opt/android-sdk-linux/platform-tools/adb connect localhost:9732 connected to localhost:9732 [android] Waiting for emulator to finish booting...
$ /opt/android-sdk-linux/platform-tools/adb -s localhost:9732 shell getprop init.svc.bootanim
error: device offline
$ /opt/android-sdk-linux/platform-tools/adb connect localhost:9732 $ /opt/android-sdk-linux/platform-tools/adb -s localhost:9732 shell getprop init.svc.bootanim
error: device offline
$ /opt/android-sdk-linux/platform-tools/adb connect localhost:9732 $ /opt/android-sdk-linux/platform-tools/adb -s localhost:9732 shell getprop init.svc.bootanim
error: device offline
$ /opt/android-sdk-linux/platform-tools/adb disconnect localhost:9732 $ /opt/android-sdk-linux/platform-tools/adb connect localhost:9732 $ /opt/android-sdk-linux/platform-tools/adb -s localhost:9732 shell getprop init.svc.bootanim
error: device offline
$ /opt/android-sdk-linux/platform-tools/adb connect localhost:9732 $ /opt/android-sdk-linux/platform-tools/adb -s localhost:9732 shell getprop init.svc.bootanim
error: device offline
$ /opt/android-sdk-linux/platform-tools/adb connect localhost:9732 $ /opt/android-sdk-linux/platform-tools/adb -s localhost:9732 shell getprop init.svc.bootanim
error: device offline
$ /opt/android-sdk-linux/platform-tools/adb disconnect localhost:9732 $ /opt/android-sdk-linux/platform-tools/adb connect localhost:9732 [android] Emulator was shut down before it finished booting
$ /opt/android-sdk-linux/platform-tools/adb disconnect localhost:9732 [android] Stopping Android emulator
$ /opt/android-sdk-linux/platform-tools/adb kill-server
Finished: NOT_BUILT
I checked it online, mainly because of some problems caused by 32-bit emulator running on 64-bit machines. If you can manually start the VM on a machine with a graphic interface, this problem should not occur when running functional test. I will skip this question first, and a special article will be published later.
In Jenkins, the Build is mainly Android Unit Test-Android Functional Test-Android Deploy Hocky App.
The unit test and function test of Android can basically ensure that the functions of the App are normal, while the Deploy-to-Hockey App is for continuous integration, we need to ensure that our apps can be generated in real time so that our products can be tested and displayed to customers at any time, or directly publish a stable version of the Hockey App.
To directly upload Jenkins applications to the HockeyApp, we only need to installHockey App PluginThen, you can register the Hockey App to provide the corresponding API Token and perform simple configuration, that is, you can directly upload and publish our App through Jenkins.
5. Android Flavor
Android Flavor is designed for Android to use different resources during construction, similar to setting different environments during Ruby runtime.
Configure app/build. gradle as follows:
android {
defaultConfig{...}
productFlavors {
dev {
applicationId "com.tarcle.moment.dev" }
qa {
applicationId "com.tarcle.moment.qa" }
production {
applicationId "com.tarcle.moment" }
}
signingConfigs {
release {...}
}
buildTypes {
release {...}
}
packageOptions {...}
}
Through the above configuration, we added three environment variables to the APP, so we can directly create a new one under the app directory.dev, qa, production. You can select different Build variables in IDE to configure the environment Used in the current project.
Pass./Gradlew clean build taskInapp/build/outputs/apkGenerate Debug and Release packages in different environments. The above Release package can be uploaded to the Hockey App by Jenkins.
The following plug-ins may be used to configure Jenkins Build and Hockey App. For different Flavor, we can add Build Parameters in the Deploy HockeyApp configuration. During the Build, we can select different types of packages. To release versions in different environments.
Copy Artifact PluginCopy the generated APK file package from other builds.
Android Lint PluginPublish the Lint Report after the build.
6. Common records
The following are common commands for Docker and Android:
android list avdView all current devices.
android create avd -f -a -s 1080x1920 -n Nexus_5_API_21 -t android-21Create an emulator with the API-21 name Nexus_5_API_21.
emulator -avd Nexus_5_API_21Run the created emulator named Nexus_5_API_21. Note that the command line is always blocked during running, so you can add&Let it run in the background.
adb devicesList of devices attached.
sudo docker exec -i -t a45953b9f2fe bashEnter the console of the running iner