diff --git a/pkg/cmd/issue/create/create.go b/pkg/cmd/issue/create/create.go index 640057100..51f828f8d 100644 --- a/pkg/cmd/issue/create/create.go +++ b/pkg/cmd/issue/create/create.go @@ -242,7 +242,7 @@ func createRun(opts *CreateOptions) (err error) { } allowPreview := !tb.HasMetadata() && utils.ValidURL(openURL) - action, err = prShared.ConfirmSubmission(allowPreview, repo.ViewerCanTriage()) + action, err = prShared.ConfirmIssueSubmission(allowPreview, repo.ViewerCanTriage()) if err != nil { err = fmt.Errorf("unable to confirm: %w", err) return @@ -260,7 +260,7 @@ func createRun(opts *CreateOptions) (err error) { return } - action, err = prShared.ConfirmSubmission(!tb.HasMetadata(), false) + action, err = prShared.ConfirmIssueSubmission(!tb.HasMetadata(), false) if err != nil { return } diff --git a/pkg/cmd/issue/create/create_test.go b/pkg/cmd/issue/create/create_test.go index 4eaea333a..7f7dc2433 100644 --- a/pkg/cmd/issue/create/create_test.go +++ b/pkg/cmd/issue/create/create_test.go @@ -472,7 +472,9 @@ func TestIssueCreate_nonLegacyTemplate(t *testing.T) { as.StubPrompt("Choose a template").AnswerWith("Submit a request") as.StubPrompt("Body").AnswerDefault() - as.StubPrompt("What's next?").AnswerWith("Submit") + as.StubPrompt("What's next?"). + AssertOptions([]string{"Submit", "Continue in browser", "Cancel"}). + AnswerWith("Submit") output, err := runCommandWithRootDirOverridden(http, true, `-t hello`, "./fixtures/repoWithNonLegacyIssueTemplates") if err != nil { diff --git a/pkg/cmd/pr/create/create.go b/pkg/cmd/pr/create/create.go index a642a1def..213ed3760 100644 --- a/pkg/cmd/pr/create/create.go +++ b/pkg/cmd/pr/create/create.go @@ -312,7 +312,7 @@ func createRun(opts *CreateOptions) (err error) { allowPreview := !state.HasMetadata() && utils.ValidURL(openURL) allowMetadata := ctx.BaseRepo.ViewerCanTriage() - action, err := shared.ConfirmSubmission(allowPreview, allowMetadata) + action, err := shared.ConfirmPRSubmission(allowPreview, allowMetadata) if err != nil { return fmt.Errorf("unable to confirm: %w", err) } @@ -329,7 +329,7 @@ func createRun(opts *CreateOptions) (err error) { return } - action, err = shared.ConfirmSubmission(!state.HasMetadata(), false) + action, err = shared.ConfirmPRSubmission(!state.HasMetadata(), false) if err != nil { return } @@ -350,6 +350,11 @@ func createRun(opts *CreateOptions) (err error) { return previewPR(*opts, openURL) } + if action == shared.SubmitDraftAction { + state.Draft = true + return submitPR(*opts, *ctx, *state) + } + if action == shared.SubmitAction { return submitPR(*opts, *ctx, *state) } diff --git a/pkg/cmd/pr/create/create_test.go b/pkg/cmd/pr/create/create_test.go index 348ad30af..3342ef5a1 100644 --- a/pkg/cmd/pr/create/create_test.go +++ b/pkg/cmd/pr/create/create_test.go @@ -370,6 +370,7 @@ func TestPRCreate(t *testing.T) { assert.Equal(t, "my body", input["body"].(string)) assert.Equal(t, "master", input["baseRefName"].(string)) assert.Equal(t, "feature", input["headRefName"].(string)) + assert.Equal(t, false, input["draft"].(bool)) })) cs, cmdTeardown := run.Stub() @@ -632,7 +633,7 @@ func TestPRCreate_nonLegacyTemplate(t *testing.T) { AnswerWith("template1") as.StubPrompt("Body").AnswerDefault() as.StubPrompt("What's next?"). - AssertOptions([]string{"Submit", "Continue in browser", "Add metadata", "Cancel"}). + AssertOptions([]string{"Submit", "Submit as draft", "Continue in browser", "Add metadata", "Cancel"}). AnswerDefault() output, err := runCommandWithRootDirOverridden(http, nil, "feature", true, `-t "my title" -H feature`, "./fixtures/repoWithNonLegacyPRTemplates") @@ -861,6 +862,46 @@ func TestPRCreate_webProject(t *testing.T) { assert.Equal(t, "https://github.com/OWNER/REPO/compare/master...feature?body=&expand=1&projects=ORG%2F1", output.BrowsedURL) } +func TestPRCreate_draft(t *testing.T) { + http := initFakeHTTP() + defer http.Verify(t) + + http.StubRepoInfoResponse("OWNER", "REPO", "master") + shared.RunCommandFinder("feature", nil, nil) + http.Register( + httpmock.GraphQL(`query PullRequestTemplates\b`), + httpmock.StringResponse(` + { "data": { "repository": { "pullRequestTemplates": [ + { "filename": "template1", + "body": "this is a bug" }, + { "filename": "template2", + "body": "this is a enhancement" } + ] } } }`), + ) + http.Register( + httpmock.GraphQL(`mutation PullRequestCreate\b`), + httpmock.GraphQLMutation(` + { "data": { "createPullRequest": { "pullRequest": { + "URL": "https://github.com/OWNER/REPO/pull/12" + } } } } + `, func(input map[string]interface{}) { + assert.Equal(t, true, input["draft"].(bool)) + })) + + as := prompt.NewAskStubber(t) + + as.StubPrompt("Choose a template").AnswerDefault() + as.StubPrompt("Body").AnswerDefault() + as.StubPrompt("What's next?"). + AssertOptions([]string{"Submit", "Submit as draft", "Continue in browser", "Add metadata", "Cancel"}). + AnswerWith("Submit as draft") + + output, err := runCommand(http, nil, "feature", true, `-t "my title" -H feature`) + require.NoError(t, err) + + assert.Equal(t, "https://github.com/OWNER/REPO/pull/12\n", output.String()) +} + func Test_determineTrackingBranch_empty(t *testing.T) { cs, cmdTeardown := run.Stub() defer cmdTeardown(t) diff --git a/pkg/cmd/pr/shared/survey.go b/pkg/cmd/pr/shared/survey.go index 4597f777b..585efcf21 100644 --- a/pkg/cmd/pr/shared/survey.go +++ b/pkg/cmd/pr/shared/survey.go @@ -23,19 +23,32 @@ const ( MetadataAction EditCommitMessageAction EditCommitSubjectAction + SubmitDraftAction noMilestone = "(none)" ) -func ConfirmSubmission(allowPreview bool, allowMetadata bool) (Action, error) { +func ConfirmIssueSubmission(allowPreview bool, allowMetadata bool) (Action, error) { + return confirmSubmission(allowPreview, allowMetadata, false) +} + +func ConfirmPRSubmission(allowPreview bool, allowMetadata bool) (Action, error) { + return confirmSubmission(allowPreview, allowMetadata, true) +} + +func confirmSubmission(allowPreview, allowMetadata, allowDraft bool) (Action, error) { const ( - submitLabel = "Submit" - previewLabel = "Continue in browser" - metadataLabel = "Add metadata" - cancelLabel = "Cancel" + submitLabel = "Submit" + submitDraftLabel = "Submit as draft" + previewLabel = "Continue in browser" + metadataLabel = "Add metadata" + cancelLabel = "Cancel" ) options := []string{submitLabel} + if allowDraft { + options = append(options, submitDraftLabel) + } if allowPreview { options = append(options, previewLabel) } @@ -65,6 +78,8 @@ func ConfirmSubmission(allowPreview bool, allowMetadata bool) (Action, error) { switch options[confirmAnswers.Confirmation] { case submitLabel: return SubmitAction, nil + case submitDraftLabel: + return SubmitDraftAction, nil case previewLabel: return PreviewAction, nil case metadataLabel: