Open bestK opened 10 months ago
// 判断 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 }
👍 好东西
Good jop!
Is very very nice!