Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

分享一个测试通过的 Jenkinsfile 支持 apk,wgt 构建 #9

Open
bestK opened this issue Dec 18, 2023 · 3 comments
Open

分享一个测试通过的 Jenkinsfile 支持 apk,wgt 构建 #9

bestK opened this issue Dec 18, 2023 · 3 comments

Comments

@bestK
Copy link

bestK commented Dec 18, 2023

// 判断 manifest.json 中 versionCode 是否大于上一个版本则执行构建 apk eg:  $.versionCode2 > $.versionCode2
// 判断 git comment 中包含 [release] 则执行构建 apk eg: feat: xxxx [release]
// 判断 git comment 中包含 [wgt] 则执行构建 wgt eg: feat: xxxx [wgt]
// 构建成功之后自动更新 ctms app 版本信息
// ===============================
// >>>>>>mamifest.json 必填参数<<<<<
// $.description 更新描述
// $.versionName 版本号
// $.versionCode 版本号
// $.uapp.type 1101:android 1103:ios
// $.uapp.forceUpdate 是否强制更新
// $.uapp.diff 最大相差版本
// ================================

import groovy.json.JsonSlurper

pipeline {
    agent any

    environment  {
        APP_NAME = "ctms"
        MENTION_USERS = '"AAA BBB","小明"'
        PRODD_SERVER_HOST = credentials('example-prod-host-248')
        RELEASE_UPDATE_URL = "https://ctms.example.com/ctms/appVersion/add"
        RELEASE_USERNAME = credentials('example-admin-username')
        RELEASE_PASSWORD = credentials('example-admin-password')
    }

    stages {
        stage('release') {
            steps {
                script {
                    // 1. 获取上一个版本号
                    def previousVersion = getPreviousVersion()

                    // 2. 获取当前版本号
                    def currentVersion = getCurrentVersion()

                    echo "Previous Version: ${previousVersion}"
                    echo "Current Version: ${currentVersion}"

                    // 3. 比较版本号 或者 提交信息中含有 [release] 字样
                    if (isVersionGreaterThan(currentVersion,previousVersion) || isReleaseCommit()) {
                        echo "🚀 Current version is greater than the previous version. Starting build..."
                        // 4. 执行构建
                        def buildCommand = """
                        cd android && \
                        chmod +x ./gradlew && \
                        uapp manifest ../manifest.json && \
                        uapp run build
                        """ 

                        echo "🛠️ Executing command: ${buildCommand}"

                        try {
                            def result = sh(script: buildCommand, returnStatus: true)
                            if (result == 0) {
                                echo "✅ Build successful. "
                                // 设置变量 HAS_RELEASE_OUT 为 true
                                env.HAS_RELEASE_OUT = true
                                env.RELEASE_VERSION = currentVersion
                                echo "🎉 Release version: ${env.APP_NAME} ${env.RELEASE_VERSION} ${env.HAS_RELEASE_OUT}"
                                echo "🎉 Release path: ./android/app/build/outputs/apk/release/app-release.apk"
                                
                            } else {
                                error "❌ Build failed. Exit code: $result"
                            }
                        } catch (Exception ex) {
                            error "❌ Error during build: $ex.message"
                        }
                    } else {
                        echo "⏭️ Current version is not greater than the previous version. Skipping build."
                    }
                }
            }
        }
        stage('upload') {
            when {
                // 当 HAS_RELEASE_OUT 为 true 时执行
                expression { env.HAS_RELEASE_OUT.toString() == "true" }
            }
            steps {
                script {
                    def remote = [:]
                    remote.name = "prod-server-248"
                    remote.host = env.PRODD_SERVER_HOST
                    remote.allowAnyHosts = true
                    withCredentials([usernamePassword(credentialsId: 'example-prod-server-248', usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) {
                        remote.user = "${USERNAME}"
                        remote.password = "${PASSWORD}"
                    }

                    def latestVersion = env.RELEASE_VERSION
                    def appName = env.APP_NAME
                    if (isZipWgtCommit()) {
                        def appid = getAppid()
                        def wgtName = "${env.APP_NAME}_${latestVersion}.wgt"
                        def zipResult = zipWgt(wgtName,appid)
                        echo "📦 Wgt path: ${zipResult} ."
                        sshPut remote: remote, from: "${zipResult}", into: "/home/static/apk/${appName}/"
                        def latestUrl = "https://static.example.com/apk/$appName/$wgtName"
                        env.LATEST_URL = latestUrl
                    }else{
                        sshPut remote: remote, from: './android/app/build/outputs/apk/release/app-release.apk', into: "/home/static/apk/${appName}/${appName}_app_v${latestVersion}.apk"
                        def latestUrl = "https://static.example.com/apk/${appName}/${appName}_app_v${latestVersion}.apk"
                        env.LATEST_URL = latestUrl
                    }

                    echo "🚀 Upload successful."
                 
                }
            }
        }
        stage('config') {
            when {
                // 当 LATEST_URL 不为空字符串时执行
                expression { env.LATEST_URL != "" && env.HAS_RELEASE_OUT.toString() == "true"}
            }
            steps {
                script {
                    echo "ℹ️ Configing..."
                    def paramsJson = buildReleaseJson()
                    def url = "${env.RELEASE_UPDATE_URL}"
                    def token = loginForToken()
                    echo "ℹ️ Config params: $paramsJson"
                    echo "ℹ️ Config url: $url"
                    echo "ℹ️ Config token: $token"
                    
                    def response = httpRequest(
                        contentType: 'APPLICATION_JSON',
                        customHeaders: [
                            [name:"Content-Type", value:"application/json"],
                            [name:"Authorization",value:"Bearer $token"]
                        ],
                        httpMode: 'POST',
                        requestBody: paramsJson,
                        url: url
                    )
                    echo "ℹ️ Config done response: $response ."
                }
            }
        }
        stage('notify') {
            when {
                // 当 LATEST_URL 不为空字符串时执行
                expression { env.LATEST_URL != "" && env.HAS_RELEASE_OUT.toString() == "true" }
            }
            steps {
                script {
                    def appName = "$env.APP_NAME $env.RELEASE_VERSION"    
                    def latestUrl = "$env.LATEST_URL"    
                    def gitCommand = "git log -1 --pretty=%B"
                    def commitMessage = sh(script: gitCommand, returnStdout: true).trim()
                    
                    def message = "🚀 $appName\\n $commitMessage\\n发布成功\\n下载地址: $latestUrl"

                    def mentionUsers = "${env.MENTION_USERS}"
                    def wechatMessageCommand = "sh /home/shell/wechat-notify.sh xxx开发者通知群 text '$message' '$mentionUsers'"

                    def result = sh(script: wechatMessageCommand, returnStdout: true).trim()
                     
                    echo "🚀 Notify done result: $result ."
                }
            }
        }
    }
}

// 获取上一个版本中 manifest.json 的 versionCode
def getPreviousVersion() {
    // 使用 Git 命令获取上一个提交的版本号
    def gitCommand = "git show HEAD^:manifest.json"
    def manifestJsonContent = sh(script: gitCommand, returnStdout: true).trim()

    // 解析 manifest.json 文件内容并获取 versionCode
    def manifestJson = readJSON text: manifestJsonContent
    def previousVersionCode = manifestJson.versionCode

    return previousVersionCode.toInteger()
}


// 获取当前版本号的函数
def getCurrentVersion() {
    // 从 manifest.json 文件中读取 versionName 字段
    def manifestJson = readJSON file: 'manifest.json'
    // 转换为 number
    return manifestJson.versionCode.toInteger()
}
 
def isVersionGreaterThan(currentVersion,previousVerion) {
    return currentVersion > previousVerion
}

//  提交信息中含有 [release] 字样
def isReleaseCommit() {
    def gitCommand = "git log -1 --pretty=%B"
    def commitMessage = sh(script: gitCommand, returnStdout: true).trim()
    return commitMessage.contains("[release]")
}

def isZipWgtCommit() {
    def gitCommand = "git log -1 --pretty=%B"
    def commitMessage = sh(script: gitCommand, returnStdout: true).trim()
    return commitMessage.contains("[wgt]")
}

// 从 manifest.json 文件中读取 appid 字段
def getAppid() {
    def manifestJson = readJSON file: 'manifest.json'
    return manifestJson.appid
}

// 构建更新配置文件
def buildReleaseJson() {
    def manifestJson = readJSON file: 'manifest.json'
    def latestUrl = "${env.LATEST_URL}"    
    def postJson = [
        "diff": manifestJson.uapp.diff,
        "downloadUrl": latestUrl,
        "forceUpdate": manifestJson.uapp.forceUpdate,
        "type": manifestJson.uapp.type,
        "versionCode": manifestJson.versionCode,
        "versionInfo": manifestJson.description,
        "versionName": manifestJson.versionName
    ]

    return groovy.json.JsonOutput.toJson(postJson)
}


// 打包成 zip 压缩包并将后缀改成 wgt
def zipWgt(wgtName,appid) {
    def zipCommand = "cd ./unpackage/resources/$appid/www/ && zip -r -q -o $wgtName . && cd ../../../../"
    def zipResult = sh(script: zipCommand, returnStdout: true).trim()

    return "./unpackage/resources/${appid}/www/${wgtName}"
}


def loginForToken(){
    def url = "https://sso.example.com/sso/user/token"
    def response = httpRequest(
            httpMode: 'POST',
            contentType: 'APPLICATION_FORM',
            requestBody: "username=${env.RELEASE_USERNAME}&password=${env.RELEASE_PASSWORD}&t=MD5",
            url: url,
            customHeaders:  [
                [name:"Content-Type",value:"application/x-www-form-urlencoded"],
                [name:"Authorization",value:"Basic xxx=="],
            ]
        )
 
    def json = new JsonSlurper().parseText(response.content)
    echo "ℹ️ Login response: $json ."
    def token = json.data.access_token    

    return token    
}
 

@zencodex
Copy link
Member

👍 好东西

@SunSeekerX
Copy link

Good jop!

@zencodex zencodex pinned this issue Dec 21, 2023
@813wangyanfei
Copy link

Is very very nice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants