社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
不知道是哪一天,安卓同事走过来跟我说能不能帮他搞一个自动打包。
我在网上逛了一圈之后,基本都是差不多的一个思路:先把安卓代码打包成apk包,然后再把apk上传到下载服务器上(并配置apk的下载地址),并生成一个绑定apk下载地址的二维码供测试人员下载。
在实际的使用过程中,可能不同的测试人员需要对同一个app的不同分支同时进行测试,这样在构建的过程中就不能采用覆盖的形式来覆盖上次生成的apk和二维码了。说白了就是每次生成的二维码或apk的名称是不同的。so,我这里采用时间戳作为图片和apk的命名方法。
这里提前说一下踩到的坑吧。我在shell脚本中使用了time=date '+%Y%m%d%H%M%S'
来作为时间戳变量。但是后来在展示二维码的时候,发现这个shell脚本中的变量在Set build description中用不了。仔细想想,当然是用不了的啊,这个又不是全局变量,仅仅是shell脚本中的一个变量而已啊,哎,还是年轻了。
正好Jenkins有一个全局的时间戳变量叫做${BUILD_TIMESTAMP},安装Zentimestamp plugin插件之后就有这个变量可以用了,并且还可以设置时间戳的格式,刚好可以完美的解决我的困扰。
思路有了,废话不多说,开干吧。
在开始构建之前,还是跟之前一样,需要准备下以下的环境
IP地址 | 作用 | |
---|---|---|
Jenkins | 192.168.0.111 | 自动化打包部署 |
Gitlab | 192.168.0.123 | 开发人员用来托管代码 |
Server1 | 192.168.0.124 | 将apk上传至此服务器供测试人员下载 |
准备好这3台服务器之后,下面就开始安装gradle和Android sdk了。在安装之前,最好跟Android开发人员确认下他们的gradle和sdk的版本,毕竟这个是给他们服务的啊,哈哈。我这边已经跟开发确认了,版本情况为:
软件 | 版本 |
---|---|
gradle | 5.4.1 |
Android SDK Platform-tools | 只有一个,貌似没得选 |
Android SDK Build-tools | 28.0.3 |
SDK Platform | Android 9, API 28 |
再多一句嘴,gradle和sdk是安装在Jenkins服务器上的,因为是在Jenkins服务器上进行安卓打包的(感觉这句太废话了。。)。
gradle的下载地址:https://services.gradle.org/distributions/
下载5.4.1版本进行安装
[root@localhost src]# wget https://services.gradle.org/distributions/gradle-5.4.1-all.zip
[root@localhost src]# unzip gradle-5.4.1-all.zip -d /usr/local/
[root@localhost src]# vim /etc/profile
#gradle
export GRADLE_HOME=/usr/local/gradle-5.4.1
export PATH=$PATH:$GRADLE_HOME/bin
[root@localhost src]# source /etc/profile
验证是否配置成功
[root@localhost src]# gradle -v
安卓sdk的下载地址,百度一搜一大把,看到有个网友大神推荐的这个网站还不错http://tools.android-studio.org/index.php/sdk
下载linux版本的sdk进行安装
[root@localhost src]# wget http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz
[root@localhost src]# tar -zxf android-sdk_r24.4.1-linux.tgz -C /usr/local/
[root@localhost src]# vim /etc/profile
#android-sdk
export ANDROID_HOME=/usr/local/android-sdk-linux
export PATH=$PATH:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools
[root@localhost src]# source /etc/profile
完成之后,来查看下所有安卓sdk版本信息
[root@localhost src]# android list sdk --all
根据之前确认的版本信息,需要安装的是第2,6,50个,可以通过下面这个命令进行安装。
[root@localhost src]# android update sdk --all --no-ui --filter 2,6,50
##解释下这个命令,其实用android update sdk --help可以查到
'''
android update sdk #这个是更新或安装sdk的命令
--all #因为上面查看sdk版本信息的时候用了all,所以这里也要加上,不然序号会对不上
--no-ui #指定非 UI 显示
--filter #一个过滤器,以逗号分隔的形式指定需要更新的包的序号
'''
安装完成后的输出结果
再细心点,可以比较下安装前后sdk目录结构的变化
###安装前的sdk目录结构###
[root@localhost local]# tree -L 2 android-sdk-linux
android-sdk-linux
├── add-ons
├── platforms
├── SDK Readme.txt
└── tools
├── android
├── ant
├── apps
├── bin
├── bin64
├── ddms
├── draw9patch
├── emulator
├── emulator64-arm
├── emulator64-mips
├── emulator64-ranchu-arm64
├── emulator64-ranchu-mips64
├── emulator64-x86
├── emulator-arm
├── emulator-mips
├── emulator-ranchu-arm64
├── emulator-ranchu-mips64
├── emulator-x86
├── hierarchyviewer
├── jobb
├── lib
├── lib64
├── lint
├── mksdcard
├── monitor
├── monkeyrunner
├── NOTICE.txt
├── proguard
├── qemu
├── screenshot2
├── source.properties
├── support
├── templates
├── traceview
└── uiautomatorviewer
13 directories, 26 files
###安装后的sdk目录结构###
[root@localhost local]# tree -L 2 android-sdk-linux
android-sdk-linux
├── add-ons
├── build-tools
│ └── 28.0.3
├── platforms
│ └── android-28
├── platform-tools
│ ├── adb
│ ├── api
│ ├── dmtracedump
│ ├── e2fsdroid
│ ├── etc1tool
│ ├── fastboot
│ ├── hprof-conv
│ ├── lib64
│ ├── make_f2fs
│ ├── mke2fs
│ ├── mke2fs.conf
│ ├── NOTICE.txt
│ ├── package.xml
│ ├── sload_f2fs
│ ├── source.properties
│ ├── sqlite3
│ └── systrace
├── SDK Readme.txt
├── temp
└── tools
├── android
├── ant
├── apps
├── bin
├── bin64
├── ddms
├── draw9patch
├── emulator
├── emulator64-arm
├── emulator64-mips
├── emulator64-ranchu-arm64
├── emulator64-ranchu-mips64
├── emulator64-x86
├── emulator-arm
├── emulator-mips
├── emulator-ranchu-arm64
├── emulator-ranchu-mips64
├── emulator-x86
├── hierarchyviewer
├── jobb
├── lib
├── lib64
├── lint
├── mksdcard
├── monitor
├── monkeyrunner
├── NOTICE.txt
├── package.xml
├── proguard
├── qemu
├── screenshot2
├── source.properties
├── support
├── templates
├── traceview
└── uiautomatorviewer
21 directories, 41 files
在打包之前,看一下gradle的官网,从官网中可以看到,从3.0版本开始,Daemon 便默认开启的。它是一个长时间运行的后台进程,作用是在内存中储存构建信息,以便在之后的构建过程中复用信息提高构建速度。但是在文章中,也提到了一句:“If you run CI builds in ephemeral environments (such as containers) that do not reuse any processes, use of the Daemon will slightly decrease performance (due to caching additional information) for no benefit, and may be disabled.”。意思是如果通过CI(持续集成)进行项目构建,Daemon 就没多大作用了,反倒会因为存储额外的信息而降低系统性能,从而导致被停用。
那么怎么停用Daemon呢?
官网中给出了好几种方法,这里我选择相对较为简单的一种,就是在打包命令中加入--no-daemon参数。
所以我们的app的打包命令为:
测试环境:gradle clean --no-daemon assemFortest
生产环境:gradle clean --no-daemon assembleRelease
现在可以手动把代码克隆到服务器上,进行一次手动打测试环境的包。
[root@localhost test_android]# gradle clean --no-daemon assemFortest
打包过程会有点漫长,等出现"BUILD SUCCESSFUL"时证明打包成功了!
百度下"二维码生成",方法少说也有几十种,各种生成二维码的网站遍地开花。
除了在网站上生成二维码,还有一些在服务器本地生成二维码的方法,有java的,有python的,也有linux命令行的。
让我选择,当然是选择linux命令行的。为什么?因为简单方便啊。
linux中生成二维码的命令叫做qrencode,直接用yum安装即可:yum -y install qrencode
命令的使用方法可以man一下查看,这里就简单介绍下
qrencode -o 二维码图片名 -s 二维码像素 下载内容的url
例如:
[root@localhost ~]# qrencode -o /home/dev/images/20190926162209.png -s 8 http://192.168.0.124:81/20190926162209.apk
-o 指定二维码图片的名称
-s 指定二维码像素,默认为3
-d 指定生成的PNG的DPI,默认为72
有些插件之前已经安装过了,在这里也列出来了。
插件 | 作用 |
---|---|
Git plugin | 用于从Gitlab获取代码 |
Git Parameter | 用于选择发布的分支 |
user build vars | 用于设置用户构建变量 |
Build Name and Description Setter | 用于修改构建的显示名称 |
description setter | 用于展示二维码 |
Gradle | 用于app打包 |
Zentimestamp plugin | 使用"BUILD_TIMESTAMP"变量 |
1)系统管理–>系统设置–>全局属性
配置ANDROD_HOME和GRADLE_HOME
2)系统管理–>全局工具配置
配置JDK/Git/Gradle
1)新建项目
选择"构架一个自由风格的项目",名字就叫test_android吧
2)配置"General"
设置项目的描述、时间戳格式、丢弃旧的构建、参数化构建(可以选择发布的环境和分支)
3)源码管理
设置git仓库地址
4)构建环境
设置Build Name
5)构建
配置"Invoke Gradle script"
配置"执行shell"
#!/bin/bash
. /etc/profile
remote_server="192.168.0.124"
remote_user=dev
remote_port=22
remote_dir=/home/dev/apks
remoteshell_path=/home/dev/jenkins_shell/test_android/deploy.sh
apk_dir=$WORKSPACE/app/build/outputs/apk/fortest
apk_remotename=app_${ENVIRONMENT}_${BUILD_TIMESTAMP}.apk
scpapk()
{
echo "transfer apk file to remote servers......"
scp -P $remote_port $apk_dir/*.apk ${remote_user}@${remote_server}:${remote_dir}/${apk_remotename}
if [ $? -eq 0 ];then
echo "transfer apk is success!"
else
echo -e ' 33[31m[ error ] Failed to scp the apk file! 33[0m' && exit 1
fi
sleep 2
}
remotedeploy() {
scpapk
ssh -p $remote_port ${remote_user}@${remote_server} "echo "调用远程脚本" && ${remoteshell_path} ${apk_remotename} ${BUILD_TIMESTAMP}"
}
remotedeploy
在远程服务器上的/home/dev/jenkins_shell/test_android/目录下配置deploy.sh:生成二维码并保留最近5次的二维码和apk
#!/bin/sh
. /etc/profile
apk_name=$1
http_addr=192.168.0.124
http_port=82
qrcode_dir=/home/dev/images
apk_dir=/home/dev/apks
time=$2
apk_url=http://${http_addr}:${http_port}/${apk_name}
left_limit() {
rm -f `ls -t ${qrcode_dir}/*.png | tail -n +6`
rm -f `ls -t ${apk_dir}/*.apk | tail -n +6`
}
makeqrcode() {
qrencode -o ${qrcode_dir}/${time}.png -s 8 ${apk_url}
if [ $? -eq 0 ];then
echo "make qrcode is success!"
else
echo -e ' 33[31m[ error ] make qrcode is Failed! 33[0m' && exit 1
fi
left_limit
}
makeqrcode
在远程服务器上创建二维码和apk的存放目录
[dev@localhost ~]$ mkdir /home/dev/apks /home/dev/images
在远程服务器上配置nginx,用于二维码图片的访问和apk的下载
android.conf
server {
listen 81;
server_name localhost;
location / {
root /home/dev/images;
}
}
server {
listen 82;
server_name localhost;
location / {
root /home/dev/apks;
}
}
6)构建后操作
用html的img标签来展示二维码
构建完成之后,如下图所示
可以直接扫描二维码进行下载,扫描构建历史中最近5次的二维码都可以下载到。
再来看看远程服务器上存放二维码和apk的目录,是否保留了最近的5文件
和预期的一样,完美实现保留最近5个文件的需求。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!