Skip to content

Commit 8f26730

Browse files
authored
Merge pull request cli#12846 from yuvrajangadsingh/feat/squash-merge-commit-message
feat(repo): add --squash-merge-commit-message flag to gh repo edit
2 parents 19864b9 + 198487e commit 8f26730

File tree

2 files changed

+281
-21
lines changed

2 files changed

+281
-21
lines changed

pkg/cmd/repo/edit/edit.go

Lines changed: 103 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"fmt"
88
"io"
99
"net/http"
10+
"slices"
1011
"strings"
1112
"time"
1213

@@ -35,18 +36,25 @@ const (
3536
allowSquashMerge = "Allow Squash Merging"
3637
allowRebaseMerge = "Allow Rebase Merging"
3738

39+
squashMsgDefault = "default"
40+
squashMsgPRTitle = "pr-title"
41+
squashMsgPRTitleCommits = "pr-title-commits"
42+
squashMsgPRTitleDescription = "pr-title-description"
43+
3844
optionAllowForking = "Allow Forking"
3945
optionDefaultBranchName = "Default Branch Name"
4046
optionDescription = "Description"
4147
optionHomePageURL = "Home Page URL"
4248
optionIssues = "Issues"
4349
optionMergeOptions = "Merge Options"
4450
optionProjects = "Projects"
45-
optionDiscussions = "Discussions"
4651
optionTemplateRepo = "Template Repository"
4752
optionTopics = "Topics"
4853
optionVisibility = "Visibility"
4954
optionWikis = "Wikis"
55+
56+
// TODO: GitHub Enterprise Server does not support has_discussions yet
57+
// optionDiscussions = "Discussions"
5058
)
5159

5260
type EditOptions struct {
@@ -69,24 +77,27 @@ type EditRepositoryInput struct {
6977
enableAdvancedSecurity *bool
7078
enableSecretScanning *bool
7179
enableSecretScanningPushProtection *bool
72-
73-
AllowForking *bool `json:"allow_forking,omitempty"`
74-
AllowUpdateBranch *bool `json:"allow_update_branch,omitempty"`
75-
DefaultBranch *string `json:"default_branch,omitempty"`
76-
DeleteBranchOnMerge *bool `json:"delete_branch_on_merge,omitempty"`
77-
Description *string `json:"description,omitempty"`
78-
EnableAutoMerge *bool `json:"allow_auto_merge,omitempty"`
79-
EnableIssues *bool `json:"has_issues,omitempty"`
80-
EnableMergeCommit *bool `json:"allow_merge_commit,omitempty"`
81-
EnableProjects *bool `json:"has_projects,omitempty"`
82-
EnableDiscussions *bool `json:"has_discussions,omitempty"`
83-
EnableRebaseMerge *bool `json:"allow_rebase_merge,omitempty"`
84-
EnableSquashMerge *bool `json:"allow_squash_merge,omitempty"`
85-
EnableWiki *bool `json:"has_wiki,omitempty"`
86-
Homepage *string `json:"homepage,omitempty"`
87-
IsTemplate *bool `json:"is_template,omitempty"`
88-
SecurityAndAnalysis *SecurityAndAnalysisInput `json:"security_and_analysis,omitempty"`
89-
Visibility *string `json:"visibility,omitempty"`
80+
squashMergeCommitMsg *string
81+
82+
AllowForking *bool `json:"allow_forking,omitempty"`
83+
AllowUpdateBranch *bool `json:"allow_update_branch,omitempty"`
84+
DefaultBranch *string `json:"default_branch,omitempty"`
85+
DeleteBranchOnMerge *bool `json:"delete_branch_on_merge,omitempty"`
86+
Description *string `json:"description,omitempty"`
87+
EnableAutoMerge *bool `json:"allow_auto_merge,omitempty"`
88+
EnableIssues *bool `json:"has_issues,omitempty"`
89+
EnableMergeCommit *bool `json:"allow_merge_commit,omitempty"`
90+
EnableProjects *bool `json:"has_projects,omitempty"`
91+
EnableDiscussions *bool `json:"has_discussions,omitempty"`
92+
EnableRebaseMerge *bool `json:"allow_rebase_merge,omitempty"`
93+
EnableSquashMerge *bool `json:"allow_squash_merge,omitempty"`
94+
EnableWiki *bool `json:"has_wiki,omitempty"`
95+
Homepage *string `json:"homepage,omitempty"`
96+
IsTemplate *bool `json:"is_template,omitempty"`
97+
SecurityAndAnalysis *SecurityAndAnalysisInput `json:"security_and_analysis,omitempty"`
98+
SquashMergeCommitTitle *string `json:"squash_merge_commit_title,omitempty"`
99+
SquashMergeCommitMessage *string `json:"squash_merge_commit_message,omitempty"`
100+
Visibility *string `json:"visibility,omitempty"`
90101
}
91102

92103
func NewCmdEdit(f *cmdutil.Factory, runF func(options *EditOptions) error) *cobra.Command {
@@ -120,7 +131,15 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(options *EditOptions) error) *cobr
120131
When the %[1]s--visibility%[1]s flag is used, %[1]s--accept-visibility-change-consequences%[1]s flag is required.
121132
122133
For information on all the potential consequences, see <https://gh.io/setting-repository-visibility>.
123-
`, "`"),
134+
135+
When the %[1]s--enable-squash-merge%[1]s flag is used, %[1]s--squash-merge-commit-message%[1]s
136+
can be used to change the default squash merge commit message behavior:
137+
138+
- %[1]s%[2]s%[1]s: uses commit title and message for 1 commit, or pull request title and list of commits for 2 or more
139+
- %[1]s%[3]s%[1]s: uses pull request title
140+
- %[1]s%[4]s%[1]s: uses pull request title and list of commits
141+
- %[1]s%[5]s%[1]s: uses pull request title and description
142+
`, "`", squashMsgDefault, squashMsgPRTitle, squashMsgPRTitleCommits, squashMsgPRTitleDescription),
124143
Args: cobra.MaximumNArgs(1),
125144
Example: heredoc.Doc(`
126145
# Enable issues and wiki
@@ -162,6 +181,19 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(options *EditOptions) error) *cobr
162181
return cmdutil.FlagErrorf("use of --visibility flag requires --accept-visibility-change-consequences flag")
163182
}
164183

184+
if opts.Edits.squashMergeCommitMsg != nil {
185+
if opts.Edits.EnableSquashMerge == nil {
186+
return cmdutil.FlagErrorf("--squash-merge-commit-message requires --enable-squash-merge")
187+
}
188+
if !*opts.Edits.EnableSquashMerge {
189+
return cmdutil.FlagErrorf("--squash-merge-commit-message cannot be used when --enable-squash-merge=false")
190+
}
191+
if err := validateSquashMergeCommitMsg(*opts.Edits.squashMergeCommitMsg); err != nil {
192+
return err
193+
}
194+
transformSquashMergeOpts(&opts.Edits)
195+
}
196+
165197
if hasSecurityEdits(opts.Edits) {
166198
opts.Edits.SecurityAndAnalysis = transformSecurityAndAnalysisOpts(opts)
167199
}
@@ -192,6 +224,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(options *EditOptions) error) *cobr
192224
cmdutil.NilBoolFlag(cmd, &opts.Edits.DeleteBranchOnMerge, "delete-branch-on-merge", "", "Delete head branch when pull requests are merged")
193225
cmdutil.NilBoolFlag(cmd, &opts.Edits.AllowForking, "allow-forking", "", "Allow forking of an organization repository")
194226
cmdutil.NilBoolFlag(cmd, &opts.Edits.AllowUpdateBranch, "allow-update-branch", "", "Allow a pull request head branch that is behind its base branch to be updated")
227+
cmdutil.NilStringFlag(cmd, &opts.Edits.squashMergeCommitMsg, "squash-merge-commit-message", "", "The default value for a squash merge commit message: {default|pr-title|pr-title-commits|pr-title-description}")
195228
cmd.Flags().StringSliceVar(&opts.AddTopics, "add-topic", nil, "Add repository topic")
196229
cmd.Flags().StringSliceVar(&opts.RemoveTopics, "remove-topic", nil, "Remove repository topic")
197230
cmd.Flags().BoolVar(&opts.AcceptVisibilityChangeConsequences, "accept-visibility-change-consequences", false, "Accept the consequences of changing the repository visibility")
@@ -474,6 +507,20 @@ func interactiveRepoEdit(opts *EditOptions, r *api.Repository) error {
474507
return fmt.Errorf("you need to allow at least one merge strategy")
475508
}
476509

510+
if enableSquashMerge {
511+
squashMsgOptions := validSquashMsgValues
512+
idx, err := p.Select(
513+
"Default squash merge commit message",
514+
squashMsgDefault,
515+
squashMsgOptions)
516+
if err != nil {
517+
return err
518+
}
519+
selected := squashMsgOptions[idx]
520+
opts.Edits.squashMergeCommitMsg = &selected
521+
transformSquashMergeOpts(&opts.Edits)
522+
}
523+
477524
opts.Edits.EnableAutoMerge = &r.AutoMergeAllowed
478525
c, err := p.Confirm("Enable Auto Merge?", r.AutoMergeAllowed)
479526
if err != nil {
@@ -634,3 +681,39 @@ func transformSecurityAndAnalysisOpts(opts *EditOptions) *SecurityAndAnalysisInp
634681
}
635682
return securityOptions
636683
}
684+
685+
var validSquashMsgValues = []string{squashMsgDefault, squashMsgPRTitle, squashMsgPRTitleCommits, squashMsgPRTitleDescription}
686+
687+
func validateSquashMergeCommitMsg(value string) error {
688+
if slices.Contains(validSquashMsgValues, value) {
689+
return nil
690+
}
691+
return cmdutil.FlagErrorf("invalid value for --squash-merge-commit-message: %q. Valid values are: %s", value, strings.Join(validSquashMsgValues, ", "))
692+
}
693+
694+
// transformSquashMergeOpts maps the user-facing squash merge commit message option
695+
// to the two API fields: squash_merge_commit_title and squash_merge_commit_message.
696+
func transformSquashMergeOpts(edits *EditRepositoryInput) {
697+
if edits.squashMergeCommitMsg == nil {
698+
return
699+
}
700+
var title, message string
701+
switch *edits.squashMergeCommitMsg {
702+
case squashMsgDefault:
703+
title = "COMMIT_OR_PR_TITLE"
704+
message = "COMMIT_MESSAGES"
705+
case squashMsgPRTitle:
706+
title = "PR_TITLE"
707+
message = "BLANK"
708+
case squashMsgPRTitleCommits:
709+
title = "PR_TITLE"
710+
message = "COMMIT_MESSAGES"
711+
case squashMsgPRTitleDescription:
712+
title = "PR_TITLE"
713+
message = "PR_BODY"
714+
default:
715+
return
716+
}
717+
edits.SquashMergeCommitTitle = &title
718+
edits.SquashMergeCommitMessage = &message
719+
}

0 commit comments

Comments
 (0)