Android Gradle Task 自動打包上傳到蒲公英并通知企業(yè)微信機器人

近期頻繁的打包, 有點心累, 所以有了這篇文章. 話不多說, 直接開整.

先上企業(yè)微信機器人通知的效果


image.png

1. 創(chuàng)建 task.gradle

在項目的 build.gradle 所在的目錄下創(chuàng)建一個 task.gradle 內容如下

project.ext {
    uploadTask = { extension,versionName ->
        extension.android {
            task upload2Pgyer(group: 'upload', description: 'Upload apk to pgyer', dependsOn: 'assembleDebug') {
                doLast {
                    android.applicationVariants.all { variant ->
                        String taskSuffix = variant.name.capitalize()
                        //輸出versionname
                        if (taskSuffix.equals("Debug")) {
                            variant.outputs.all { output ->
                                // 執(zhí)行腳本任務
                                uploadApk(output.outputFile, versionName)
                            }
                        }
                    }
                }
            }
        }
    }
}

我這里是只打了debug包. 別的環(huán)境的自己的需求進行修改.
接著就需要創(chuàng)建具體的執(zhí)行任務的上傳及通知腳本了.

2. 創(chuàng)建 pgyer-upload.gradle

代碼較多, 后面一些獲取git提交日志的方法沒有用到. 不需要的可以刪掉. 通知的內容改成了 markdown 的形式, 看起來好看一點. 這點看個人需求了. 不需要的可以將

    def json = JsonOutput.toJson([
            msgtype: "markdown",
            markdown: [
                    content: message
            ]
    ])

這里的 markdown 改為 text. 完整代碼如下:

import groovy.json.JsonSlurper
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
import java.text.SimpleDateFormat
import groovy.json.JsonOutput
ext.uploadApk = this.&uploadApk

def String makeMarkDownText(String versionName, String url, String updateTime) {
    return """
      ### <font color="warning">**新版本更新**</font>\n
      > 應用名稱:<font color="info">app名稱</font>
      > 應用類型:<font color="info">Android</font>
      > 對應版本:<font color="info">${versionName}</font>
      > 應用環(huán)境:<font color="info">國內測試環(huán)境</font>
      > 更新日期:<font color="info">${updateTime}</font>\n
      > 更新內容如下
      > <font color="info">1. Gradle</font> 
      > <font color="info">2. Task</font>
      > <font color="info">3. 自動構建</font>
      > <font color="info">4. 自動上傳</font>
      > <font color="info">5. 自動通知</font> \n
      > [點擊鏈接安裝此版本](${url}) \n
      """
}

static String getApiKey() {
    return "蒲公英的APIKEY"
}
static String getPgyDescription() {
    return ""
}

def uploadApk(File apk, String versionName) {
    //查找上傳的apk文件,這里需要換成自己apk路徑
    if (!apk.exists()) {
        println "*************** APK 文件不存在 ***************"
    }
    println "*************** 開始上傳文件 ***************"
    def twoHyphens = "--"
    def boundary = "*********"
    def end = "\r\n"

    //模擬表單上傳 multipart/form-data
    def conn = new URL("https://www.pgyer.com/apiv2/app/upload").openConnection()
    conn.setRequestMethod('POST')
    conn.setRequestProperty("Connection", "Keep-Alive")
    conn.setRequestProperty("Charset", "UTF-8")
    conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary)
    conn.setDoInput(true)
    conn.setDoOutput(true)
    //添加參數:_api_key
    def sb = new StringBuilder()
    sb.append(twoHyphens).append(boundary).append(end)
    sb.append("Content-Disposition: form-data; name=_api_key")
    sb.append(end).append(end)
    sb.append(apiKey).append(end)

    //添加參數:buildUpdateDescription 更新日志,取值gradle.properties中的 BUILD_NOTES
    sb.append(twoHyphens).append(boundary).append(end)
    sb.append("Content-Disposition: form-data; name=buildUpdateDescription")
    sb.append(end).append(end)
    sb.append(pgyDescription).append(end)

    //添加參數file: 需要上傳的apk文件
    sb.append(twoHyphens).append(boundary).append(end)
    sb.append("Content-Disposition: form-data; name=file;filename=").append(apk.getName())
    sb.append(end).append(end)

    def dos = new DataOutputStream(conn.getOutputStream())
    dos.writeBytes(sb.toString())
    dos.flush()
    sb.delete(0, sb.length())

    def fis = new FileInputStream(apk)
    byte[] bf = new byte[8192]
    int len
    while ((len = fis.read(bf)) != -1) {
        dos.write(bf, 0, len)
    }
    sb.append(end)
    sb.append(twoHyphens).append(boundary).append(end)
    dos.writeBytes(sb.toString())

    dos.flush()
    fis.close()
    dos.close()
    conn.connect()

    def text = conn.getContent().text

    def resp = new JsonSlurper().parseText(text)

    println text
    if (resp.code != 0) {
        println "*************** 上傳失敗 *************** 原因 " + resp.message
    }else  {
        println "*************** 上傳成功 ***************"
    }

    def downloadUrl = "https://www.pgyer.com/" + resp.data.buildShortcutUrl.strip()
    def updateTime = resp.data.buildUpdated
    def content = makeMarkDownText(versionName, downloadUrl, updateTime)

    notifyWeChatBot(content)
}

/**
 * 通知企業(yè)微信機器人
 */
def notifyWeChatBot(String message) {
    // 替換以下變量為你的企業(yè)微信機器人 webhook URL
    def webhookUrl = "企業(yè)微信機器人的urlkey"

    // 構建 JSON 數據
    def json = JsonOutput.toJson([
            msgtype: "markdown",
            markdown: [
                    content: message
            ]
    ])

    // 發(fā)送 HTTP POST 請求
    HttpResponse<String> response = postJsonData(webhookUrl, json)

    // 打印響應結果
    println ">>>> 企業(yè)微信機器人通知結果:\n${response.body()}"
}

/**
 * 發(fā)送 JSON 數據的 HTTP POST 請求
 */
static HttpResponse<String> postJsonData(String url, String json) {
    HttpRequest httpRequest = HttpRequest
            .newBuilder(URI.create(url))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(json))
            .build()
    return HttpClient.newHttpClient().send(httpRequest, HttpResponse.BodyHandlers.ofString())
}



/**
 * 獲取當天提交日志
 * @return
 */
static String getGitCommitLogByToDay() {
    //獲取 git 提交日志
    Calendar calendar = Calendar.getInstance()
    String endTime = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime())
    calendar.add(Calendar.DATE, -1)
    String startTime = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime())
    //git 命令
    String gitCommand = "git log --pretty=\"%s\" --since=\"${startTime}\" --before=\"${endTime}\""
    //println "getUpdateDescription() --> gitCommand = ${gitCommand}"
    String description = gitCommand.execute().text.trim()
    return description
}

/**
 * 獲取最近 n 條提交日志
 */
static String getGitCommitLogByCount(int count) {
    //git 命令
    String gitCommand = "git log -${count} --pretty=format:\"%s\""
    //println "getUpdateDescription() --> gitCommand = ${gitCommand}"
    String description = gitCommand.execute().text.trim()
    return description
}

/**
 * 獲取分支名
 */
static String getBranchName() {
    String gitCommand = "git rev-parse --abbrev-ref HEAD"
    return gitCommand.execute().text.trim()
}

class KeyValue {
    String key
    String value
    boolean isFile

    KeyValue(String key, String value) {
        this(key, value, false)
    }

    KeyValue(String key, String value, boolean isFile) {
        this.key = key
        this.value = value
        this.isFile = isFile
    }

    @Override
    String toString() {
        return "{key:" + key + ", value:" + value + ", isFile:$isFile}"
    }
}

3. 使用

app module 下中的 build.gradle 文件中添加

apply from: "${rootProject.rootDir}/task.gradle"
apply from: "${rootProject.rootDir}/pgyer-upload.gradle"

重新編譯后,在Gradle 工具側欄中的 Tasks 目錄下就回有一個 upload 的文件夾, 里面有一個 uplopad2Pgyer 的任務. 雙擊就能執(zhí)行腳本了. 自動打Debug包, 然后上傳到蒲公英, 并發(fā)送企業(yè)微信通知了.

image.png

4. 遇到的問題

4.1 Tasks 沒有顯示

遇到 Gradle 中的這個 Tasks 沒有出現(xiàn)的. 需要進行設置一下. 如下圖

image.png
4.2 IPv6

我電腦開啟了ipv6, 一直報錯, 關閉了后就正常了. 遇到此問題的可以嘗試一下這個操作.

后面遇到其他問題了, 繼續(xù)記錄.

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容