提升效率——自動加固並上傳到蒲公英
我們的超管包是需要發給運營人員去使用的,防止洩露導致的安全風險,我們希望對超管包先進行加固然後再上傳到蒲公英。
我們的應用在釋出的時候一般都需要進行加固和生成多渠道包,大家通常的做法應該是下載加固客戶端,或者將 apk 檔案上傳到加固服務的管理後臺進行加固,然後等著加固完成,再下載安裝包檔案。
再次引用我的名言:
時間是最寶貴的財富,我們的時間得用在刀刃上。
本文基於使用 Gradle 實現一套程式碼開發多個應用
中的 Gradle 配置進行迭代開發,帶領大家實現360加固
的自動化 Gradle 指令碼。
自動加固
我們的目標是全自動化,並且在每個團隊成員的電腦上都能夠實現一行命令執行,不需要做額外的配置。
自動下載 360 加固程式
完整的config.gradle
配置:
ext { //簽名檔案配置 signing = [keyAlias: 'xxxxx', keyPassword: 'xxxxx', storeFile: '../sign.keystore', storePassword: 'xxxxxx'] //蒲公英配置 pgy = [apiKey: "xxxx", uploadUrl: "https://www.pgyer.com/apiv2/app/upload"] //360加固配置 jiagu = [name: 'xxxxx', password: 'xxxxx', zipPath: "../jiagu/360jiagu.zip", unzipPath: "../jiagu/360jiagubao/", jarPath: '../jiagu/360jiagubao/jiagu/jiagu.jar', channelConfigPath: '../jiagu/Channel.txt', jiagubao_mac: "http://down.360safe.com/360Jiagu/360jiagubao_mac.zip", jiagubao_windows : "http://down.360safe.com/360Jiagu/360jiagubao_windows_64.zip", ] android = [compileSdkVersion: 28, minSdkVersion: 19, targetSdkVersion : 28] //版本號管理 APP1_VERSION_NAME = "2.0.2" APP1_TEST_NUM = "0001" APP2_VERSION_NAME = "1.0.5" APP2_TEST_NUM = "0005" } 複製程式碼
新建一個jiagu.gradle
檔案:
import org.apache.tools.ant.taskdefs.condition.Os def downloadUrl = Os.isFamily(Os.FAMILY_WINDOWS) ? rootProject.ext.jiagu["jiagubao_windows"] : rootProject.ext.jiagu["jiagubao_mac"] def zipPath = rootProject.ext.jiagu["zipPath"] def unzipPath = rootProject.ext.jiagu["unzipPath"] task download360jiagu() { doFirst { //如果 Zip 檔案不存在就進行下載 File zipFile = file(zipPath) if (!zipFile.exists()) { if (!zipFile.parentFile.exists()) { zipFile.parentFile.mkdirs() } exec { executable = 'curl' args = ['-o', zipPath, downloadUrl] } } } doLast { //解壓 Zip 檔案 ant.unzip(src: zipPath, dest: unzipPath, encoding: "GBK") //將解壓後的檔案開啟讀寫許可權,防止執行 Jar 檔案沒有許可權執行 exec { executable = 'chmod' args = ['-R', '777', unzipPath] } } } 複製程式碼
執行download360jiagu
就可以自動下載並解壓 360 的加固程式啦。
根據多渠道檔案進行加固
import org.apache.tools.ant.taskdefs.condition.Os def downloadUrl = Os.isFamily(Os.FAMILY_WINDOWS) ? rootProject.ext.jiagu["jiagubao_windows"] : rootProject.ext.jiagu["jiagubao_mac"] def zipPath = rootProject.ext.jiagu["zipPath"] def unzipPath = rootProject.ext.jiagu["unzipPath"] //加固後所有apk的儲存路徑 def APP1_OUTPUT_PATH = "jiagu/apk/app1/" def APP1_APK_PATH = "${projectDir.absolutePath}/build/outputs/apk/app1Online/release/${getApkName(rootProject.ext.APP1_VERSION_NAME)}" /** * 加固 * @param config 配置加固可選項 * @param apkPath 要加固的檔案路徑 * @param outputPath 輸出路徑 * @param automulpkg 是否自動生成多渠道包 */ def jiaGu(String config, String apkPath, String outputPath, boolean automulpkg) { //首次使用必須先登入 exec { executable = 'java' args = ['-jar', rootProject.ext.jiagu["jarPath"], '-login', rootProject.ext.jiagu["name"], rootProject.ext.jiagu["password"]] } //升級到最新版本 exec { executable = 'java' args = ['-jar', rootProject.ext.jiagu["jarPath"], '-update'] } //顯示當前版本號 exec { executable = 'java' args = ['-jar', rootProject.ext.jiagu["jarPath"], '-version'] } //匯入簽名信息 exec { executable = 'java' args = ['-jar', rootProject.ext.jiagu["jarPath"], '-importsign', rootProject.ext.signing["storeFile"], rootProject.ext.signing["storePassword"], rootProject.ext.signing["keyAlias"], rootProject.ext.signing["keyPassword"]] } //配置加固可選項 exec { executable = 'java' args = ['-jar', rootProject.ext.jiagu["jarPath"], '-config', config] } //加固命令 def jiaGuArgs if (automulpkg) { jiaGuArgs = ['-jar', rootProject.ext.jiagu["jarPath"], '-jiagu', apkPath, outputPath, '-autosign', '-automulpkg', '-pkgparam', rootProject.ext.jiagu["channelConfigPath"] ] } else { jiaGuArgs = ['-jar', rootProject.ext.jiagu["jarPath"], '-jiagu', apkPath, outputPath, '-autosign' ] } exec { executable = 'java' args = jiaGuArgs } println "加固的檔案路徑:${apkPath}" println "加固後的檔案路徑:${outputPath}" } /** * App1 * 根據多渠道檔案進行加固 * 執行命令:./gradlew releaseApp1 */ task releaseApp1(dependsOn: 'assembleApp1OnlineRelease') { doFirst { //判斷加固程式是否存在,不存在則進行下載 File jarFile = file(rootProject.ext.jiagu["jarPath"]) if (!jarFile.exists()) { download360jiagu.execute() } } group = "publish" doLast { File apkOutputFile = new File(APP1_OUTPUT_PATH, getCurTime()) checkOutputDir(apkOutputFile) File apkFile = file(APP1_APK_PATH) if (!apkFile.exists()) { println("apk file is not exists:" + apkFile.absolutePath) return } jiaGu("-", apkFile.absolutePath, apkOutputFile.absolutePath, true) } } private static void checkOutputDir(File apkOutputFile) { if (apkOutputFile.exists()) { File[] files = apkOutputFile.listFiles() if (files != null) { for (File file : files) { file.delete() } } } else { apkOutputFile.mkdirs() } } static def getCurTime() { return new Date().format("yyyy-MM-dd HH:mm:ss") } 複製程式碼
現在我們只需要在命令列執行./gradlew releaseApp1
就可以靜待輸出了。
在根目錄的jiagu
資料夾中建立Channel.txt
檔案,在其中可以配置你需要的多渠道資訊。
如果需要配置更多的加固選項,可以在jiagu/360jiagubao/jiagu/help.txt
中檢視所有的加固命令。
加固超管包上傳蒲公英
我們的超管包不需要上傳應用商店,直接加固上傳到蒲公英,然後傳送二維碼給管理員下載安裝。我們把自動加固和自動上傳蒲公英整合到一起。
在jiagu.gradle
中新增單獨加固超管包的方法:
def APP1_ADMIN_OUTPUT_PATH = "jiagu/apk/app1Admin/" def APP1_ADMIN_APK_PATH = "${projectDir.absolutePath}/build/outputs/apk/app1Admin/release/${getApkName(getTestVersionName("管理員"))}" /** * 加固超管服包 * 執行命令:./gradlew jiaGuApp1Admin */ task jiaGuApp1Admin(dependsOn: 'assembleApp1AdminRelease') { doFirst { File jarFile = file(rootProject.ext.jiagu["jarPath"]) if (!jarFile.exists()) { download360jiagu.execute() } } group = "publish" doLast { File apkOutputFile = new File(APP1_ADMIN_OUTPUT_PATH) checkOutputDir(apkOutputFile) File apkFile = file(APP1_ADMIN_APK_PATH) if (!apkFile.exists()) { println("apk file is not exists:" + apkFile.absolutePath) return } jiaGu("-", apkFile.absolutePath, apkOutputFile.absolutePath, false) } } 複製程式碼
修改蒲公英上傳方法:
def app1AdminFileDir = "${projectDir.parent}/jiagu/apk/app2Admin/" /** * 執行 “uploadApp1Admin” 命令自動打超管服包,並上傳到蒲公英 */ task uploadApp1Admin(dependsOn: 'jiaGuApp1Admin') { group = "publish" doLast { File dir = new File(app1AdminFileDir) if (!dir.exists()) { println "Alpha dir not exists:" + dir.path return } File[] files = dir.listFiles(new FileFilter() { @Override boolean accept(File file) { return file.isFile() && file.name.endsWith(".apk") } }) if (files == null || files.size() == 0) { println "files == null ||files.size() == 0" return } File apkFile = files[0] uploadPGY(apkFile.path) } } 複製程式碼
在命令列執行./gradlew uploadApp1Admin
就可以靜待二維碼地址輸出。
