提升效率——自動打包上傳蒲公英

劉俊發表於2019-03-17

時間是最寶貴的財富,我們的時間得用在刀刃上。

在文章 使用 Gradle 對應用進行個性化定製 中,我們能夠針對一個應用的正式服、測試服、超管服等其他版本,進行個性化定製。所以經常會有測試跑過來說,幫我打個測試服的包吧、幫我打個正式服的包吧、幫我打個超管服的包吧。我打你一臉包???。

我們的目標是一行命令完成:

  1. 自動編譯 apk 上傳到蒲公英
  2. 上傳完成後輸出二維碼地址和版本號
  3. 支援多環境包上傳

自動上傳蒲公英

直接使用蒲公英的上傳 API ,在 Gradle 中封裝如下方法:

private def uploadPGY(String filePath) {
    def stdout = new ByteArrayOutputStream()
    exec {
        executable = 'curl'
        args = ['-F', "file=@${filePath}", '-F', "_api_key=${rootProject.ext.pgy["apiKey"]}", rootProject.ext.pgy["uploadUrl"]]
        standardOutput = stdout
    }
    String output = stdout.toString()
    def parsedJson = new groovy.json.JsonSlurper().parseText(output)
    println parsedJson.data.buildQRCodeURL
    println "版本號:" + parsedJson.data.buildVersion
}
複製程式碼

好了,執行以上方法就可以實現我們上面的兩個目標啦。看不懂的我們繼續,包教包會。

curl 是一種命令列工具,作用是發出網路請求,然後得到和提取資料,顯示在"標準輸出"(stdout)上面。

我們使用 curl 命令來呼叫蒲公英的介面上傳 apk 檔案。將蒲公英的 apiKeyuploadUrl 放在 config.gradle 中進行統一的管理。

ext{
    pgy = [apiKey   : "xxxxxxxxxxx",
           uploadUrl: "https://www.pgyer.com/apiv2/app/upload"]
}
複製程式碼

stdout 變數是用來獲取網路請求返回的資料流,我們解析成 JSON 物件後列印出二維碼地址和版本號資訊。如果你還想上傳或者輸出更多資訊請檢視蒲公英的上傳 API

這個時候大家要問了,apk 的檔案路徑從哪來呢?

實現不同環境包上傳

我們有正式環境、測試環境和超管環境,並且每個環境生成的 apk 檔名也不同,那麼我們怎麼獲取到 apk 檔案的路徑呢?

統一檔案命名規則

config.gradle 中增加版本資訊

ext{
    pgy = [apiKey   : "xxxxxxxxxxx",
           uploadUrl: "https://www.pgyer.com/apiv2/app/upload"
          ]

    android = [compileSdkVersion: 28,
               buildToolsVersion: "28.0.3",
               minSdkVersion    : 16,
               targetSdkVersion : 28,
               versionCode      : 1,
               versionName      : "1.0.0"
              ]
}
複製程式碼

在根目錄的 build.gradle 中增加獲取 getApkName 方法

def getTestVersionName(String suffix) {
    def testVersion = "001"
    if (suffix == null || suffix.isEmpty()) {
        return String.format("%s.%s", rootProject.ext.android["versionName"], testVersion)
    } else {
        return String.format("%s.%s.%s", rootProject.ext.android["versionName"], testVersion, suffix)
    }
}

def getApkName(String versionName) {
    return String.format("我是一個包-v%s.apk", versionName)
}

複製程式碼

在 application 工程的 build.gradle 中修改 apk 檔名

productFlavors {
        offline {
            buildConfigField "String", "DOMAIN_NAME", "\"https://offline.domain.com/\""
            versionName getTestVersionName("offline") //修改 versionName
        }

        online {
            buildConfigField "String", "DOMAIN_NAME", "\"https://online.domain.com/\""
            versionName rootProject.ext.android["versionName"]
        }

        admin {
            buildConfigField "String", "DOMAIN_NAME", "\"https://admin.domain.com/\""
            versionName versionName getTestVersionName("管理員") //修改 versionName
        }
}

android.applicationVariants.all { variant ->
    variant.outputs.all {
        outputFileName = getApkName(variant.versionName)
    }
}
複製程式碼

實現多環境上傳

def offlineFile = "${projectDir.absolutePath}/build/outputs/apk/offline/release/${getApkName(getTestVersionName("offline"))}"
def adminFile = "${projectDir.absolutePath}/build/outputs/apk/admin/release/${getApkName(getTestVersionName("管理員"))}"
def onlineFile = "${projectDir.absolutePath}/build/outputs/apk/online/release/${getApkName(rootProject.ext.android["versionName"])}"


/**
 * 執行 “uploadOfflineApk” 命令自動打測試服包,並上傳到蒲公英
 */
task uploadOfflineApk(dependsOn: 'assembleOfflineRelease') {
    group = "publish"
    doLast {
        uploadPGY(offlineFile)
    }
}

/**
 * 執行 “uploadOnlineApk” 命令自動打正式服包,並上傳到蒲公英
 */
task uploadOnlineApk(dependsOn: 'assembleOnlineRelease') {
    group = "publish"
    doLast {
        uploadPGY(onlineFile)
    }
}

/**
 * 執行 “uploadAdminApk” 命令自動打超管服包,並上傳到蒲公英
 */
task uploadAdminApk(dependsOn: 'assembleAdminRelease') {
    group = "publish"
    doLast {
        uploadPGY(adminFile)
    }
}
複製程式碼

一行命令打3個包上傳: ./gradlew uploadOfflineApk uploadOnlineApk uploadAdminApk

下篇預告

我們的超管包是需要發給運營人員去使用的,防止洩露導致的安全風險,我們希望對超管包先進行加固然後再上傳到蒲公英。

提升效率——自動加固並上傳到蒲公英

相關閱讀

歡迎關注微信公眾號:**大腦好餓**,更多幹貨等你來嘗

公眾號:大腦好餓

相關文章