From 45a4257612fe600456d1ad1a5efec64a490a8d4e Mon Sep 17 00:00:00 2001 From: Des Preston Date: Thu, 15 Jul 2021 10:07:21 -0400 Subject: [PATCH 1/2] add --discussion-category flag to release cmd Flag for signaling that a discussion should be created with the given category for the release. Discussions are not supported for draft releases. If a discussion category is given for a draft, an err will be shown. Closes #3381 --- pkg/cmd/release/create/create.go | 29 +++++-- pkg/cmd/release/create/create_test.go | 116 +++++++++++++++++++++----- 2 files changed, 119 insertions(+), 26 deletions(-) diff --git a/pkg/cmd/release/create/create.go b/pkg/cmd/release/create/create.go index 5c91eed9b..8253ea5a9 100644 --- a/pkg/cmd/release/create/create.go +++ b/pkg/cmd/release/create/create.go @@ -2,6 +2,7 @@ package create import ( "bytes" + "errors" "fmt" "net/http" "os" @@ -48,6 +49,8 @@ type CreateOptions struct { // maximum number of simultaneous uploads Concurrency int + + DiscussionCategoryName string } func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Command { @@ -92,9 +95,16 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co Upload a release asset with a display label $ gh release create v1.2.3 '/path/to/asset.zip#My display label' + + Create a release and start a discussion + $ gh release create v1.2.3 --discussion-category "General" `), Args: cmdutil.MinimumArgs(1, "could not create: no tag name provided"), RunE: func(cmd *cobra.Command, args []string) error { + if cmd.Flags().Changed("discussion-category") && opts.Draft { + return errors.New("Discussions for draft releases not supported") + } + // support `-R, --repo` override opts.BaseRepo = f.BaseRepo opts.RepoOverride, _ = cmd.Flags().GetString("repo") @@ -132,6 +142,7 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co cmd.Flags().StringVarP(&opts.Name, "title", "t", "", "Release title") cmd.Flags().StringVarP(&opts.Body, "notes", "n", "", "Release notes") cmd.Flags().StringVarP(¬esFile, "notes-file", "F", "", "Read release notes from `file`") + cmd.Flags().StringVarP(&opts.DiscussionCategoryName, "discussion-category", "", "", "Start a discussion of the specified category") return cmd } @@ -268,12 +279,20 @@ func createRun(opts *CreateOptions) error { } } + if opts.Draft && len(opts.DiscussionCategoryName) > 0 { + return fmt.Errorf( + "%s Discussions not supported with draft releases", + opts.IO.ColorScheme().FailureIcon(), + ) + } + params := map[string]interface{}{ - "tag_name": opts.TagName, - "draft": opts.Draft, - "prerelease": opts.Prerelease, - "name": opts.Name, - "body": opts.Body, + "tag_name": opts.TagName, + "draft": opts.Draft, + "prerelease": opts.Prerelease, + "name": opts.Name, + "body": opts.Body, + "discussion_category_name": opts.DiscussionCategoryName, } if opts.Target != "" { params["target_commitish"] = opts.Target diff --git a/pkg/cmd/release/create/create_test.go b/pkg/cmd/release/create/create_test.go index 8bfb2d325..2eb37a7da 100644 --- a/pkg/cmd/release/create/create_test.go +++ b/pkg/cmd/release/create/create_test.go @@ -160,6 +160,30 @@ func Test_NewCmdCreate(t *testing.T) { isTTY: true, wantErr: "could not create: no tag name provided", }, + { + name: "discussion category", + args: "v1.2.3 --discussion-category 'General'", + isTTY: true, + want: CreateOptions{ + TagName: "v1.2.3", + Target: "", + Name: "", + Body: "", + BodyProvided: false, + Draft: false, + Prerelease: false, + RepoOverride: "", + Concurrency: 5, + Assets: []*shared.AssetForUpload(nil), + DiscussionCategoryName: "General", + }, + }, + { + name: "discussion category for draft release", + args: "v1.2.3 -d --discussion-category 'General'", + isTTY: true, + wantErr: "Discussions for draft releases not supported", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -209,6 +233,7 @@ func Test_NewCmdCreate(t *testing.T) { assert.Equal(t, tt.want.Prerelease, opts.Prerelease) assert.Equal(t, tt.want.Concurrency, opts.Concurrency) assert.Equal(t, tt.want.RepoOverride, opts.RepoOverride) + assert.Equal(t, tt.want.DiscussionCategoryName, opts.DiscussionCategoryName) require.Equal(t, len(tt.want.Assets), len(opts.Assets)) for i := range tt.want.Assets { @@ -240,11 +265,34 @@ func Test_createRun(t *testing.T) { Target: "", }, wantParams: map[string]interface{}{ - "tag_name": "v1.2.3", - "name": "The Big 1.2", - "body": "* Fixed bugs", - "draft": false, - "prerelease": false, + "tag_name": "v1.2.3", + "name": "The Big 1.2", + "body": "* Fixed bugs", + "draft": false, + "prerelease": false, + "discussion_category_name": "", + }, + wantStdout: "https://github.com/OWNER/REPO/releases/tag/v1.2.3\n", + wantStderr: ``, + }, + { + name: "with discussion category", + isTTY: true, + opts: CreateOptions{ + TagName: "v1.2.3", + Name: "The Big 1.2", + Body: "* Fixed bugs", + BodyProvided: true, + Target: "", + DiscussionCategoryName: "General", + }, + wantParams: map[string]interface{}{ + "tag_name": "v1.2.3", + "name": "The Big 1.2", + "body": "* Fixed bugs", + "draft": false, + "prerelease": false, + "discussion_category_name": "General", }, wantStdout: "https://github.com/OWNER/REPO/releases/tag/v1.2.3\n", wantStderr: ``, @@ -260,12 +308,13 @@ func Test_createRun(t *testing.T) { Target: "main", }, wantParams: map[string]interface{}{ - "tag_name": "v1.2.3", - "name": "", - "body": "", - "draft": false, - "prerelease": false, - "target_commitish": "main", + "tag_name": "v1.2.3", + "name": "", + "body": "", + "draft": false, + "prerelease": false, + "target_commitish": "main", + "discussion_category_name": "", }, wantStdout: "https://github.com/OWNER/REPO/releases/tag/v1.2.3\n", wantStderr: ``, @@ -282,15 +331,39 @@ func Test_createRun(t *testing.T) { Target: "", }, wantParams: map[string]interface{}{ - "tag_name": "v1.2.3", - "name": "", - "body": "", - "draft": true, - "prerelease": false, + "tag_name": "v1.2.3", + "name": "", + "body": "", + "draft": true, + "prerelease": false, + "discussion_category_name": "", }, wantStdout: "https://github.com/OWNER/REPO/releases/tag/v1.2.3\n", wantStderr: ``, }, + { + name: "discussion category for draft release", + isTTY: true, + opts: CreateOptions{ + TagName: "v1.2.3", + Name: "", + Body: "", + BodyProvided: true, + Draft: true, + Target: "", + DiscussionCategoryName: "general", + }, + wantParams: map[string]interface{}{ + "tag_name": "v1.2.3", + "name": "", + "body": "", + "draft": true, + "prerelease": false, + "discussion_category_name": "general", + }, + wantErr: "X Discussions not supported with draft releases", + wantStdout: "", + }, { name: "publish after uploading files", isTTY: true, @@ -312,11 +385,12 @@ func Test_createRun(t *testing.T) { Concurrency: 1, }, wantParams: map[string]interface{}{ - "tag_name": "v1.2.3", - "name": "", - "body": "", - "draft": true, - "prerelease": false, + "tag_name": "v1.2.3", + "name": "", + "body": "", + "draft": true, + "prerelease": false, + "discussion_category_name": "", }, wantStdout: "https://github.com/OWNER/REPO/releases/tag/v1.2.3-final\n", wantStderr: ``, From bdc5b55f556c768068f146182a30b799b4f95a0a Mon Sep 17 00:00:00 2001 From: Des Preston Date: Tue, 10 Aug 2021 09:47:49 -0400 Subject: [PATCH 2/2] pr comments Only add discussion category to request if there is one. This eliminates the need to update old tests. Renaming the variable to something shorter. --- pkg/cmd/release/create/create.go | 20 +++--- pkg/cmd/release/create/create_test.go | 96 +++++++++++++-------------- 2 files changed, 57 insertions(+), 59 deletions(-) diff --git a/pkg/cmd/release/create/create.go b/pkg/cmd/release/create/create.go index 8253ea5a9..2394804ff 100644 --- a/pkg/cmd/release/create/create.go +++ b/pkg/cmd/release/create/create.go @@ -50,7 +50,7 @@ type CreateOptions struct { // maximum number of simultaneous uploads Concurrency int - DiscussionCategoryName string + DiscussionCategory string } func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Command { @@ -142,7 +142,7 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co cmd.Flags().StringVarP(&opts.Name, "title", "t", "", "Release title") cmd.Flags().StringVarP(&opts.Body, "notes", "n", "", "Release notes") cmd.Flags().StringVarP(¬esFile, "notes-file", "F", "", "Read release notes from `file`") - cmd.Flags().StringVarP(&opts.DiscussionCategoryName, "discussion-category", "", "", "Start a discussion of the specified category") + cmd.Flags().StringVarP(&opts.DiscussionCategory, "discussion-category", "", "", "Start a discussion of the specified category") return cmd } @@ -279,7 +279,7 @@ func createRun(opts *CreateOptions) error { } } - if opts.Draft && len(opts.DiscussionCategoryName) > 0 { + if opts.Draft && len(opts.DiscussionCategory) > 0 { return fmt.Errorf( "%s Discussions not supported with draft releases", opts.IO.ColorScheme().FailureIcon(), @@ -287,16 +287,18 @@ func createRun(opts *CreateOptions) error { } params := map[string]interface{}{ - "tag_name": opts.TagName, - "draft": opts.Draft, - "prerelease": opts.Prerelease, - "name": opts.Name, - "body": opts.Body, - "discussion_category_name": opts.DiscussionCategoryName, + "tag_name": opts.TagName, + "draft": opts.Draft, + "prerelease": opts.Prerelease, + "name": opts.Name, + "body": opts.Body, } if opts.Target != "" { params["target_commitish"] = opts.Target } + if opts.DiscussionCategory != "" { + params["discussion_category_name"] = opts.DiscussionCategory + } hasAssets := len(opts.Assets) > 0 diff --git a/pkg/cmd/release/create/create_test.go b/pkg/cmd/release/create/create_test.go index 2eb37a7da..46b7fc4be 100644 --- a/pkg/cmd/release/create/create_test.go +++ b/pkg/cmd/release/create/create_test.go @@ -165,17 +165,17 @@ func Test_NewCmdCreate(t *testing.T) { args: "v1.2.3 --discussion-category 'General'", isTTY: true, want: CreateOptions{ - TagName: "v1.2.3", - Target: "", - Name: "", - Body: "", - BodyProvided: false, - Draft: false, - Prerelease: false, - RepoOverride: "", - Concurrency: 5, - Assets: []*shared.AssetForUpload(nil), - DiscussionCategoryName: "General", + TagName: "v1.2.3", + Target: "", + Name: "", + Body: "", + BodyProvided: false, + Draft: false, + Prerelease: false, + RepoOverride: "", + Concurrency: 5, + Assets: []*shared.AssetForUpload(nil), + DiscussionCategory: "General", }, }, { @@ -233,7 +233,7 @@ func Test_NewCmdCreate(t *testing.T) { assert.Equal(t, tt.want.Prerelease, opts.Prerelease) assert.Equal(t, tt.want.Concurrency, opts.Concurrency) assert.Equal(t, tt.want.RepoOverride, opts.RepoOverride) - assert.Equal(t, tt.want.DiscussionCategoryName, opts.DiscussionCategoryName) + assert.Equal(t, tt.want.DiscussionCategory, opts.DiscussionCategory) require.Equal(t, len(tt.want.Assets), len(opts.Assets)) for i := range tt.want.Assets { @@ -265,12 +265,11 @@ func Test_createRun(t *testing.T) { Target: "", }, wantParams: map[string]interface{}{ - "tag_name": "v1.2.3", - "name": "The Big 1.2", - "body": "* Fixed bugs", - "draft": false, - "prerelease": false, - "discussion_category_name": "", + "tag_name": "v1.2.3", + "name": "The Big 1.2", + "body": "* Fixed bugs", + "draft": false, + "prerelease": false, }, wantStdout: "https://github.com/OWNER/REPO/releases/tag/v1.2.3\n", wantStderr: ``, @@ -279,12 +278,12 @@ func Test_createRun(t *testing.T) { name: "with discussion category", isTTY: true, opts: CreateOptions{ - TagName: "v1.2.3", - Name: "The Big 1.2", - Body: "* Fixed bugs", - BodyProvided: true, - Target: "", - DiscussionCategoryName: "General", + TagName: "v1.2.3", + Name: "The Big 1.2", + Body: "* Fixed bugs", + BodyProvided: true, + Target: "", + DiscussionCategory: "General", }, wantParams: map[string]interface{}{ "tag_name": "v1.2.3", @@ -308,13 +307,12 @@ func Test_createRun(t *testing.T) { Target: "main", }, wantParams: map[string]interface{}{ - "tag_name": "v1.2.3", - "name": "", - "body": "", - "draft": false, - "prerelease": false, - "target_commitish": "main", - "discussion_category_name": "", + "tag_name": "v1.2.3", + "name": "", + "body": "", + "draft": false, + "prerelease": false, + "target_commitish": "main", }, wantStdout: "https://github.com/OWNER/REPO/releases/tag/v1.2.3\n", wantStderr: ``, @@ -331,12 +329,11 @@ func Test_createRun(t *testing.T) { Target: "", }, wantParams: map[string]interface{}{ - "tag_name": "v1.2.3", - "name": "", - "body": "", - "draft": true, - "prerelease": false, - "discussion_category_name": "", + "tag_name": "v1.2.3", + "name": "", + "body": "", + "draft": true, + "prerelease": false, }, wantStdout: "https://github.com/OWNER/REPO/releases/tag/v1.2.3\n", wantStderr: ``, @@ -345,13 +342,13 @@ func Test_createRun(t *testing.T) { name: "discussion category for draft release", isTTY: true, opts: CreateOptions{ - TagName: "v1.2.3", - Name: "", - Body: "", - BodyProvided: true, - Draft: true, - Target: "", - DiscussionCategoryName: "general", + TagName: "v1.2.3", + Name: "", + Body: "", + BodyProvided: true, + Draft: true, + Target: "", + DiscussionCategory: "general", }, wantParams: map[string]interface{}{ "tag_name": "v1.2.3", @@ -385,12 +382,11 @@ func Test_createRun(t *testing.T) { Concurrency: 1, }, wantParams: map[string]interface{}{ - "tag_name": "v1.2.3", - "name": "", - "body": "", - "draft": true, - "prerelease": false, - "discussion_category_name": "", + "tag_name": "v1.2.3", + "name": "", + "body": "", + "draft": true, + "prerelease": false, }, wantStdout: "https://github.com/OWNER/REPO/releases/tag/v1.2.3-final\n", wantStderr: ``,