Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.8k views
in Technique[技术] by (71.8m points)

git - BitBucket does not update refspec for PR, causing Jenkins to build old commits

I am using a local BitBucket server with Git. I am trying to get started with Continous Integration so I've set up a local Jenkins instance. The goal is to have Jenkins check out pull-requests and build the project, and then report back to BitBucket with the result.

In BitBucket I am using Webhook to Jenkins for Stash which notifies my Jenkins instance each time a pull-request is created/updated.

In Jenkins i am using Stash pullrequest builder plugin to have Jenkins checkout the pullrequest, when notified from the plugin above. I have used the settings in the documentation, i.e.

Refspec: +refs/pull-requests/*:refs/remotes/origin/pr/*
Branch Specifier: origin/pr/${pullRequestId}/from

It almost works...

When i create a new pull request in BitBucket, Jenkins get nofitied, checks out the PR and report the result back to BitBucket. So far so good.

However when I update the PR (i.e. commit new code and push to BitBucket), Jenkins gets triggered but still checks out the previous commit in the PR, and not the new commit.

I've done some investegation but got stuck. From what I understand Refspec specifies that i should map refs/remotes/origin/pr/* to refs/pull-requests/* locally. However it does not seem like BitBucket updates the refs for the PR when i do a new commit to an existing PR, which causes Jenkins only to find the old one.

When I run git ls-remote origin after commiting and pushing an update to an existing PR i get this:

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

However after visiting the PR-page in BitBucket, the refs seems to be updated and i get the following result:

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

And if i manually trigger Jenkins after this it build the latest commit.

So my problem is that BitBucket does not seem to upfate the refspec until I visit the acutal PR-page in BitBucket. How can i fix this?

Googling the problem I ended up here where it seems like the behaviour is by design...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Full disclosure: I work for Atlassian's Premier Support team.

First of all, this isn't a bug - it's worth noting that pull request refs (under refs/pull-requests/*) are an implementation detail of Bitbucket Server. They are not intended to be used for CI, or generally relied upon for development. This comment by one of our developers lists some of the reasons why it might not be a good idea to build these refs in CI.

To give you a more technical background, these refs are only created when the pull requests are viewed - they're not eagerly created. Further, the refs under /refs/pull-requests/* may be updated at any time - any change to the source or target branch will result in the pull request being rescoped, but this rescoping event is not guaranteed to be instantaneous and may be enqueued alongside other system events. This is one of the main reasons why we don't recommend building off them. There are other good reasons not to build off these refs - considering the following scenario:

  • Sarah at Apple opens PR #123 in ios-core, to merge feature/hologram-ui-support into develop (I know, I'm a dreamer)
  • refs/pull-requests/123 is created, and a CI build runs for the feature/hologram-ui-support PR
  • Meanwhile, Ahmed merges bug/weird-apfs-edge-case into develop. This causes refs/pull-requests/123 to be rescoped because the target branch has changed, and another CI build runs for the feature/hologram-ui-support PR
  • Jane merges feature/siri-asimov-laws-of-robotics-support into develop. refs/pull-requests/123 is rescoped again, and another CI build runs for the feature/hologram-ui-support PR

You can see what I mean - because those refs get rescoped on changes to the target as well as the source branch, it results in a lot more CI builds than you might be expecting. This is likely to be very taxing for your CI server, as effectively every merged PR will trigger a build of every open PR.

Generally speaking I'd recommend one of two approaches:

  1. Build the merge in your CI build:
    • Trigger builds on changes to the source branch, and have your build plan do something like git checkout target; git merge source as a build step. Most CI systems should have native support for this kind of workflow.
  2. If you must build off refs/pull-requests/, do so only on refs/pull-requests/<id>/merge-clean. There are other merge types here that are inherently failure cases: merge-conflicted and merge-base, so there's no point even trying to build those.

Cheers,

Dave


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...