Set Squash&Merge / Merge commit restrictions in Branch Protection Rules #201976
Replies: 4 comments
|
💬 Your Product Feedback Has Been Submitted 🎉 Thank you for taking the time to share your insights with us! Your feedback is invaluable as we build a better GitHub experience for all our users. Here's what you can expect moving forward ⏩
Where to look to see what's shipping 👀
What you can do in the meantime 💻
As a member of the GitHub community, your participation is essential. While we can't promise that every suggestion will be implemented, we want to emphasize that your feedback is instrumental in guiding our decisions and priorities. Thank you once again for your contribution to making GitHub even better! We're grateful for your ongoing support and collaboration in shaping the future of our platform. ⭐ |
|
This is mostly possible now with rulesets, although not as an old-style Branch Protection override. The important distinction is:
So I would keep the needed merge methods enabled globally, then add separate branch rulesets, for example:
The rule is listed under the pull request rules: “Require a merge type of merge, squash, or rebase.” The related changelog is here too: https://github.blog/changelog/2024-12-04-pull-request-merge-method-rule-public-preview/ One caveat for your exact For that part, I would combine rulesets with one required status check. A small workflow can inspect name: merge-policy
on:
pull_request:
types: [opened, synchronize, reopened, edited, ready_for_review]
jobs:
merge-policy:
runs-on: ubuntu-latest
steps:
- name: Validate source/target branch policy
run: |
base='${{ github.base_ref }}'
head='${{ github.head_ref }}'
if [[ "$base" == "main" && "$head" != release/* ]]; then
echo "Only release/* branches should merge into main."
exit 1
fi
if [[ "$base" == release/* && "$head" != feature/* ]]; then
echo "Only feature/* branches should merge into release/* through this path."
exit 1
fiThen require that status check in the ruleset for That still cannot read the user’s final button choice before merge in every case, so for the actual merge-method enforcement I would use the native ruleset merge-method rule wherever the policy is target-branch based. For source+target routing, use the required check to stop the wrong branch-flow before people get to the merge button. |
|
Agreed, especially with
Maybe I'm missing something, but I haven't seen any way to set a restriction based on the source branch. Sometimes hotfixes get merged directly into |
|
Yes, I think that is exactly the remaining gap. The native ruleset merge-method rule is useful when the policy is based on the target branch: But it does not currently express a full source+target matrix like: For that kind of policy, the closest enforceable workaround I know is:
A required check can prevent the worst mistakes, for example blocking name: branch-flow-policy
on:
pull_request:
types: [opened, edited, synchronize, reopened, labeled, unlabeled]
jobs:
branch-flow-policy:
runs-on: ubuntu-latest
steps:
- name: Validate branch flow
run: |
base='${{ github.base_ref }}'
head='${{ github.head_ref }}'
labels='${{ join(github.event.pull_request.labels.*.name, ",") }}'
if [[ "$base" == "development-branch" && "$head" == "main" ]]; then
if [[ ",$labels," != *",backport,"* && ",$labels," != *",sync,"* ]]; then
echo "main -> development-branch PRs must be labeled backport or sync and merged with a merge commit."
exit 1
fi
fiThat still is not the same as a native “source branch + target branch + merge method” rule, because it cannot inspect the final merge button before the merge happens in all UI paths. So I agree with the feature request: a source/target-aware ruleset condition would close a real governance gap for release trains, hotfixes, and backport/sync PRs. |
Uh oh!
There was an error while loading. Please reload this page.
🏷️ Discussion Type
Product Feedback
Body
Like a lot of people, we use a
feature(optional) >release>mainworkflow. We generally want all PRs merged intofeature/releaseinitially to be Squash & Merge. Later if afeatureis going into arelease, we want it to be a Merge commit (to not lose history and tracking). Likewise forreleaseintomain, these should always be a Merge commit to not lose history and tracking.It would be great if in the Branch Protection rules that we could override the system wide Settings for these merge types so the github UI would only allow the the ones we want based on the target. Even more powerful would be to the ability to specify these in not just a "into" sense but also a "from"/"to" for the feature > release use case. Right now we have informal rules for the engineers to follow but they frequently forget and merge the wrong way and we lose history and tracking.
All reactions