概述

在linux服务器上安装docker和jenkins,项目仓库在搭建的gitlab私服上,然后在windows或者mac上编写项目,最后push代码到gitlab指定分支时,触发jenkins去gitlab上拉取项目,进行构建。这里主要记录一下配置和构建的过程,而不是怎么在linux中安装docker和jenkins。

jenkins配置

在安装好的jenkins中,创建一个新任务,名称一般和项目名称一致。然后选中pipeline,点击“确定”,就创建了一个新任务。 创建新任务后,会进入配置页面:

  1. General:GitLab Repository Name栏目,输入项目组名+项目名,如clients/android_client
  2. Build Triggers:选择Build when a change is pushed to GitLab,意思是当push代码到指定的分支时,就触发构建。Allowed branches:允许触发构建的分支,选择的是Filter branches by name,然后填写允许触发构建的分支名称,必须是项目里存在的分支名称。
  3. Advanced Project Options:不用管
  4. Pipeline:选择pipeline script frm SCM(source code manage);SCM(源代码管理)选择Git,Repository URL填写项目所在仓库地址,是https而不是ssh;Credentials填写仓库的账号密码;Branches to build填写需要构建的分支名称; Script Path,是jenkins脚本的路径,脚本放在项目下,如buildsystem/ci/jenkins/Jenkinsfile,是一个相对于项目的相对路径。

最后点击保存,这样jenkins里就配置好了。这里配置了去哪个仓库地址拉取源代码,但是还得有人告诉你什么时间该拉源代码进行构建,这就需要在gitlab里配置。

gitlab配置

这里主要配置一个webhook,可以简单理解成一个通知器,当项目发生某些事件时,就通知jenkins,然后jenkins再根据配置的事件类型和传来的事件类型是否一致来决定是否需要拉取源代码进行构建。比如,我们在jenkins里配置了push到master就会拉取源代码进行构建,那么如果通知过来的是push到develop分支的事件,jenkins就不会拉取源代码进行构建,如果通知过来的是push到master分支的事件,jenkins就会拉取源代码进行构建。

你的账号必须要是这个项目的管理者,不然是没有权限进行配置webhook的。点项目,在左侧栏里找到Settings,选择integrations进入到webhook的配置页面:

  1. URL:这个是在jenkins里创建的任务的地址,紧跟在Build Triggers的Build when a change is pushed to GitLab后面,当事件发生时,会向这个地址发送事件(是一个post请求)。
  2. Secret Token:这个是token认证,验证是不是合法请求;在jenkins配置中的Build Triggers->Build when a change is pushed to GitLab->高级->Secret token,点击Generate会自动生成一个token。
  3. Trigger:配置哪些事件会通知Jenkins,根据需要,这里选择了Push events。
  4. 点Add webhook保存配置

至此,gitlab里也配置好了,现在push源代码到指定的分支话,gitlab会通知jenkins,jenkins会执行构建。但是用什么来构建呢?就是用在jenkins的Pipeline里配置的script path脚本来执行构建。它指向的是一份Jenkinsfile脚本。

Jenkinsfile脚本

两个jenkins基础概念node和stage。node是一个节点,可以有多个节点,一般执行耗时操作时才需要另开一个节点;stage是一个阶段,每个阶段干一件具体的事情;可以一个node下有一个或多个stage,也可以一个stage下有一个或多个node。没有特别需要一般都是一个node下多个stage。

当一个正确的事件触发时,jenkins会执行这份Jenkinsfile脚本。去配置的gitlab仓库中拉取源代码,拉取来时默认是master分支,这个都知道。接下来的实现就需要在Jenkinsfile脚本中来做:

  1. 构建一个docker镜像,就是一个Android环境,因为项目需要在Android环境下才能够执行。可以在Docker Hub上找一个Android基镜像文件,然后自己的Dockerfile继承这个基镜像(FROM beevelop/android:latest)。Dockerfile示例如下:
FROM beevelop/android:latest
MAINTAINER KuickDeal "xiaoge@kuick.cn"
#安装expect
RUN apt-get update && apt-get install -y --force-yes expect
# 设置环境变量
ENV PATH ${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools
# 创建目录
RUN mkdir -p /opt/workspace
# 拷贝所有文件到目录下
COPY . /opt/workspace
# 切换目录
WORKDIR /opt/workspace
# 配置环境变量
ENV PATH ${PATH}:/opt/workspace/buildsystem/ci/tools/
# 更新sdk,要和项目的编译版本一致
RUN echo y | android update sdk --all --no-ui --filter build-tools-27.0.3,extra-android-m2repository,android-27
# Cleaning
RUN apt-get clean复制代码

BuildPushDocker.sh(构建、推送docker镜像的shell脚本):使用docker build -t ${image_name} -f ${Dockerfile_path} ${workspace}来构建镜像。构建好后用docker push ${image_name}命令把镜像push到公共的仓库,以便在不同的终端可以使用这个镜像。${image_name}是由在Docker Hub注册的用户名/tag组成的,例如注册的用户名为test.docker,tag为1.5,则${image_name}为test.docker/1.5。至此已经构建好一个Android镜像,并且推到了公共仓库。

  1. PullDocker.sh(拉取docker镜像的shell脚本):通过docker pull ${image_name}拉取镜像,因为不需要在每次构建Android包的时候都构建一次docker镜像,所以第1步一般情况下只执行一次,只需要去公共仓库拉取镜像就可以。在项目编译版本改变时,需要重新构建一个安装了对应AndroidSDK版本的镜像。

  2. AssembleApk.sh(构建apk的shell脚本):

docker run -v ${workspace}:/opt/workspace ${container_name} ./gradlew build --info
复制代码

在物理机的{workspace}目录和docker的/opt/workspace目录做一个映射,创建一个新的docker容器{container_name},在容器中执行命令./gradlew build 来构建apk。{workspace}是gradlew和gradlew.bat所在的目录,也就是项目的根目录,在物理机中,但是没有Android环境。所以需要把这个目录和有Android环境的docker镜像的目录/opt/workspace做一个映射。至此,debug包和release包就构建出来了。

现在都希望能更好的保护公司的源代码,所以会对apk做一些加固。市面上加固平台有很多,有阿里安全、腾讯加固宝、爱加密、梆梆加固、360加固等。两年前用的是梆梆加固,但是发现加固后在小米note手机上会出现崩溃,所以果断放弃了。后来一直用爱加密到现在(2018.6),手动上传到平台去加密。后面需要做自动化,所以咨询了上面各家加固平台是否有自动化脚本加固。梆梆加固、腾讯加固宝没有,放弃。阿里安全、爱加密有,但是收费,费用还不便宜,爱加密单买自动化加固就得2w一年,所以也暂时不考虑。最后只有360加固有自动化脚本加固,还免费,所以采纳了它。

  1. 360加固,需要他们的加固工具,所以需要先下载加固工具。这一步涉及到多个脚本,JiaGu360Exist.sh、DownloadUnzip360.sh、JiaGu360.sh。第一个脚本是检测有没有下载360的加固工具,如果没有下载,则用第二个脚本下载并解压加固工具,最后用第三个脚本对apk进行加固。根据有没有目录来判断有没有下载加固工具,比如把加固工具解压到./jg目录下,那只需要判断./jg这个目录是否存在就可以了:
   for file in $(ls ${curPath})dozipFile=`echo ${file} | grep 'jg'`if [[ ${zipFile} = "jg" ]]thenecho ${zipFile}breakfidone
复制代码

如果不存在,则说明没有下载加固工具,下载的命令是直接写在了Jenkinsfile里,也可以写成一个shell脚本,Jenkinsfile是用groovy语言编写:

def download = sh(script: "wget -O jiagubao.zip -P ./ http://down.360safe.com/360Jiagu/360jiagubao_linux_64.zip", returnStdout: true).toString().trim()
echo "download=${download}"
// 解压到./jg目录下
sh "sudo unzip -d ./jg ./jiagubao.zip"
// 删除加固工具压缩包
sh "sudo rm ./jiagubao.zip"
复制代码

最后是加固:

//登录360开放平台
loginR=`sudo ${base} -login ${name} ${pw2}`
echo "loginR=${loginR}"
//导入签名信息,加固后自动签名
keystoreR=`sudo ${base} -importsign ${ccPath} ${pw} ${alias} ${pw}`
echo "keystoreR=${keystoreR}"
//修改需要的加固服务
updateR=`sudo ${base} -config -x86`
echo "updateR=${updateR}"chmod +x ${curScriptDir}/FindDebugApk.sh
chmod +x ${curScriptDir}/FindReleaseApk.sh
//创建加固后的debug和release包保存路径
sudo mkdir ${debugEnhancePath} ${releaseEnhancePath}
//找到需要加固的debug包
debugApk=`${curScriptDir}/FindDebugApk.sh`
echo "debugApk=${debugApk}"
//加固debug包
enhanceDebugR=`sudo ${base} -jiagu ${debugPath}${debugApk} ${debugEnhancePath} -autosign`
echo "enhanceDebugR=${enhanceDebugR}"
找到需要加固的release包
releaseApk=`${curScriptDir}/FindReleaseApk.sh`
echo "releaseApk=${releaseApk}"
//加固release包
enhanceReleaseR=`sudo ${base} -jiagu ${releasePath}${releaseApk} ${releaseEnhancePath} -autosign`
echo "enhanceReleaseR=${enhanceReleaseR}"
复制代码

至此,加固后的apk就出来了,但是现在apk是在服务器上的,测试组或者其他人员都无法拿到这个apk,所以需要一个公共的地址,来存放这个apk。可以是自己的服务器下载地址,也可以是其他开放的下载地址。这里选择的是蒲公英。

  1. UploadDebugApk.sh和UploadReleaseApk.sh,上传加固包到蒲公英的脚本。 上传命令
uploadResult=`curl -F "file=@${apk_path}" -F "uKey=${userKey}" -F "_api_key=${apiKey}" "http://www.pgyer.com/apiv1/app/upload"`
复制代码

上传完后,我们需要做最后一步,就是通过邮件通知相关人员,比如测试人员。把蒲公英下载地址通过邮件发送给他们。

  1. 发送邮件,直接在Jenkinsfile里定义函数,jenkins自带发邮件功能:
// 发邮件
def sendMail(String to,String title, String body){mail([bcc: '',body: body,cc: '',from: '',replyTo: '',subject: title,to: to]);
}
复制代码

到此,整个自动化构建、打包、加固apk就完成了。 Jenkinsfile的结构如下:

node('node_name'){stage("删除build目录"){//切换到jenkins里配置的需要构建的分支,默认拉取的是master分支checkout scm//删除build目录,避免资源更换后,缓存未更新,导致构建错误sh "sudo rm -rf app/build"}stage("准备镜像") {// 不用每次都构建镜像
//        sh "buildDocker.sh"sh "pullDocker.sh"}stage("构建包") {try{sh "assembleAPK.sh"}catch(Exception e){sendMail(mySelfEmail, 'Android安装包构建失败', e.message)}}stage("加密包"){try{// 检测是否下载了360加固工具def exist360 = sh(script: "JiaGu360Exist.sh", returnStdout: true).toString().trim()if ("jg" != exist360){// 查看wget下载工具版本,未安装会抛异常def result = sh(script: "wget -V", returnStdout: true).toString().trim()// 下载360加固工具,重命名为jiagubao.zip,下载到当前目录./def download = sh(script: "wget -O jiagubao.zip -P ./ http://down.360safe.com/360Jiagu/360jiagubao_linux_64.zip", returnStdout: true).toString().trim()// 解压到./jg目录下sh "sudo unzip -d ./jg ./jiagubao.zip"// 删除加固工具压缩包sh "sudo rm ./jiagubao.zip"}sh "JiaGu360.sh"}catch(Exception e){sendMail(mySelfEmail, '360加密包失败', e.message)}}stage("确认上传测试包"){input message: "确认上传测试包?"}stage("上传测试包") {try{def code = sh(script: "uploadTestApk.sh", returnStdout: true).toString().trim()if(code == null || code != "0"){sendMail(mySelfEmail, 'Android测试包上传失败', "code=${code}")}else{//从readme文件中读取apk的更新内容def content = sh(script: "ReadUpgradeInfo.sh", returnStdout: true).toString().trim()sendMail(testGroupEmail, 'Android测试包下载地址', "https://www.pgyer.com ${content}")}}catch(e){sendMail(mySelfEmail, 'Android测试包上传失败', e.message)}}stage("确认上传正式包"){input message: "确认上传正式包?"}stage("上传正式包") {}}
// 发邮件
def sendMail(String to,String title, String body){mail([bcc: '',body: body,cc: '',from: '',replyTo: '',subject: title,to: to]);
}
复制代码

完结。

Tips:

  1. 如里出现Permission Denied,在执行脚本前用 chmod +x {shell_path}给脚本加上执行权限。
  2. 有问题,可以给xiaoge@kuick.cn发邮件,一起探讨

[凡文]Docker+Jenkins+Gradle+GitLab在Linux服务端自动化构建Android包相关推荐

  1. docker之搭建gitlab私有仓库服务

    简单三步搭建docker之搭建gitlab私有仓库服务 服务配置:1c2g+2g虚拟内存,服务启动大概需要3.x g内存 内存不足可配置虚拟使用--memory=10M --memory-swap=- ...

  2. docker下编译mangoszero WOW60级服务端(二)

    开始搭建基于docker的mangoszero WOW服务端,我自己的操作系统是mac os,其他平台操作可以等价替换 1.准备工作 (1) 安装docker,参考docker官方文档,https:/ ...

  3. windows 下frp服务启动_内网穿透frp linux服务端搭建和windows客户端使用

    一.Linux 服务端搭建 1.下载安装 wget --no-check-certificate https://raw.githubusercontent.com/clangcn/onekey-in ...

  4. linux服务端搭配win7客户端的frp

    下载frp 从https://github.com/fatedier/frp/releases 下载最新版本的frp压缩包.因为是两种系统,所以把linux和windows的版本都下载了一份. lin ...

  5. 冒险岛linux服务端 143端

    更新版本 冒险岛服务端 143 端 请在linux(ubuntu ContOs)上使用 使用前先转移数据库(如何转移?) 请看:https://blog.csdn.net/qq_31392539/ar ...

  6. Kcauldron服务端linux版,我的世界1.7.10[KCauldron]服务端精简基础整合包

    我的世界1.7.10[KCauldron]服务端精简基础整合包下载,这是一款体积只有54MB的超精减服务器整合包,这个整合服务端除了必要文件和基础插件外,没有其他任何的东西,服务端默认没有任何mod, ...

  7. Docker+Jenkins+Git+GitLab实现DevOps

    先了解一下Jenkins Jenkins是一个开源的.提供友好操作界面的持续集成(CI)工具,提供了数百个插件来支持构建,部署和自动化任何项目.我们可以使用Jenkins结合常用的版本控制工具(git ...

  8. Jenkins+Gradle+Gitlab+蒲公英 +打包成功后发送邮件配置

    一.配置全局属性 Environment variables ANDROID_HOME SDK路径 /Users/lejumobile/Library/Android/sdk GRADLE_USER_ ...

  9. 用Jenkins自动化构建Android和iOS应用

    背景 随着业务需求的演进,工程的复杂度会逐渐增加,自动化的践行日益强烈.事实上,工程的自动化一直是我们努力的目标,能有效提高我们的生产效率,最大化减少人为出错的概率,实现一些复杂的业务需求应变. 场景 ...

最新文章

  1. 初识广度优先搜索与解题套路
  2. python argparse库_Python的argparse库使用详解
  3. es6+最佳入门实践(10)
  4. 旧闻 - 来怀念一下Sun公司
  5. js中页面与页面传参遇到Uncaught SyntaxError: Unexpected token =报错
  6. ASP.NET Core模块化前后端分离快速开发框架介绍
  7. 六、pink老师学习笔记——CSS三角形之美 margin负值之美文字围绕浮动元素行内块元素布局的巧妙运用
  8. 中国国民休闲状况调查(2020)
  9. 求n!的算法和C 实现
  10. vmplayer虚拟机文件夹共享不生效解决方法
  11. 1篇SCI二区+4篇一类可定A档博士!110万房补,享副教授甚至教授待遇!
  12. Ant Deign Pro - ProTable - 高级表格 通用打印组件
  13. HTML css把图片变圆,HTML+CSS:圆形和圆角图片格式
  14. 点歌机显示歌库服务器未能连接,快速解决常见的六种KTV点歌设备突发故障
  15. 用python将视频转化为图片
  16. 万全服务器t350装系统_联想万全350安装win2003
  17. 雪狐密码箱PwdBox记录导出
  18. vue 路由跳转打开新窗口(被浏览器拦截)
  19. springboot蓝球场馆预约系统毕业设计-附源码211706
  20. struts2漏洞监测_struts2 漏洞 测试方案 与 解决方案

热门文章

  1. 执行perl xttdriver.pl报错Can't locate Getopt/Long.pm in @INC
  2. 可用于企业的 7 个最佳开源 Web 服务器
  3. 改造房车走天下,这个阿里妹子不一般
  4. 第十八章 lamp架构
  5. 六安瓜片在51CTO【礼树迎蛇 红满社区】
  6. 如何在while和for中使用ssh
  7. 虚拟内存的配置(页面文件大小)
  8. ShardingSphere(七) 读写分离配置,实现分库读写操作
  9. extjs 获取id的值_Extjs combox获取显示值和ID值
  10. 面向对象的经验原则小结