Jenkins实现Android自动打包并生成二维码 - Go语言中文社区

Jenkins实现Android自动打包并生成二维码


一、登录之后进行首页面。


219825-d79024511a3b60a5.png

 

1、配置环境变量

需要配置的环境变量有Android Home、JDK目录、Gradle目录。首先点击系统管理=>系统设置,选中Environment variables,然后新增Android Home环境变量


219825-70006dd3d7929f7c.png

然后在系统管理=>Global Tool Configuration中配置JDK目录和Gradle目录


219825-9ac6a08832fc22e4.png

JDK和Gradle建议提前下载好放到服务器上,不要使用自动安装,Jenkins自动下载安装非常慢

 

2、配置打包脚本

Jenkins配置完成之后需要我们来完善我们的gradle脚本让它能够满足我们的打包要求,既能支持在Jenkins中打包,也能支持我们使用Android Studio进行打包。首先我们需要一个变量IS_JENKINS用来标识当前是在Jenkins中打包还是在Android Studio中打包,在不同环境下打包时证书的路径和APK生成的路径不同,我们定义一个函数来获取证书路径,然后在gradle中指定打包时使用的证书

def getMyStoreFile()

{

if("true".equals(IS_JENKINS))

{

return file("使用Jenkins打包时的证书路径") }

else{

    return file("使用Android Studio打包时证书路径") } }

android

{

signingConfigs

{ release

{

keyAlias '*****'

      keyPassword '****'

      storeFile getMyStoreFile()

storePassword '****' }

}

buildTypes

{

debug{ .... signingConfig signingConfigs.release }

      release{ .... signingConfig signingConfigs.release }

}

....

}

  •  

然后配置不同打包环境下apk的生成路径

android.applicationVariants.all { variant ->

variant.outputs.each { output ->

//新名字

def newName

//输出文件夹

def outDirectory

//是否为Jenkins打包,输出路径不同

if ("true".equals(IS_JENKINS)) {

//BUILD_PATH为服务器输出路径

outDirectory = BUILD_PATH newName = "你的应用名称" + "-" + defaultConfig.versionName + "-" + BUILD_TYPE + ".apk" }

else {

outDirectory = output.outputFile.getParent() newName = "你的应用名称" + "-" + defaultConfig.versionName + "-" + BUILD_TYPE + ".apk" }

output.outputFile = new File(outDirectory, newName) }

}

 

最终完成的gradle脚本为

apply plugin: 'com.android.application'

repositories {

flatDir {

dirs 'libs' }

}

dependencies {

.... }

def getMyStoreFile(){

if("true".equals(IS_JENKINS)){

    return file("使用Jenkins打包时的证书路径") }

else{

    return file("使用Android Studio打包时证书路径") }

}

android {

    signingConfigs {

release {

    keyAlias '*****'

    keyPassword '****'

    storeFile getMyStoreFile()

    storePassword '****' }

}

compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION) buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION

dexOptions { jumboMode true }

      defaultConfig {

applicationId project.APPLICATION_ID

minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION)

targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)

versionName project.APP_VERSION

versionCode Integer.parseInt(project.VERSION_CODE)

ndk {

abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "mips", "mips64", "x86", "x86_64" }

// Enabling multidex support.

multiDexEnabled true }

buildTypes {

debug {

minifyEnabled false

shrinkResources false

signingConfig signingConfigs.release proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' }

release {

// 移除无用的resource文件

shrinkResources true

minifyEnabled true

signingConfig signingConfigs.release

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' }

}

android.applicationVariants.all { variant ->

variant.outputs.each { output -> //新名字

def newName

//输出文件夹

def outDirectory

//是否为Jenkins打包,输出路径不同

if ("true".equals(IS_JENKINS)) {

//BUILD_PATH为服务器输出路径 outDirectory = BUILD_PATH newName = "你的app名字" + "-" + defaultConfig.versionName + "-" + BUILD_TYPE + ".apk" }

else { outDirectory = output.outputFile.getParent() newName = "你的app名字" + "-" + defaultConfig.versionName + "-" + BUILD_TYPE + ".apk" }

output.outputFile = new File(outDirectory, newName) } }

flavorDimensions("channel")

productFlavors { yingyongbao { dimension "channel" } }

productFlavors.all { flavor -> flavor.manifestPlaceholders = [CHANNEL_VALUE: name]

}

packagingOptions {

exclude 'META-INF/DEPENDENCIES.txt'

exclude 'META-INF/LICENSE.txt'

exclude 'META-INF/NOTICE.txt'

exclude 'META-INF/NOTICE'

exclude 'META-INF/LICENSE'

exclude 'META-INF/DEPENDENCIES'

exclude 'META-INF/notice.txt'

exclude 'META-INF/license.txt'

exclude 'META-INF/dependencies.txt'

exclude 'META-INF/LGPL2.1' } }

 

gradle脚本中使用了在gradle.properties中定义的变量,gradle.properties内容如下

org.gradle.daemon=true

org.gradle.parallel=true

manifestmerger.enabled=true

android.useDeprecatedNdk=true

org.gradle.configureondemand=true

org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=4096m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

ANDROID_BUILD_MIN_SDK_VERSION=14

ANDROID_BUILD_TOOLS_VERSION=25.0.1

ANDROID_BUILD_TARGET_SDK_VERSION=22

ANDROID_BUILD_SDK_VERSION=24

VERSION_CODE=176

APPLICATION_ID=你的applicationId #jenkins中用到的变量

NODEJS_ADDRESS=app要访问的服务器地址

API_VERSION=api版本号

APP_VERSION=app版本号

IS_JENKINS=false

BUILD_PATH=apk输出路径

BUILD_TYPE=Debug

 

二、创建Job

经过上面对gradle的配置我们已经做好了准备工作,现在需要在Jenkins上新建一个任务来完成对上面脚本的调用。

在Jenkins中点击新建,输入Job名字,由于Jenkins会根据Job名字生成目录所以建议使用英文不要使用中文,然后选择构建一个自由风格的软件项目,然后点击OK进入配置页面


219825-b49c27b7339be3fe.png

Job配置一共分为六个部分:General、源码管理、构建触发器、构建、构建后操作。

1、General

General中可以配置Job的基本信息,名字、描述等信息,我们需要关注的是关于构建的配置,如果服务器资源比较紧张可以选择丢弃旧的构建,然后选中参数化构建过程,这样就能够在打包的时候输入一些必要的参数,比如App版本号、打包类型、服务器地址、渠道等信息,这些输入参数会在构建过程中替换掉gradle.properties中定义的变量。Jenkins中支持的参数类型有Boolean、Choice(下拉选择形式的)、String、Git(需要安装插件)。网上其他文章中提到的Dynamic Parameter Plug-in由于安全性问题已经不再支持。下面看一下我们需要添加参数:


219825-0703205f0461e77d.png

BUILD_TYPE表示构建版本是Release版还是Debug版,这样可以区分App是正式版本还是内容测试版本。JS_JENKINS表示这是从Jenkins打包的,默认值为true


219825-6e2259ffb9b36cb7.png

PRODUCT_FLAVORS表示App的渠道,我们目前只设置了应用宝这个一个渠道,如果渠道包多的话这样打包效率比较低,需要一个专门进行多渠道打包的工具。APP_VERSION表示APP的版本号,这里添加这个参数是为了能够让运维人员在App发布时能够指定发布的版本号。


219825-a8349b63dd6b8124.png

GIT_TAG用于在打包时选择使用仓库上哪个分支或者TAG,其中Parameter Type可以选择Tag、Branch、Branch or Tag或者revision,这里我们选择Branch or Tag


219825-76bc5757e623763a.png

NODEJS_ADDRESS表示服务器地址,这里可以配置上测试环境、生产环境地址,在打包时选择要哪个后台服务。


219825-9eef0276cb5374ee.png

REMARK用来描述本次打包的版本,比如这次打包使用来验证哪个问题等等,要不然单凭版本号很难想起当时打包这个版本是用来干什么的。

2、源码管理

我们公司使用Gitlab进行代码管理,这里选择git,然后输入仓库地址,并在Branch Specifier绑定GIT_TAG变量,这样GIT_TAG会自动读取仓库上的分支和TAG列表。


219825-97c5327e590df3b4.png

 

3、构建触发器

构建触发器用来配置什么时候触发构建,一般做法有手动触发、定时触发、或者提交代码时触发。提交代码触发需要在gitlab中添加webhook,我们这里使用手动触发所以这里不做配置

 

4、构建环境

通过选中Set Build Name设置构建名称,我们这里设置名称为

#${BUILD_NUMBER}_${BUILD_USER}_${APP_VERSION}_${BUILD_TYPE}

 

在Jenkins中${}表示引用变量,其中BUILD_NUMBER为构建编号,为Jenkins提供的变量;BUILD_USER为构建人,即当前登录用户,需要选中Set jenkins user build variables;APP_VERSION为App版本号;BUILD_TYPE为构建类型。一个实际的构建名称为#14_admin_1.2_Release,表示第14次构建,构建人为admin,构建的App版本为1.2Release版本


219825-adc25624b9e2f105.png

 

5、构建


219825-a9426521b0d6429a.png

选中invoke gradle通过调用gradle脚本进行构建,选择在系统管理中配置的gradle的版本,这里为gradle4.0

然后在Tasks输入打包命令

clean assemble${PRODUCT_FLAVORS}${BUILD_TYPE}

 

首先执行clean,然后执行assemble进行打包。以PRODUCT_FLAVORS选择yingyongbao,BUILD_TYPE为Release为例,则实际执行的命令为

clean assemble Yingyongbao Release

 

然后选中Pass job parameters as Gradle properties这样才能将我们自定义参数在打包时传递到gradle脚本中

这样我们就能成功打包出apk了

 

三、实现二维码下载

为了能够更方便的使用,我们还应该提供一个二维码功能,这样手机扫描之后就能下载安装。一般做法有两个:一是选择将打包出来的apk上传到第三方平台蒲公英;另一个是本地搭建一个服务,实现静态文件服务器的功能。我们这里选择上传到第三方平台蒲公英。

 

下载插件:jenkins -> 系统管理 -> 插件管理,搜索 Upload to pgyer,点击下载,下载完的效果如下图:

在 jenkins 的 job 配置页面 构建或 构建后操作中添加构建步骤 upload to pgyer 如下图:

7309174-49a0e0e37daa5662.png

 

在 jenkins 的 job 配置页面 构建或 构建后操作中添加构建步骤 upload to pgyer 如下图:

 7309174-953c2d27fe8cfc19.png

 

插件添加成功后,会显示一下效果:

7309174-d4f812a913f27b48.png

 

插件填写参数说明:参数说明

pgyer uKey蒲公英的 uKey (必填)

pgyer api_key蒲公英的 api_key (必填)

scandir ipa/apk 所在目录 (必填)

file widcard上传文件的通配符 (必填)

installType(optional)应用安装方式,值为(1,2,3)。1:公开,2:密码安装,3:邀请安装。默认为1公开(选填)

password(optional)设置App安装密码(选填)

updateDescription(optional)版本更新描述(选填)

qrcodePath(optional)如果你需要下载蒲公英返回的二维码,那么这里填写二维码的存储路径,如果你不需要下载,那么你不需要在这里填写任何内容(选填)

envVarsPath(optional)如果你想存储蒲公英返回的上传信息,那么这里填写保存信息的文件路径,如果你不需要保存,那么你不需要在这里填写任何内容(选填)

注意:

qrcodePath与envVarPath是存储二维码和应用信息的文件路径地址,而不是一个文件夹的地址。例如可以这样填写这两个参数:

qrcodePath: /Users/James/Integration/${BUILD_TYPE}/${BUILD_TIME}/qrcode.png

envVarPath: /Users/James/Integration/${BUILD_TYPE}/${BUILD_TIME}/envVars.txt**

执行构建,蒲公英上传插件将输出相应的 log,如下图:

上传蒲公英成功后,可在 jenkins 中的其他构建中使用蒲公英上传成功后返回的参数:

这款会将蒲公英返回的参数注入为jenkins的全局变量,在其他构建步骤的使用方法直接引用这个全局变量即可,变量名称直接使用返回的 key值。例如:${appBuildURL}

注意:

qrcodePath与envVarPath是存储二维码和应用信息的文件路径地址,而不是一个文件夹的地址。例如可以这样填写这两个参数:

qrcodePath: /Users/James/Integration/${BUILD_TYPE}/${BUILD_TIME}/qrcode.png

envVarPath: /Users/James/Integration/${BUILD_TYPE}/${BUILD_TIME}/envVars.txt**

我的配置

 

7309174-47a249486ecf6869.png

 

${WORKSPACE}/app/build/outputs/apk/${PRODUCT_FLAVOR_BUILD}/${ENVIRONMENT}

#${CHANGES_SINCE_LAST_SUCCESS}${BUILD_NUMBER}-${APPLICATION_ID}-${APP_VERSION}-${PRODUCT_FLAVOR_BUILD}-${ENVIRONMENT}${BUILD_NUMBER}-${APPLICATION_ID}-${APP_VERSION}-${PRODUCT_FLAVOR_BUILD}-${ENVIRONMENT}

${WORKSPACE}/app/build/outputs/apk/${PRODUCT_FLAVOR_BUILD}/${ENVIRONMENT}/${BUILD_TAG}/qrcode.png

${WORKSPACE}/app/build/outputs/apk/${PRODUCT_FLAVOR_BUILD}/${ENVIRONMENT}/${BUILD_TAG}/envVars.txt**

 

最后打包成功之后的效果


219825-577407527b3592e5.png

 

有了这个前提,我们可以以html的形式让二维码显示出来,但是Jenkins默认是plain text模式,不会对html解析的。所以我们需要在全局安全设置(Configure Global Security),将Markup Formatter的设置更改为Safe HTML即可。

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/m0_37787904/article/details/100563697
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-05-22 10:48:48
  • 阅读 ( 457 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢