Jenkins构建Git分支及制品命名部署问题求助
解决方案:Jenkins构建多Feature分支并生成带JIRA编号的Nexus制品
针对你遇到的分支筛选、JIRA编号提取以及POM与jgitflow冲突的问题,我提供两种可落地的解决方案,优先推荐基于Maven Profile的方案,更优雅且无副作用:
一、核心需求拆解
先明确要解决的三个核心问题:
- Jenkins仅构建有最近PUSH事件的feature分支
- 从
origin/feature/JIRA-1234这类分支名中提取纯JIRA编号(如JIRA-1234) - 生成
APP-0.0.1-JIRA-1234-SNAPSHOT格式的制品,同时不影响mvn jgitflow:release-start/finish命令
二、方案1:基于Maven Profile的优雅实现(推荐)
这个方案通过在POM中添加专属Jenkins构建的Profile,仅在构建feature分支时激活,既不修改默认POM版本,也不会和jgitflow命令冲突。
1. 修改POM.xml添加Profile
在你的pom.xml中新增一个Profile,只有当传入jira.id参数时才激活,自动修改制品名称和部署版本:
<profiles> <profile> <id>jenkins-feature-build</id> <!-- 只有传入jira.id参数时才激活该Profile --> <activation> <property> <name>jira.id</name> </property> </activation> <build> <plugins> <!-- 配置Jar插件,修改最终制品名称 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.2.0</version> <configuration> <finalName>APP-0.0.1-${jira.id}-SNAPSHOT</finalName> </configuration> </plugin> <!-- 如果是Web项目,添加maven-war-plugin配置 --> <!-- <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>3.3.2</version> <configuration> <warName>APP-0.0.1-${jira.id}-SNAPSHOT</warName> </configuration> </plugin> --> <!-- 配置Deploy插件,确保上传到Nexus的版本正确 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-deploy-plugin</artifactId> <version>3.0.0-M1</version> <configuration> <version>APP-0.0.1-${jira.id}-SNAPSHOT</version> </configuration> </plugin> </plugins> </build> </profile> </profiles>
2. Jenkins配置(Pipeline/自由风格任选)
方式A:Jenkins Pipeline(更灵活可控)
使用Pipeline脚本自动筛选feature分支、提取JIRA编号并构建:
pipeline { agent any triggers { // 每15分钟轮询一次SCM,检测分支更新 pollSCM('H/15 * * * *') } stages { stage('Checkout & Extract JIRA ID') { steps { // 拉取当前触发构建的feature分支 git branch: env.BRANCH_NAME, url: '你的Git仓库URL' script { // 用正则从分支名中提取JIRA编号(支持origin/feature/JIRA-xxx格式) def jiraPattern = ~/(JIRA-\d+)/ def jiraMatch = env.BRANCH_NAME =~ jiraPattern if (jiraMatch) { env.JIRA_ID = jiraMatch[0][0] echo "提取到JIRA编号:${env.JIRA_ID}" } else { error "分支名${env.BRANCH_NAME}不符合规范,未找到JIRA编号" } } } } stage('Build & Deploy to Nexus') { steps { // 激活jenkins-feature-build Profile,传入JIRA编号参数 sh "mvn clean deploy -DskipTests -Pjenkins-feature-build -Djira.id=${env.JIRA_ID}" } } } }
- 分支筛选:在Git配置的
Branch Specifier中填写*/feature/*,Jenkins会自动只监控feature分支,且仅在分支有新提交时触发构建。
方式B:自由风格项目
- 源码管理:选择Git,填写仓库URL,
Branch Specifier填*/feature/*,勾选Poll SCM,设置cron表达式(如H/15 * * * *)。 - 提取JIRA编号:添加
Execute shell步骤,脚本如下:# 从分支名中提取JIRA编号并写入环境变量文件 JIRA_ID=$(echo $GIT_BRANCH | grep -oE 'JIRA-[0-9]+') echo "JIRA_ID=$JIRA_ID" > $WORKSPACE/jira.properties - 注入环境变量:添加
Inject environment variables步骤,选择Properties File Path为jira.properties。 - Maven构建:添加
Maven build步骤,目标填写:clean deploy -DskipTests -Pjenkins-feature-build -Djira.id=${JIRA_ID}
三、方案2:基于versions插件的临时版本修改
如果不想修改POM,也可以用Maven的versions:set插件临时修改版本号,构建完成后再还原,避免影响jgitflow命令。
Jenkins Pipeline示例
pipeline { agent any triggers { pollSCM('H/15 * * * *') } stages { stage('Checkout & Extract JIRA ID') { steps { git branch: env.BRANCH_NAME, url: '你的Git仓库URL' script { def jiraPattern = ~/(JIRA-\d+)/ def jiraMatch = env.BRANCH_NAME =~ jiraPattern if (jiraMatch) { env.JIRA_ID = jiraMatch[0][0] } else { error "分支名不符合规范" } } } } stage('Build & Deploy') { steps { // 临时修改版本号 sh "mvn versions:set -DnewVersion=APP-0.0.1-${env.JIRA_ID}-SNAPSHOT" // 构建并上传到Nexus sh "mvn clean deploy -DskipTests" // 还原POM版本,避免影响后续Git提交 sh "mvn versions:revert" } } } }
- 注意:
versions:revert会还原POM的版本号到修改前的状态,确保本地POM不会被改动,因此jgitflow命令可以正常使用。
四、关键说明
- 分支自动筛选:Jenkins的Git插件会自动检测每个feature分支的最后提交时间,轮询时仅触发有新PUSH事件的分支构建,无需额外配置。
- JIRA编号提取:通过正则表达式可以稳定提取
JIRA-xxx格式的编号,适配origin/feature/JIRA-xxx或feature/JIRA-xxx等分支命名格式。 - 无jgitflow冲突:两种方案都不会修改POM的默认版本(方案1通过Profile激活,方案2临时修改后还原),因此
mvn jgitflow:release-start和mvn jgitflow:release-finish命令可以完全正常执行。
内容的提问来源于stack exchange,提问作者Sambit Swain




