文章目录

  • 思路
  • 编写Gradle自定义任务
  • 命令行调用360加固
    • 执行构建并获取apk
    • 获取加固程序
    • 执行加固
    • 签名
    • 拷贝文件到指定位置
  • Jenkins调用加固并发送邮件

项目中使用到了360加固与阿里的热修复方案,以前是人工去操作加固或生成补丁包,比较浪费开发人员的时间,并且在我的电脑上每次命令行执行完全量编译都会卡很久。前段时间项目不紧,所以抽时间完成了在Jenkins流水线上进行360加固与生成热修复补丁的步骤。本文主要介绍实现Jenkins上进行自动加固的过程。

思路

先简单描述一下项目相关的一些背景条件:

  1. 项目采用git-flow分支模型,在release分支提测,并且当测试通过时需要对应版本的正式环境的apk进行冒烟测试。
  2. 由于用到了热修复,所以需要保存加固前的原apk及mapping文件。
  3. Jenkins构建节点为mac电脑,我个人使用的是Ubuntu,所以加固的脚本需要至少在Mac/Linux上都可以正常执行。
  4. 安全起见,不导入签名到360加固中。

由于后续的热修复的需要,我在项目中约定,当版本发布时,在项目的release/文件夹下保存该版本的apk及mapping文件。在前面所述背景条件下,加固过程比起网上的多数文章会偏复杂一点,在项目中我需要依次实现以下过程:

  1. 构建正式环境的flavor,并将apk及mapping文件拷贝到release/文件夹下。
  2. 执行加固并签名。
  3. 将加固前apk,mapping文件及加固后的apk通过邮件发送出来。

考虑到对于我实现这些过程的容易程度,我决定第一步使用自定义gradle任务实现,第二、三步使用shell脚本实现,第四步使用Jenkins的发邮件功能实现。

编写Gradle自定义任务

我们项目中用于区分正式、测试、预发布环境是使用productFlavor来实现的,所以我在app的build.gradle中定义了以下任务:

android.applicationVariants.all { variant ->if (variant.buildType.name == "release") {def variantName = variant.flavorName.capitalize()def releaseDir = new File(rootProject.rootDir, "release")Task releaseTask = task "release${variantName}"(dependsOn: "assemble${variantName}Release") {group = 'publish'description "Copy the output apk and mapping file to target folder for ${variant.name}"inputs.files(variant.outputs[0].outputFile, variant.mappingFile)outputs.dir releaseDir}releaseTask.doLast {// 需要保留 mapping.txt 文件用于热修复if (variant.buildType.minifyEnabled) {println "copy ${variant.mappingFile}"copy {from variant.mappingFileinto releaseDirrename {"mapping-${variant.name}-${variant.versionName}.txt"}}}println "copy ${variant.outputs[0].outputFile}"copy {from variant.outputs[0].outputFileinto releaseDirrename {"IOP-${variant.name}-${variant.versionName}.apk"}}}}
}

我解释一下上面的代码,很简单很好理解。
这里对于所有的productFlavorrelease构建类型,创建了对应的依赖该assemble任务的任务,任务名称为release${variantName}。比如productFlavor名称为Official,则这里创建的任务名称为releaseOfficial,并且依赖于assembleOfficialRelease任务,其中assembleOfficialRelease即我们用于构建apk的任务。
在任务里我指定了任务所在分组及描述,这是为了能够在执行./gradlew app:tasks或在Android Studio右边的Gradle面板中显示出该任务来。另外我指定了inputs及outputs,这是为了实现UP-TO-DATE的效果,即如果对应的assemble任务的输出结果没有变,并且这里的outputs没有变,就不会再重复拷贝。
然后我通过调用这个任务的doTask方法,给这个任务增加了一个Action,把apk及mapping文件拷到项目根目录下的release文件夹中并重新命名。
到此这个过程就完成了,也就是我们只需要执行./gradlew releaseOfficial,就会进行Official的构建,并把其apk和mapping拷贝到release文件夹下。

注:关于Gradle编写自定义任务的详细介绍,可参考我翻译的Gradle用户指南:《第五十七章. 编写自定义任务类》。

命令行调用360加固

我这里是采用shell脚本实现,脚本文件将位于项目根目录的buildsystem文件夹下。我把这一过程拆分为五部分。

  1. 执行releaseOfficial进行构建。
  2. 获取加固程序。
  3. 执行加固。
  4. 签名
  5. 拷贝加固前后相关文件到指定文件夹下,以便于后续的邮件发送。

执行构建并获取apk

由于我这里的shell脚本是通过Jenkinsfile来调用的,所以并不知道生成的apk名称。因此我的思路是,先创建一个文件,然后再调用构建任务,最后找出release文件夹下比刚才所创建文件新的apk文件,即这次构建所生成的apk文件。脚本如下:

#!/bin/bashcd `dirname $0`/../
projectDir=`pwd`
buildDir="$projectDir/build"# release Official apk
cd $buildDir
touch timestampFile
echo "Build release official apk"
cd $projectDir
# invoke gradlew to build the official apk
./gradlew releaseOfficial || exit 1
# find the target apk
targetApk=`find $projectDir/release -name "*.apk" -newer $buildDir/timestampFile`
if [ ! -n "$targetApk" ]; thenecho "Apk is not changed. Exit"exit 0
fi

获取加固程序

360加固为windows, linux及mac分别提供了对应平台的加固助手。我下载了这三个平台的加固助手后,发现主要是java/bin里面的文件不同,这里的文件会依赖于具体平台的可执行文件。所以我的思路是,把这三个平台的文件都打包到一起,然后在调用的时候,先判断当前的操作系统,再拷贝对应的文件到java/bin目录下。经测试,在linux/mac上方案通过。

我在github上创建了对应的项目,将集成的文件上传并打了1.0的tag。通过https://github.com/msdx/360-jiagu/archive/1.0.zip这个地址可以下载到项目的zip包。为避免每次构建都去重新下载,在实际的项目中,我又加上了七牛的cdn地址,这里略过,还是采用github的地址。
将它下载下来后,解压并执行项目里的init.sh脚本,把平台相关的文件拷贝到java/bin目录下。
这一过程完整脚本如下:

# download the program
cd ~/
jgCacheDir=".android/jiagu"
jgVersion="1.0"
jgFolder=360-jiagu-$jgVersion
jgZipName=$jgFolder.zip
if [ ! -d "$jgCacheDir" ]; thenmkdir $jgCacheDir
fi
cd $jgCacheDirif test -e "$jgZipName"; thenzflag=" -z $jgZipName"
elsezflag=""
fi
# 这里需要把地址换成自己的cdn地址,以避免每次构建都去下载
curl -L -e ";auto" -o $jgZipName $zflag https://github.com/msdx/360-jiagu/archive/$jgVersion.zip# extract
cd $buildDir
echo "Extract jiagu.zip"
unzip -oq ~/$jgCacheDir/$jgFolder -d .
if [ ! -d "jiagu" ]; thenmv $jgFolder jiagu
elsecp -rf $jgFolder/* jiagu/
fi
cd jiagu && ./init.sh || exit 1cd $buildDir/jiagu

上面下载使用了curl而不是wget,是因为我发现在公司的mac机器上,没有wget,于是只好使用curl来代替wget。
注意这里,应该把地址换成自己的cdn地址,不然可能每次都会去重新下载。

执行加固

在执行加固前需要进行账号登录。我这里把账号及密码配置在Jenkins的环境变量中。由于个人不是很信任360,所以并没有把签名证书导入进去,这里只是进行加固。这部分的脚本如下:

# login
if [ ! -n "$1" ] || [ ! -n "$2" ]; thenusername=$JIAGU_USERNAMEpassword=$JIAGU_PASSWORD
elseusername=$1password=$2
fi
java -jar jiagu.jar -login $username $password
# remove unnecessary service config
java -jar jiagu.jar -config -
# process
for file in `find output -name "*.apk"`; dorm $file;
done
echo "Start process $targetApk"
java -jar jiagu.jar -jiagu $targetApk output || exit 1
enhancedApk=`find output -name "*.apk"`

在上面的脚本中,所有增强服务我都没有选,这一步可根据自己需要去配置。

签名

我自己写过一个签名的脚本,这里我把脚本放在同一目录下,所以直接调用该脚本签名,如下:

# sign
echo "Sign $enhancedApk"
$projectDir/buildsystem/signIOP.sh $enhancedApk

签名脚本的实现可以参考我写的签名脚本,项目地址为:https://github.com/msdx/scripts。

拷贝文件到指定位置

接下来,是把文件拷贝到archives文件夹下,并保存当前git提交信息。

# cp the archives to folder
if [ ! -d "archives" ]; thenmkdir archives
elserm archives/*
fi
cp $enhancedApk archives/
for file in `find $projectDir/release -type f -newer $buildDir/timestampFile`; docp $file archives/
done
git log -n 1 > archives/git-info.txt

完整脚本可参考我的gist:https://dwz.cn/ym6pqPMZ

Jenkins调用加固并发送邮件

最后是修改我们的Jenkinsfile,调用加固脚本,并发送邮件。在这里,增加一个Enhancestage,如下:

        stage ('Enhance') {when {expression { BRANCH_NAME ==~ /release\/.*/ }}steps {sh "./buildsystem/jiagu.sh"emailext(subject: "IOP-Android加固成功",mimeType: "text/html",attachmentsPattern: "build/jiagu/archives/*",body: enhanceEmailBody(),recipientProviders: [[$class: 'CulpritsRecipientProvider'],[$class: 'DevelopersRecipientProvider'],[$class: 'RequesterRecipientProvider']])}}

其中邮件内容如下:

def getChangeString() {def changeString = ""def changeLogSets = currentBuild.changeSetsfor (int i = 0; i < changeLogSets.size(); i++) {def entries = changeLogSets[i].itemsfor (int j = 0; j < entries.length; j++) {def entry = entries[j]truncated_msg = entry.msgchangeString += " - ${truncated_msg}\\\\n"}}if (!changeString) {changeString = " - No new changes"}return changeString
}def enhanceEmailBody() {return """<p>IOP-Android加固成功。</p><p>更新日志:<br/>${getChangeString().replaceAll("\\\\\\\\n", "")}</p><p>附件说明如下:</p><ol><li>文件名带jiagu的,是加固后的包,用于分发。</li><li>文件名不带jiagu的,与mapping开头的txt文件,用于生成补丁。</li><li>git-info.txt文件为本次构建代码的最新git信息。</li></ol></p>"""
}

大功告成。

Jenkins之自动进行360加固相关推荐

  1. Android项目jenkins自动化构建之360加固(一)

    Android项目jenkins自动化构建之360加固(一) 最近Jenkins接手一个项目,项目自动化构建都是在jenkins上做的,包括打包构建--360加固--apk签名--邮件发送apk 总共 ...

  2. android+360加固教程,Jenkins+Android自动打包续2:用360加固程序加固

    360加固保介绍,具体见其官方网站 360加固保 现在安卓APP为了代码安全,都要求在发布前先加固,可以自己写加固程序加固,我选择用第三方加固软件:360加固保加固(其他加固软件也一样),具体实现如下 ...

  3. Android项目Jenkins配置(自定义参数构建,构建完成后360加固+自动下载签名+多渠道配置,自动乐固加固+签名,自动上传蒲公英,自动上传OSS,自动发送钉钉消息,自动发送企业微信应用)

    Mac,window,unix,Linux等系统安装Jenkins服务就不说了... 直接上干货 编译后shell脚本参考 #推送钉钉群curl 'https://oapi.dingtalk.com/ ...

  4. 最强打包插件,支持fir,蒲公英上传, 360加固 ,自动生成二维码

    文章目录 序言 说明 效果 使用 下载demo 导入文件 文件内容说明 配置gradle 配置gradle.properties 文件位置 内容 项目中配置 补充说明 1.360加固配置 2.curl ...

  5. 360加固签名验证_360加固助手加固应用并自动签名的方法

    360加固助手加固应用并自动签名的方法!360加固助手是一款最专业的安全保护加固助手,专为软件应用开发者量身打造的apk加固软件,它可以有效的防止应用软件被逆向分析.反编译.二次打包等才做,不过很多很 ...

  6. 360加固apk并自动签名

    我们知道Android加混淆之后,代码的安全性得到了提高,即使你hook,反编译得到的也是乱码的,对于阅读性造成了影响,为了增强代码的破解难度,我们通常退对apk进行加固,常见的有腾讯,360,爱加密 ...

  7. android插件开发,使用360加固自动多渠道打包

    android插件开发,使用360加固自动多渠道打包 最近研究了一下安卓插件的开发,就以开发一个360加固自动打包插件为例,练了一下,本次使用android studio基于kotlin构建自动打包插 ...

  8. jenkins 批量360加固apk

    jenkins 批量360加固apk @echo on set keyStorePath=%WORKSPACE%\Assets\keystore\renjiao.keystore mowenjiaoy ...

  9. 360加固保自动签名配置了签名还一直提示签名配置中未找到此APK使用的签名

    最近使用360加固保的时候,使用自动签名一直提示签名配置中未找到此APK使用的签名,在360社区里翻了一上午全是只有问题没有答案,很是烦躁. 最后还是官方靠谱,加了客服qq给出了答案:复制一个原包,将 ...

最新文章

  1. 2022-2028年中国文化创意产业园区域发展模式与产业整体规划研究报告
  2. 【转】U3D手游《苍穹变》性能优化经验谈
  3. 使用python简单连接并操作数据库
  4. uml 时序图_面向对象设计与统一建模语言UML
  5. java es api jar包_Elasticsearch 搜索服务器 Java API 使用详解
  6. using和名空间namespace
  7. webApi项目中的问题
  8. 订单接收不同业务消息设计
  9. linux拿虚拟机充当路由,Linux通过虚拟机模拟路由器实现主机跨路由通信
  10. nginx搭建文件服务器
  11. 广东省计算机一级网络题分值,计算机一级考试内容题型以及分值
  12. MATLAB中的均值与方差求法(mean,var,std函数使用)
  13. 常见Flash小游戏开发核心思想笔记——《拼图》
  14. orcad 连mysql_OrCAD Capture CIS元件库用mysql数据库
  15. PIPIOJ1166PIPI的棋盘
  16. 打开php文件url格式,url格式是什么
  17. Python 科赫曲线绘制
  18. 暴走欧洲之文明的迭代
  19. Mathematica实例——利用Mathematica演示量子力学中的波包演化
  20. nor flash操作

热门文章

  1. Xnip Mac上方便好用的截图工具
  2. PHP调用微信wx_JSSDK录音并播放,
  3. Java加密1-散列函数
  4. 图书馆借阅管理系统(图书管理系统),可提供远程搭建运行服务
  5. 计算机无法自动排列,如何设置Excel表不能自动排序
  6. android 全键盘手机排行榜,小巧又精悍 3大系统直板全键盘手机搜罗
  7. python智力问答游戏_Python语言编写智力问答小游戏功能
  8. 大数据入门及各类技术介绍
  9. 基于Epoll的Reactor模式
  10. diagrams 一个完全可以代替visio的软件