nishio-dens / bitbucket-pullrequest-builder-plugin

Bitbucket Pull Request Builder Plugin for Jenkins
Other
125 stars 145 forks source link

Not building merged PR when source branch commit has been built, bug or ??? #222

Open hartzell opened 4 years ago

hartzell commented 4 years ago

I have two jobs defined for a particular repo.

One uses the bitbucket plugin and is configured to build for pushes to any branch, triggered via a web hook. I nicknamed this the "push job".

The second uses the Bitbucket Pullrequest Builder plugin and is configured to merge the source branch into the target branch before testing. I've nicknamed this the "pr job".

I'd hoped that the "push" job would test the isolated commit and that the "pr" job would also run and test the merged results.

Instead, the push job runs and the pr job never bothers.

If I disable the push job and push something to the PR branch then the pr job does run.

If feels as if the pr job is deciding whether to run based on whether commit at the head of the source branch has been built, NOT whether the merge of that commit with the target branch has been built.

Is there a way to achieve the result I'm looking for?

Thanks!

selop commented 4 years ago

I encountered the same problem in our build environment.

Jenkins job A: We have a multibranch pipeline for a bitbucket (Server) project. It runs only a gradle build and unit test stage for pull requests.

Jenkins job B: I wanted to hook up another job into the pull request workflow with the Pull Request Builder Plugin. The second job is a e2e test job which runs far longer and is triggered with the plugin and returns the build status for Bitbucket.

Now the problem is, that the Pull Request Builder Plugin checks each commit with ServerApiClient over the REST API of the Bitbucket Server

@Override
public boolean hasBuildStatus(String owner, String repositoryName, String revision, String keyEx) {
        return CollectionUtils.isNotEmpty(getAllValues(buildStateV1(revision), ServerPullrequest.CommitBuildState.class));
}
private String buildStateV1(String commit) {
        return this.serverUrl + "/rest/build-status/1.0/commits/" + commit;
}

If this endpoint responds with anything the plugin assumes that only itself has changed the build status of a commit. But in my case it was the other Jenkins job.

In summary, the plugin should check the build-status for each commit and also consider that other jobs could have altered it. This can be done with the url field which is returned back by /rest/build-status/1.0/commits/.

@CodeMonk FYI

CodeMonk commented 4 years ago

I'm pretty sure this is by design. The plugin stops building once a pr is merged, because there is no open PR.

CodeMonk commented 4 years ago

Ignore that other comment, I think I understand now - please bear with me while I paraphrase.

A commit is built by ONE job, and the commit state is set for the hash. A different job, also triggers off of pull requests, then looks at the commit, sees that it's updated, and ignores it.

If that is the issue, I think the simplest fix would be to mark the commit with the particular job that started it, so that jobs do not conflict with each other.

Is that a correct representation of the issue? (Not sure if my suggested fix is possible - I haven't looked at the commit marking stuff)

hartzell commented 4 years ago

Yes, your second comment hits the nail on the head.

In my case, pushes to branches trigger a simple set of tests using just the contents of the branch.

Changes to a branch that's part of a pull request run a bigger set of tests in an environment that the result of a transient merge of the "feature" branch and its base. At the moment I need to trigger them by hand because the more generic "push" tests have already "built" that commit. I could almost get the behavior I want by preventing the "push" commits from running on PR branches but it turns out that I want their results too.

selop commented 4 years ago

For my BitbucketServer version each commit has a build-status resource. And this Pull Request Plugin uses this resource to check if the plugin has already processed this commit.

https://<URL>/rest/build-status/1.0/commits/2bcb66ef485d316ec105cdd9309307c4a9f47433

To illustrate my problem:

A multibranch pipeline which does NOT use Bitubucket Pull Request Builder detects a PR and builds it alters the build-status of a commit. If I query the REST API I get:

{
  "size": 1,
  "limit": 100,
  "isLastPage": true,
  "values": [
    {
      "state": "INPROGRESS",
      "key": "99cca0830f6c0649ad011fd99c6d9f3f",
      "name": "product-pipeline » multibranch-project » PR-843 #1",
      "url": "https://<URL>/job/product-pipeline/job/multibranch-project/job/PR-843/1/display/redirect",
      "description": "The build is in progress...",
      "dateAdded": 1593154788327
    }
  ],
  "start": 0
}

Now the second job which HAS Bitbucket Pull Request Plugin enabled queries this commit build state via REST and sees that this commit has already a build status and prints in the Jenkinslog that it already has processed this commit, which clearly it never has. In my opinion this is a bug.

The plugin should check the "key": "99cca0830f6c0649ad011fd99c6d9f3f" and make sure the build state was actually altered by the plugin.

Does this help? This might be a bold feature request, not a bug. Just wanted to give you guys more input on my view.

CodeMonk commented 4 years ago

lol - while I'm always the guy to correct bug -vs- feature request, I do believe this is a bug, and I think we're both on the same page.

Do you have the skills to attempt a fix? I haven't looked at that portion of the code before, but, I'm happy to give it a shot.

-Dave

hartzell commented 4 years ago

@CodeMonk —- I assume you’re asking @selop, not me, but it’s definitely not in my wheelhouse.

CodeMonk commented 4 years ago

Lol, I'm asking anyone! Otherwise, I'll try to get to it.

selop commented 4 years ago

I try to file a pull request until the end of this week.