1

在我的工作场所,我们使用由多个开发人员共享的月度发布分支。

Gradle 版本是 2.14.1

我们使用Jenkins手动触发代码构建和发布(任务)(有效运行——gradle clean compileJava release)

整个过程大约需要 30-40 分钟,基本上是编译、生成工件、运行 Junit 测试并将工件上传到 Artifactory。

最终到了标记和推送版本号的步骤: preTagCommit,它尝试更新 gradle.properties 并将版本号提升到它并提交和推送。

此时,如果最近 30-40 分钟(由于手动触发构建)分支上没有提交,则发布成功。

在整个过程之间甚至有一个提交的那一刻它失败并出现错误:任务':preTagCommit'的执行失败。

*
error: failed to push some refs to 'xxx.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
*

我尝试了几种技巧并搜索了文档,但还没有找到任何合适的解决方案。

这是我的发布步骤的样子:

***
    release {
        project.setProperty("gradle.release.useAutomaticVersion", "true");
        newVersionCommitMessage = "Re-snapshoted project to version "
        preTagCommitMessage = "Preparing version for release "
        tagCommitMessage = "Tagging Release "
        tagPrefix = "calypso"
        requireBranch = ""
        // Sometimes the plugin trips over its own feet with modifying the gradle.properties
        // then complaining it has changed.
        failOnCommitNeeded = false
        pushToCurrentBranch = true
    }
***

抱歉,如果以前有人问过这个问题,我发现的所有解决方案都是 git 的一般方法,而不是来自使用 Gradle-Release-Plugin 和 git 的人。

任何回应将不胜感激。

4

2 回答 2

1

我相信插件的GitHub 页面中提到了您要查找的标志:

例如。要忽略上游更改,请将“failOnUpdateNeeded”更改为 false:

release {
  failOnUpdateNeeded = false
}

编辑

似乎上述标志由于某种原因不起作用。然而,还有另一种方法可以实现这一点,那就是gitrelease扩展选项中添加强制推送选项(多嘴多说)。

release {
  git {
    pushOptions = ['--force']
  }
}

这基本上会强制覆盖分支(参见下面的问题分析),除非托管存储库的服务器被调整为拒绝这种强制推送。在这种情况下,您确实无法通过此处提供帮助。


问题分析

正如我在下面的最后一条评论中所说,失败的部分是扩展运行preTagCommit任务,然后尝试将此提交推送到上游分支(master例如)。你可以在这里看到这个推送命令。

当然,如果其他人已经将提交推送到该分支,这将失败。

现在解决这个问题的一种更简单的方法是,如果插件作者让我们能够说

不要将 preTag 提交推送到上游

或者

将 preTagCommits 推送到名为 foo 的分支

不幸的是,他们没有给我们这个选项(至少从我到目前为止收集的内容来看)。所以我想出了一些hacky解决方案来规避这个问题。

解决方案/黑客

指定 pushToBranchPrefix创建标记分支

这是另一个可以传递给对象的选项git,它会导致它所做的所有推送都执行到具有给定前缀的特定分支而不是当前分支:

例如:

afterReleaseBuild {
  doFirst {
    project.exec {
        executable = 'git'
        args 'checkout', '-b', 'v1.x.x@master'
    }
  }
}

替换v1.x.x为与当前版本的标签匹配的内容。

这样做是每当插件尝试推送/提交时,它会改为推送/提交到我们创建的这个分支,最后也从这个分支创建标签。

我认为这可能是最好的选择

禁用preTagCommit任务

由于preTagCommit任务是失败的地方,我们可以禁用该任务,它将不再运行:

tasks.named('preTagCommit') {
    enabled = false
}

自己确定这是否可以接受。

动态推送行为

因为我看过源代码,所以我可以看到它推送的原因是它看到了git.pushToRemote非空。知道了这一点,我们就可以动态地控制这种行为。

tasks.named('preTagCommit') {
  def pushToRemote = null
  doFirst {
    project.extensions.configure(net.researchgate.release.ReleaseExtension) {
      pushToRemote = it.git.pushToRemote
      it.git.pushToRemote = null
    }
  }

  doLast {
    project.extensions.configure(net.researchgate.release.ReleaseExtension) {
      it.git.pushToRemote = pushToRemote
    }
  }
}

这样,在 中preTagCommit,它不会推动任何事情,但会成功完成其他所有事情。

于 2020-05-06T03:43:36.797 回答
0

对于我的情况,最简单的方法是在 build.gradle 中简单地修改我的发布插件组件:

***
release {
....
 pushToRemote = ''
....
}
***

这确保了发布插件不会推送!

在控制来自 gradle 版本之后,我跟进了:

Git 拉取原点

git push --tags origin

这很好地同步了我的提交,并且还遵循了先拉后推规则!

虽然这是一个 hacky 解决方案,但 @Clijsters 建议我使用特殊版本分支来解决这个问题。

于 2020-05-08T05:30:47.827 回答