Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 103 additions & 20 deletions pkg/cmd/repo/edit/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io"
"net/http"
"slices"
"strings"
"time"

Expand Down Expand Up @@ -35,18 +36,25 @@ const (
allowSquashMerge = "Allow Squash Merging"
allowRebaseMerge = "Allow Rebase Merging"

squashMsgDefault = "default"
squashMsgPRTitle = "pr-title"
squashMsgPRTitleCommits = "pr-title-commits"
squashMsgPRTitleDescription = "pr-title-description"

optionAllowForking = "Allow Forking"
optionDefaultBranchName = "Default Branch Name"
optionDescription = "Description"
optionHomePageURL = "Home Page URL"
optionIssues = "Issues"
optionMergeOptions = "Merge Options"
optionProjects = "Projects"
optionDiscussions = "Discussions"
optionTemplateRepo = "Template Repository"
optionTopics = "Topics"
optionVisibility = "Visibility"
optionWikis = "Wikis"

// TODO: GitHub Enterprise Server does not support has_discussions yet
// optionDiscussions = "Discussions"
)

type EditOptions struct {
Expand All @@ -69,24 +77,27 @@ type EditRepositoryInput struct {
enableAdvancedSecurity *bool
enableSecretScanning *bool
enableSecretScanningPushProtection *bool

AllowForking *bool `json:"allow_forking,omitempty"`
AllowUpdateBranch *bool `json:"allow_update_branch,omitempty"`
DefaultBranch *string `json:"default_branch,omitempty"`
DeleteBranchOnMerge *bool `json:"delete_branch_on_merge,omitempty"`
Description *string `json:"description,omitempty"`
EnableAutoMerge *bool `json:"allow_auto_merge,omitempty"`
EnableIssues *bool `json:"has_issues,omitempty"`
EnableMergeCommit *bool `json:"allow_merge_commit,omitempty"`
EnableProjects *bool `json:"has_projects,omitempty"`
EnableDiscussions *bool `json:"has_discussions,omitempty"`
EnableRebaseMerge *bool `json:"allow_rebase_merge,omitempty"`
EnableSquashMerge *bool `json:"allow_squash_merge,omitempty"`
EnableWiki *bool `json:"has_wiki,omitempty"`
Homepage *string `json:"homepage,omitempty"`
IsTemplate *bool `json:"is_template,omitempty"`
SecurityAndAnalysis *SecurityAndAnalysisInput `json:"security_and_analysis,omitempty"`
Visibility *string `json:"visibility,omitempty"`
squashMergeCommitMsg *string

AllowForking *bool `json:"allow_forking,omitempty"`
AllowUpdateBranch *bool `json:"allow_update_branch,omitempty"`
DefaultBranch *string `json:"default_branch,omitempty"`
DeleteBranchOnMerge *bool `json:"delete_branch_on_merge,omitempty"`
Description *string `json:"description,omitempty"`
EnableAutoMerge *bool `json:"allow_auto_merge,omitempty"`
EnableIssues *bool `json:"has_issues,omitempty"`
EnableMergeCommit *bool `json:"allow_merge_commit,omitempty"`
EnableProjects *bool `json:"has_projects,omitempty"`
EnableDiscussions *bool `json:"has_discussions,omitempty"`
EnableRebaseMerge *bool `json:"allow_rebase_merge,omitempty"`
EnableSquashMerge *bool `json:"allow_squash_merge,omitempty"`
EnableWiki *bool `json:"has_wiki,omitempty"`
Homepage *string `json:"homepage,omitempty"`
IsTemplate *bool `json:"is_template,omitempty"`
SecurityAndAnalysis *SecurityAndAnalysisInput `json:"security_and_analysis,omitempty"`
SquashMergeCommitTitle *string `json:"squash_merge_commit_title,omitempty"`
SquashMergeCommitMessage *string `json:"squash_merge_commit_message,omitempty"`
Visibility *string `json:"visibility,omitempty"`
}

func NewCmdEdit(f *cmdutil.Factory, runF func(options *EditOptions) error) *cobra.Command {
Expand Down Expand Up @@ -120,7 +131,15 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(options *EditOptions) error) *cobr
When the %[1]s--visibility%[1]s flag is used, %[1]s--accept-visibility-change-consequences%[1]s flag is required.

For information on all the potential consequences, see <https://gh.io/setting-repository-visibility>.
`, "`"),

When the %[1]s--enable-squash-merge%[1]s flag is used, %[1]s--squash-merge-commit-message%[1]s
can be used to change the default squash merge commit message behavior:

- %[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
- %[1]s%[3]s%[1]s: uses pull request title
- %[1]s%[4]s%[1]s: uses pull request title and list of commits
- %[1]s%[5]s%[1]s: uses pull request title and description
`, "`", squashMsgDefault, squashMsgPRTitle, squashMsgPRTitleCommits, squashMsgPRTitleDescription),
Args: cobra.MaximumNArgs(1),
Example: heredoc.Doc(`
# Enable issues and wiki
Expand Down Expand Up @@ -162,6 +181,19 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(options *EditOptions) error) *cobr
return cmdutil.FlagErrorf("use of --visibility flag requires --accept-visibility-change-consequences flag")
}

if opts.Edits.squashMergeCommitMsg != nil {
if opts.Edits.EnableSquashMerge == nil {
return cmdutil.FlagErrorf("--squash-merge-commit-message requires --enable-squash-merge")
}
if !*opts.Edits.EnableSquashMerge {
return cmdutil.FlagErrorf("--squash-merge-commit-message cannot be used when --enable-squash-merge=false")
}
if err := validateSquashMergeCommitMsg(*opts.Edits.squashMergeCommitMsg); err != nil {
return err
}
transformSquashMergeOpts(&opts.Edits)
}

if hasSecurityEdits(opts.Edits) {
opts.Edits.SecurityAndAnalysis = transformSecurityAndAnalysisOpts(opts)
}
Expand Down Expand Up @@ -192,6 +224,7 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(options *EditOptions) error) *cobr
cmdutil.NilBoolFlag(cmd, &opts.Edits.DeleteBranchOnMerge, "delete-branch-on-merge", "", "Delete head branch when pull requests are merged")
cmdutil.NilBoolFlag(cmd, &opts.Edits.AllowForking, "allow-forking", "", "Allow forking of an organization repository")
cmdutil.NilBoolFlag(cmd, &opts.Edits.AllowUpdateBranch, "allow-update-branch", "", "Allow a pull request head branch that is behind its base branch to be updated")
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}")
cmd.Flags().StringSliceVar(&opts.AddTopics, "add-topic", nil, "Add repository topic")
cmd.Flags().StringSliceVar(&opts.RemoveTopics, "remove-topic", nil, "Remove repository topic")
cmd.Flags().BoolVar(&opts.AcceptVisibilityChangeConsequences, "accept-visibility-change-consequences", false, "Accept the consequences of changing the repository visibility")
Expand Down Expand Up @@ -474,6 +507,20 @@ func interactiveRepoEdit(opts *EditOptions, r *api.Repository) error {
return fmt.Errorf("you need to allow at least one merge strategy")
}

if enableSquashMerge {
squashMsgOptions := validSquashMsgValues
idx, err := p.Select(
"Default squash merge commit message",
squashMsgDefault,
squashMsgOptions)
if err != nil {
return err
}
selected := squashMsgOptions[idx]
opts.Edits.squashMergeCommitMsg = &selected
transformSquashMergeOpts(&opts.Edits)
}

opts.Edits.EnableAutoMerge = &r.AutoMergeAllowed
c, err := p.Confirm("Enable Auto Merge?", r.AutoMergeAllowed)
if err != nil {
Expand Down Expand Up @@ -634,3 +681,39 @@ func transformSecurityAndAnalysisOpts(opts *EditOptions) *SecurityAndAnalysisInp
}
return securityOptions
}

var validSquashMsgValues = []string{squashMsgDefault, squashMsgPRTitle, squashMsgPRTitleCommits, squashMsgPRTitleDescription}

func validateSquashMergeCommitMsg(value string) error {
if slices.Contains(validSquashMsgValues, value) {
return nil
}
return cmdutil.FlagErrorf("invalid value for --squash-merge-commit-message: %q. Valid values are: %s", value, strings.Join(validSquashMsgValues, ", "))
}

// transformSquashMergeOpts maps the user-facing squash merge commit message option
// to the two API fields: squash_merge_commit_title and squash_merge_commit_message.
func transformSquashMergeOpts(edits *EditRepositoryInput) {
if edits.squashMergeCommitMsg == nil {
return
}
var title, message string
switch *edits.squashMergeCommitMsg {
case squashMsgDefault:
title = "COMMIT_OR_PR_TITLE"
message = "COMMIT_MESSAGES"
case squashMsgPRTitle:
title = "PR_TITLE"
message = "BLANK"
case squashMsgPRTitleCommits:
title = "PR_TITLE"
message = "COMMIT_MESSAGES"
case squashMsgPRTitleDescription:
title = "PR_TITLE"
message = "PR_BODY"
default:
return
}
edits.SquashMergeCommitTitle = &title
edits.SquashMergeCommitMessage = &message
}
Loading
Loading