GitLab流水线中Maven发布任务失败后如何重置至干净状态?
Maven发布CI/CD流水线重试时的回滚问题
我在GitLab CI/CD中搭建Maven发布流程,发布完成后需要推送带版本标签的Docker镜像,随后部署到内部云和Artifactory。目前遇到以下问题:当Maven发布任务因变量缺失等错误失败时,mvn release:prepare已经创建了标签并提交了pom文件变更,但mvn release:perform环节因镜像推送失败报错。修复变量问题后重试任务,会因之前未推送的本地提交出现「Updates were rejected because the tip of your current branch is behind」错误。
我需要确保Maven发布任务出错后重试时,能重置到干净状态,回滚之前所有提交与变更,但之前尝试回滚操作未成功。
提供的配置文件
gitlab-ci.yml
stages: - build - test - release - push - deploy - rollback cache: key: $CI_JOB_NAME paths: - /.m2/repository gemnasium-maven-dependency_scanning: stage: test variables: MAVEN_CLI_OPTS: "-DskipTests --batch-mode" DS_MAX_DEPTH: -1 .setup-mvn: before_script: - 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )' - eval $(ssh-agent -s) - chmod 400 "$SSH_PRIVATE_KEY" - ssh-add "$SSH_PRIVATE_KEY" - mkdir -p ~/.ssh - chmod 700 ~/.ssh - git config --global user.email "gitlab@default.com" - git config --global user.name "🤖 GitLab CI/CD" - ssh-keyscan -p 2222 code.gitlab.com >> ~/.ssh/known_hosts - chmod 644 ~/.ssh/known_hosts - mkdir -p ~/.m2 - | cat <<EOF > ~/.m2/settings.xml <settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" .... EOF build: image: docker-local.artifactory.com/maven:3.9.6-eclipse-temurin-21-jammy variables: KUBERNETES_CPU_REQUEST: "3" KUBERNETES_CPU_LIMIT: "5" KUBERNETES_MEMORY_REQUEST: "4Gi" KUBERNETES_MEMORY_LIMIT: "7Gi" stage: build extends: .setup-mvn script: - mvn clean package artifacts: paths: - server/target/*.jar maven_release: stage: release image: docker-local.artifactory.com/maven:3.9.6-eclipse-temurin-21-jammy-openssh extends: .setup-mvn when: manual script: - git checkout -B "$CI_COMMIT_REF_NAME" - mvn release:clean release:prepare --batch-mode -DscmCommentPrefix="[skip ci]" - mvn release:perform -Dgoals=install push_image: stage: push dependencies: - maven_release image: name: docker-local.artifactory.com/executor:v1.14.0-debug entrypoint: [""] when: manual script: - VERSION=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout) - mkdir -p /kaniko/.docker - echo $DOCKER_AUTH_CONFIG > /kaniko/.docker/config.json - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile ./Dockerfile --destination docker-local.artifactory.com/$CI_PROJECT_NAME:$VERSION - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile ./Dockerfile --destination docker-local.artifactory.com/$CI_PROJECT_NAME:latest - echo "Docker image pushed."
pom.xml(仅maven-release-plugin部分)
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-release-plugin</artifactId> <version>3.0.1</version> <configuration> <pushChanges>false</pushChanges> <projectVersionPolicyId>SemVerVersionPolicy</projectVersionPolicyId> <tagNameFormat>v-@{project.version}</tagNameFormat> </configuration> </plugin> </plugins> </build>
解决方案
1. 在maven_release任务开头添加本地仓库重置逻辑
由于你配置了pushChanges=false,release:prepare生成的提交和标签仅存在于本地仓库。重试时先将本地仓库强制重置到远程分支的最新状态,清除所有本地未推送的变更:
修改maven_release的script部分:
maven_release: # 其他配置保持不变 script: # 拉取远程分支最新代码,重置本地分支到远程状态,丢弃所有本地变更 - git fetch origin "$CI_COMMIT_REF_NAME" - git reset --hard origin/"$CI_COMMIT_REF_NAME" # 删除本地所有v-前缀的release标签(匹配你的tagNameFormat) - git tag -l "v-*" | xargs git tag -d || true # 原有的发布命令 - mvn release:clean release:prepare --batch-mode -DscmCommentPrefix="[skip ci]" - mvn release:perform -Dgoals=install
2. 新增失败自动回滚逻辑(可选)
在任务的after_script中添加失败触发的回滚操作,确保任务失败后自动清理本地状态:
maven_release: # 其他配置保持不变 after_script: - | if [ "$CI_JOB_STATUS" == "failed" ]; then # 回滚Maven release的pom变更 mvn release:rollback --batch-mode # 再次重置本地仓库到远程最新状态 git fetch origin "$CI_COMMIT_REF_NAME" git reset --hard origin/"$CI_COMMIT_REF_NAME" # 删除本地残留标签 git tag -l "v-*" | xargs git tag -d || true fi
3. 优化Maven release插件配置(可选)
添加以下配置,让插件在失败时自动清理临时文件:
<configuration> <pushChanges>false</pushChanges> <projectVersionPolicyId>SemVerVersionPolicy</projectVersionPolicyId> <tagNameFormat>v-@{project.version}</tagNameFormat> <!-- 自动处理子模块版本(如果有子模块) --> <autoVersionSubmodules>true</autoVersionSubmodules> <!-- 禁用发布备份,避免残留文件 --> <releaseBackupPolicy>none</releaseBackupPolicy> </configuration>
关键说明
git reset --hard origin/$CI_COMMIT_REF_NAME:强制覆盖本地分支,丢弃所有未推送的提交(包括release:prepare生成的pom版本变更)。git tag -l "v-*" | xargs git tag -d:删除本地所有未推送的release标签,避免重试时标签冲突。mvn release:rollback:恢复pom文件到发布前的状态,配合git重置可实现彻底清理。
内容的提问来源于stack exchange,提问作者user23862847
相关产品推荐
相关产品推荐

