Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change default PR build strategy from merge to head #636

Merged
merged 2 commits into from
Jan 20, 2023

Conversation

jglick
Copy link
Member

@jglick jglick commented Nov 16, 2022

When multibranch was first written, using PR merge build strategy seemed like a neat way to ensure that trunk was never broken. But this strategy comes with downsides:

  • It can be expensive: as the number of open PRs grow, the time spent testing them can grow quadratically rather than linearly: every time one is merged, all the remaining ones are rebuilt.
  • It violates the principle of least surprise: gh pr checkout 123 && make can produce different results than CI.
  • This plugin as well as github-checks submit a commit status or check but then need to account for the fact that the built commit might be an ephemeral merge commit and the submission actually needs to use the first parent—though it might not, even in merge strategy, if the PR head is already up to date.
    • You can then have a PR which is initially green but then goes red without being touched, or vice-versa; this is in some sense the point of the strategy to begin with, but GitHub retains no historical record of why a status/check was overwritten for a given PR branch commit. (You can create a permalink to a particular check run, even if outdated—but after it is superseded for that commit, you cannot readily look it up if you did not remember to save the permalink before.) The same issue of course applies to using Replay (Jenkins) or Re-run (Checks tab) but at least that scenario involves a deliberate gesture.

In practice, it is not very common that two pull requests are filed which individually pass CI, fail CI in combination, and yet have no textual merge conflicts (edits within ~3 lines of one another). It can certainly happen (jenkinsci/script-security-plugin#468 is an example) but not very often, and it is even less common that the failure is so weird that is difficult to fix trunk retroactively.

Furthermore, since this feature was conceived, GitHub itself has evolved to include branch protections such as the rule that a PR must be up to date before merging (which Dependabot will automatically honor by rebasing); as well as the introduction of a merge queue feature that supersedes this Jenkins trick.

This patch simply changes the default for multibranch projects or organization folders newly created via the GUI, to the simpler and more comprehensible head mode: build whatever was last pushed to the PR branch. Example result in config.xml:

<traits>
  <org.jenkinsci.plugins.github__branch__source.BranchDiscoveryTrait>
    <strategyId>1</strategyId>
  </org.jenkinsci.plugins.github__branch__source.BranchDiscoveryTrait>
  <org.jenkinsci.plugins.github__branch__source.OriginPullRequestDiscoveryTrait>
    <strategyId>2</strategyId>
  </org.jenkinsci.plugins.github__branch__source.OriginPullRequestDiscoveryTrait>
  <org.jenkinsci.plugins.github__branch__source.ForkPullRequestDiscoveryTrait>
    <strategyId>2</strategyId>
    <trust class="org.jenkinsci.plugins.github_branch_source.ForkPullRequestDiscoveryTrait$TrustPermission"/>
  </org.jenkinsci.plugins.github__branch__source.ForkPullRequestDiscoveryTrait>
</traits>

For what I suppose are historical reasons, strategyId is an int rather than a more legible enum:

/** None strategy. */
public static final int NONE = 0;
/** Merging the pull request with the current target branch revision. */
public static final int MERGE = 1;
/** The current pull request revision. */
public static final int HEAD = 2;
/**
* Both the current pull request revision and the pull request merged with the current target
* branch revision.
*/
public static final int HEAD_AND_MERGE = 3;

@jglick jglick requested a review from a team November 16, 2022 13:08
@car-roll
Copy link
Contributor

LGTM. Does it change the behavior of existing projects? I just see it being called for newInstance, but I know this is all nested heavily with other repos.

@jglick
Copy link
Member Author

jglick commented Jan 19, 2023

Does it change the behavior of existing projects?

Should not; these are just the defaults for new projects.

Copy link
Contributor

@raul-arabaolaza raul-arabaolaza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have suffered the issues @jglick mentions and I totally agree with the arguments

@car-roll car-roll enabled auto-merge (squash) January 20, 2023 15:58
@car-roll car-roll merged commit 00cc818 into jenkinsci:master Jan 20, 2023
@jglick jglick deleted the HEAD-not-MERGE branch January 20, 2023 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants