如何对比Git特性分支与master分支版本并实现版本不达标自动阻断构建
版本校验实现方案
一、Gradle 内置脚本实现
直接在build.gradle中新增校验任务,绑定到构建流程前置节点,本地执行构建时自动触发校验:
// 版本校验任务 task verifyVersionHigherThanMaster() { doFirst { // 强制拉取远端最新master分支到本地,无需切换分支 def fetchResult = exec { commandLine 'git', 'fetch', 'origin', '+master:master' ignoreExitValue true } if (fetchResult.exitValue != 0) { throw new GradleException("拉取master分支最新代码失败,请检查网络权限") } // 读取master分支gradle.properties中的版本号,自动剔除SNAPSHOT等后缀 def masterVersionOutput = new ByteArrayOutputStream() exec { commandLine 'git', 'show', 'master:gradle.properties' standardOutput = masterVersionOutput } def masterVer = masterVersionOutput.toString() .split('\n') .find { it.trim().startsWith('version=') } ?.replace('version=', '') ?.replaceAll('-.*', '') ?.trim() // 读取当前分支版本号,自动剔除SNAPSHOT等后缀 def currentVer = project.version.toString() .replaceAll('-.*', '') .trim() if (!masterVer || !currentVer) { throw new GradleException("版本读取失败,请检查gradle.properties中是否配置了version字段") } // 语义化版本比对逻辑,支持x.y.z三段及以上格式 def compareVersions = { String v1, String v2 -> def parts1 = v1.split('\\.').collect { it.toInteger() } def parts2 = v2.split('\\.').collect { it.toInteger() } def maxLen = Math.max(parts1.size(), parts2.size()) for (int i = 0; i < maxLen; i++) { def p1 = i < parts1.size() ? parts1[i] : 0 def p2 = i < parts2.size() ? parts2[i] : 0 if (p1 > p2) return 1 if (p1 < p2) return -1 } return 0 } def compareResult = compareVersions(currentVer, masterVer) if (compareResult <= 0) { throw new GradleException("版本校验不通过:当前分支版本${currentVer} 小于等于master分支版本${masterVer},请升级版本后再构建") } println "版本校验通过:当前版本${currentVer} > master版本${masterVer}" } } // 绑定校验任务到build流程前置,构建前自动执行 build.dependsOn verifyVersionHigherThanMaster
二、CI/CD 流水线YAML实现(以GitLab CI为例)
适合在合并请求、上线构建阶段强制校验,避免本地跳过校验的情况:
stages: - verify - build version-check: stage: verify image: openjdk:11-jdk before_script: - apt update && apt install -y git - git config --global --add safe.directory /builds/$CI_PROJECT_PATH script: # 拉取最新master分支 - git fetch origin +master:master # 提取master分支版本,剔除SNAPSHOT后缀 - MASTER_VERSION=$(git show master:gradle.properties | grep '^version=' | cut -d'=' -f2 | sed 's/-.*//' | xargs) # 提取当前分支版本,剔除SNAPSHOT后缀 - CURRENT_VERSION=$(grep '^version=' gradle.properties | cut -d'=' -f2 | sed 's/-.*//' | xargs) # 版本比对函数 - | compare_ver() { [ "$1" = "$2" ] && return 1 local IFS=. local i ver1=($1) ver2=($2) for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do ver1[i]=0; done for ((i=0; i<${#ver1[@]}; i++)); do if ((10#${ver1[i]:-0} > 10#${ver2[i]:-0})); then return 0; fi if ((10#${ver1[i]:-0} < 10#${ver2[i]:-0})); then return 1; fi done return 1 } - compare_ver $CURRENT_VERSION $MASTER_VERSION - if [ $? -ne 0 ]; then echo "版本校验失败:当前版本$CURRENT_VERSION 需大于master版本$MASTER_VERSION"; exit 1; fi - echo "版本校验通过" build-job: stage: build needs: ["version-check"] script: - ./gradlew build
GitHub Actions等其他CI平台逻辑完全一致,仅需将脚本适配对应平台的steps语法即可。
三、Git 原生工具相关说明
Git没有内置专门做版本号比对的独立工具,但核心能力可以通过Git原生命令实现:
git fetch origin +master:master:强制同步远端master分支到本地,无需切换工作分支git show <分支名>:<文件路径>:直接读取指定分支的指定文件内容,不需要检出分支
以上两个命令是所有校验逻辑的基础,无需额外安装第三方工具。
注意:所有校验逻辑默认版本号符合数字组成的语义化版本规范(如x.y.z),如果有自定义版本规则,可自行修改版本拆分比对的代码逻辑。
内容的提问来源于stack exchange,提问作者jcrshankar
相关产品推荐
相关产品推荐

