When using the "Merge if necessary" submit type with Gerrit and the change-merged build trigger, if Gerrit did an automatic merge commit, the commit-ish to build will be the sha1 of the commit from the patchset prior to the merge commit resulting in the incorrect checkout of the repository content and causing an improper artifact to be built and published. Further if the merge commit merged changes that were made to the Jenkinsfile, the build will not even be using the correct pipeline code. Since either case can result in incorrect but possibly successful build results, I set the priority of this bug to Critical.
If this is a bug, change-merged events should be fetching based on the refName and checking out the newRev.
If this is not a bug in the behavior, then I believe this should be addressed in documentation as it is a common for Gerrit repos to be configured with "Merge if necessary" and following the current documentation will result in incorrect build outputs. To work around this, I have to configure multiple Jenkins jobs, one for patchset-created and one for ref-updated because I cannot figure out any way to trigger on both of those events from the same job and have the correct content checked out in this merge scenario. Also, when I build on ref-updated, there is no feedback comment to the changeset that a build was started and what its final result was.
I experimented with this a bit using a single job configured with patchset-created and change-merged triggers and pipeline scm checkout configured the way the gerrit-trigger documentation suggests here: https://plugins.jenkins.io/gerrit-trigger/#usage-with-the-git-plugin
When you let the gerrit-trigger plugin choose what to build, you get:
- For a ref-updated event, commit-ish to build is based on GERRIT_NEWREV and branch name is based on GERRIT_REFNAME
- For a patchset-created or change-merged event, commit-ish to build is based on patchset revision which is the commit-ish associated with the change GERRIT_PATCHSET_REVISION and branch name is the ref GERRIT_REFSPEC
- For a manually triggered build, the values come from the Jenkins pipeline configuration properties. The commit-ish to build will fall back to "FETCH_HEAD" which will depend on the Refspec setting of the Advanced part of that configuration and the branch will be set based on the Branch setting.
This is based on analysis of the Jenkins plugin code for the version of the plugin we currently have deployed, not documentation, see: https://github.com/jenkinsci/gerrit-trigger-plugin/blob/gerrit-trigger-2.33.0/src/main/java/com/sonyericsson/hudson/plugins/gerrit/trigger/hudsontrigger/GerritTriggerBuildChooser.java#L106
I'm fairly cetain that code is in play but not 100% as I don't follow the whole code base and Jenkins interactions.
I captured the Gerrit events during a merge from the Gerrit events-log REST API:
curl -uuser:pass "http://mygerritserver/a/plugins/events-log/events/?t1=2021-04-26"
These are the two that fired the builds for the patchset-created events:
These are the two that fired the builds for the change-merged events (note the newRev in the second event which points at our merge commit which I expected to be built but the choosing strategy is using the patchSet.revision):
Here are the related ref-updated events:
Here is the git log after the merge:
These pipelines are configured setting the option `skipDefaultCheckout` to `true` and use the `checkout scm` step in a later stage. You can see in the Jenkins console for each of the triggered jobs, what was actually checked out:
For the setup commit 788bfd7:
- checkout the pipeline
- then the checkout in the later stage
And for the second commit 7552e71:
- checkout the pipeline (note the fetch here against the refspec doesn't contain our merge commit but the event does have refName of refs/heads/master which would)
- then the checkout in the later stage