Docker + Jenkins + Gradle 实现 Android 的持续集成

Linux Docker

Android 开发的同学应该都有被 Android Studio 支配的恐惧,每一次打包 Apk 的时候真的是可以去喝个下午茶再回来干活(公司的开发机配置一般,每次批量打包都得一两个小时电脑还卡的不能干其他事🤦‍♂️)

为了解决这种情况今天就来给大家讲讲使用服务器远程打包,多的不说,直接怼~~~

1. 镜像篇

1.1 构建镜像

本例中我们使用 Dockerfile 来构建接下来需要用到的镜像,文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
FROM daocloud.io/library/tomcat:8.5.15
LABEL Name="jenkins-tomcat"
LABEL Version="0.2"
LABEL Maintainer="Layoute <reallayoute@gmail.com>"
# 环境变量
ENV GRADLE_VERSION 4.4
ENV GRADLE_HOME /root/.sdkman/candidates/gradle/${GRADLE_VERSION}/
# tomcat 容器自带 java 8u131 放弃安装
# ENV JAVA_VERSION 8.0.181_zulu

# 安装所需依赖
RUN apt-get update \
&& apt-get install -y \
git \
zip \
unzip \
&& apt-get clean \
&& apt-get autoclean

# 配置 jenkins 为 80 端口根路径
RUN rm -rf /usr/local/tomcat/webapps/ROOT
ADD http://ftp-nyc.osuosl.org/pub/jenkins/war-stable/2.121.3/jenkins.war /usr/local/tomcat/webapps/ROOT.war
RUN sed -i 's/8080/80/' /usr/local/tomcat/conf/server.xml

# 安装 SDKMAN 开发包管理器
WORKDIR /root
RUN curl -s "https://get.sdkman.io" | bash
RUN /bin/bash -c "source /root/.sdkman/bin/sdkman-init.sh"
# 安装 Gradle 等依赖
# -l 伪装为登录的 shell 执行命令
# -c 读取字符串命令
RUN yes | /bin/bash -l -c 'sdk install gradle ${GRADLE_VERSION}'
# RUN yes | /bin/bash -l -c 'sdk install java ${JAVA_VERSION}'

# 暴露端口
EXPOSE 80

# 设置 entrypoint 权限并运行
WORKDIR /usr/local/tomcat
COPY ./entrypoint.sh /usr/local/tomcat/
RUN cd /usr/local/tomcat
RUN chmod 0777 ./entrypoint.sh
# 执行脚本
ENTRYPOINT [ "./entrypoint.sh" ]

entrypoint.sh 为入口指令,包含镜像部署启东时会运行的一系列指令

1.2 部署镜像

接下来就是将构建好的镜像部署到服务器,我们使用 docker-compose 来实现部署

docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
version: '2'

services:
nginx-proxy:
image: index.docker.io/jwilder/nginx-proxy:latest
container_name: nginx-proxy
privileged: true
restart: always
ports:
- 80:80
- 443:443
volumes:
- /etc/nginx/conf.d
- /etc/nginx/vhost.d:/etc/nginx/vhost.d
- /etc/nginx/html:/usr/share/nginx/html
- /etc/nginx/certs:/etc/nginx/certs:ro
- /var/run/docker.sock:/tmp/docker.sock:ro

letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
container_name: letsencrypt
privileged: true
restart: always
volumes_from:
- nginx-proxy
volumes:
- /etc/nginx/certs:/etc/nginx/certs
- /var/run/docker.sock:/var/run/docker.sock:ro

jenkins:
build:
dockerfile: ./Dockerfile
context: .
image: jenkins_sdkman
container_name: jenkins
privileged: true
restart: always
ports:
- '80'
volumes:
- /etc/jenkins:/root/.jenkins/
- /etc/jenkins_home:/var/jenkins_home
volumes_from:
- android_sdk
environment:
- LETSENCRYPT_MAIL=email@example.com
- LETSENCRYPT_HOST=domain.example.com
- VIRTUAL_HOST=domain.example.com

android_sdk:
image: runmymind/docker-android-sdk:latest
container_name: android_sdk
privileged: true
restart: always
environment:
- REPO_OS_OVERRIDE=linux
volumes:
- /etc/android/sdk:/opt/android-sdk-linux

上述文件包含了 nginx-proxy 作为代理服务器来进行反向代理, LetsEncrypt 主要是用来签发证书,实现 https, jenkins 即为我们的持续集成服务提供者,android-sdk 则是用来为 jenkins 提供 Android SDK 支持

2. Android 构建集成

2.1 Jenkins 配置

按照网上的基本配置教程配置好 Jenkins ,设置完管理员密码

2.2 全局工具配置

此处配置主要用来配置全局的以来环境等,我们这里只需要关注 JDK,Git,Gradle 三项的配置,均可选择新增按钮添加需要支持的版本后应用保存即可

2.3 全局凭据配置

因为我们使用的是 Github 来托管项目,那就需要从 Github 上面同步代码到服务器用来构建,这里涉及到 SSH Key 的问题,我们可以去凭据管理里面新增一个凭据,类型选择 SSH Key **** 类型,别名随便填,但是后面得使用别名生成 SSH Key 如下:

1
2
3
4
5
$ ssh-keygen -t rsa -C “上面设置的别名”
# 读取私钥
$ cat ~/.ssh/id_rsa
# 读取公钥
$ cat ~/.ssh/id_rsa.pub

将上面的公钥添加到 Github 设置界面的 SSH Key 页面,私钥填入上面创建的凭据里面, 通过 SSH Key 同步代码就配置好了

2.4 构建任务配置

接下来我们就可以开始创建任务了

  • 安装插件 Android Lint, Github integration
  • 创建新的构建任务,选择自由风格
  • 基本设置
  • 源码设置
  • 构建触发器设置
  • 构建设置

接下来点击立即构建就可以开始第一次构建了,完成第一次构建后即可在工作区查看项目相关文件了

搞定,收工!