BitBucket 不更新 PR 的 refspec,导致 Jenkins 构建旧提交

Cle*_*red 1 git continuous-integration bitbucket pull-request jenkins

我正在使用带有 Git 的本地 BitBucket 服务器。我正在尝试开始持续集成,因此我设置了一个本地 Jenkins 实例。目标是让 Jenkins 检查拉取请求并构建项目,然后向 BitBucket 报告结果。

在 BitBucket 中,我使用Webhook 与 Jenkins 进行 Stash,每次创建/更新拉取请求时它都会通知我的 Jenkins 实例。

在 Jenkins 中,当从上面的插件通知时,我使用Stash pullrequest 构建器插件让 Jenkins 签出 pullrequest。我已经使用了文档中的设置,即

Refspec: +refs/pull-requests/*:refs/remotes/origin/pr/*
Branch Specifier: origin/pr/${pullRequestId}/from
Run Code Online (Sandbox Code Playgroud)

差不多就可以用了...

当我在 BitBucket 中创建新的拉取请求时,Jenkins 会收到通知,检查 PR 并将结果报告回 BitBucket。到目前为止,一切都很好。

但是,当我更新 PR(即提交新代码并推送到 BitBucket)时,Jenkins 会被触发,但仍然检查 PR 中的先前提交,而不是新提交。

我做了一些调查但陷入困境。据我了解,Refspec指定我应该映射refs/remotes/origin/pr/*refs/pull-requests/*本地。然而,当我对现有 PR 进行新提交时,BitBucket 似乎并未更新 PR 的引用,这导致 Jenkins 只能找到旧的 PR。

当我git ls-remote origin在提交并将更新推送到现有 PR 后运行时,我得到以下信息:

edf245 (new commit)...             refs/heads/feature/Name-Of-My-Branch-That-I-Created-Pull-Request-From-pr
af774f (previous commit in PR)...  refs/pull-requests/69/from
7fa82b (master)...                 refs/pull-requests/69/merge
Run Code Online (Sandbox Code Playgroud)

然而,在访问 BitBucket 中的 PR 页面后,参考似乎已更新,我得到以下结果:

edf245 (new commit)...             refs/heads/feature/Name-Of-My-Branch-That-I-Created-Pull-Request-From-pr
edf245 (new commit)...             refs/pull-requests/69/from
7fa82b (master)...                 refs/pull-requests/69/merge
Run Code Online (Sandbox Code Playgroud)

如果我在此之后手动触发 Jenkins,它会构建最新的提交。

所以我的问题是,在我访问 BitBucket 中的实际 PR 页面之前,BitBucket 似乎不会更新 refspec。我怎样才能解决这个问题?

谷歌搜索我最终在这里的问题,似乎该行为是设计使然......

dav*_*ing 5

全面披露:我在 Atlassian 的高级支持团队工作。

首先,这不是一个错误 - 值得注意的是,拉取请求引用(在 下refs/pull-requests/*)是 Bitbucket Server 的实现细节。它们不适合用于 CI,或者通常依赖于开发。我们的一位开发人员的评论列出了在 CI 中构建这些引用可能不是一个好主意的一些原因。

为了给您提供更多技术背景,这些引用仅在查看拉取请求时创建 - 它们并不是急切创建的。此外,下面的引用/refs/pull-requests/*可能会随时更新 - 对源或目标分支的任何更改都将导致拉取请求被重新限定范围,但此重新限定范围事件不能保证是瞬时的,并且可能与其他系统事件一起排队。这是我们不建议构建它们的主要原因之一。考虑到以下情况,还有其他充分的理由不构建这些参考文献:

  • Apple 的 Sarah 在ios-core中打开 PR #123,将功能/hologram-ui-support合并到开发中(我知道,我是一个梦想家)
  • refs/pull-requests/123创建完毕,并为feature/hologram-ui-support PR运行 CI 构建
  • 与此同时,Ahmed 将bug/weird-apfs-edge-case合并到开发中。这会导致refs/pull-requests/123重新调整范围,因为目标分支已更改,并且另一个 CI 构建针对feature/hologram-ui-support PR运行
  • Jane 将feature/siri-asimov-laws-of-robotics-support合并到开发中。再次重新调整范围,并为feature/hologram-ui-support PRrefs/pull-requests/123运行另一个 CI 构建

您可以明白我的意思 - 因为这些引用会根据目标和源分支的更改重新调整范围,因此会导致比您预期的更多的 CI 构建。这对于 CI 服务器来说可能会非常繁重,因为实际上每个合并的 PR 都会触发每个开放 PR 的构建。

一般来说,我推荐以下两种方法之一:

  1. 在 CI 构建中 构建合并:
    • 触发器基于对源分支的更改进行构建,并让您的构建计划执行类似于git checkout target; git merge source构建步骤的操作。大多数 CI 系统应该对这种工作流程具有本机支持。
  2. 如果您必须构建refs/pull-requests/,请仅在构建refs/pull-requests/<id>/merge-clean。这里还有其他合并类型本质上是失败案例:merge-conflictedmerge-base,因此尝试构建这些合并类型是没有意义的。

干杯,

戴夫