You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 00:14:53