github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/release/edit/edit.go (about) 1 package edit 2 3 import ( 4 "fmt" 5 "net/http" 6 7 "github.com/MakeNowJust/heredoc" 8 "github.com/ungtb10d/cli/v2/internal/ghrepo" 9 "github.com/ungtb10d/cli/v2/pkg/cmd/release/shared" 10 "github.com/ungtb10d/cli/v2/pkg/cmdutil" 11 "github.com/ungtb10d/cli/v2/pkg/iostreams" 12 "github.com/spf13/cobra" 13 ) 14 15 type EditOptions struct { 16 IO *iostreams.IOStreams 17 HttpClient func() (*http.Client, error) 18 BaseRepo func() (ghrepo.Interface, error) 19 20 TagName string 21 Target string 22 Name *string 23 Body *string 24 DiscussionCategory *string 25 Draft *bool 26 Prerelease *bool 27 IsLatest *bool 28 } 29 30 func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Command { 31 opts := &EditOptions{ 32 IO: f.IOStreams, 33 HttpClient: f.HttpClient, 34 } 35 36 var notesFile string 37 38 cmd := &cobra.Command{ 39 DisableFlagsInUseLine: true, 40 41 Use: "edit <tag>", 42 Short: "Edit a release", 43 Example: heredoc.Doc(` 44 Publish a release that was previously a draft 45 $ gh release edit v1.0 --draft=false 46 47 Update the release notes from the content of a file 48 $ gh release edit v1.0 --notes-file /path/to/release_notes.md 49 `), 50 Args: cobra.ExactArgs(1), 51 RunE: func(cmd *cobra.Command, args []string) error { 52 opts.BaseRepo = f.BaseRepo 53 54 if cmd.Flags().NFlag() == 0 { 55 return cmdutil.FlagErrorf("use flags to specify properties to edit") 56 } 57 58 if notesFile != "" { 59 b, err := cmdutil.ReadFile(notesFile, opts.IO.In) 60 if err != nil { 61 return err 62 } 63 body := string(b) 64 opts.Body = &body 65 } 66 67 if runF != nil { 68 return runF(opts) 69 } 70 return editRun(args[0], opts) 71 }, 72 } 73 74 cmdutil.NilBoolFlag(cmd, &opts.Draft, "draft", "", "Save the release as a draft instead of publishing it") 75 cmdutil.NilBoolFlag(cmd, &opts.Prerelease, "prerelease", "", "Mark the release as a prerelease") 76 cmdutil.NilBoolFlag(cmd, &opts.IsLatest, "latest", "", "Explicitly mark the release as \"Latest\"") 77 cmdutil.NilStringFlag(cmd, &opts.Body, "notes", "n", "Release notes") 78 cmdutil.NilStringFlag(cmd, &opts.Name, "title", "t", "Release title") 79 cmdutil.NilStringFlag(cmd, &opts.DiscussionCategory, "discussion-category", "", "Start a discussion in the specified category when publishing a draft") 80 cmd.Flags().StringVar(&opts.Target, "target", "", "Target `branch` or full commit SHA (default: main branch)") 81 cmd.Flags().StringVar(&opts.TagName, "tag", "", "The name of the tag") 82 cmd.Flags().StringVarP(¬esFile, "notes-file", "F", "", "Read release notes from `file` (use \"-\" to read from standard input)") 83 84 return cmd 85 } 86 87 func editRun(tag string, opts *EditOptions) error { 88 httpClient, err := opts.HttpClient() 89 if err != nil { 90 return err 91 } 92 93 baseRepo, err := opts.BaseRepo() 94 if err != nil { 95 return err 96 } 97 98 release, err := shared.FetchRelease(httpClient, baseRepo, tag) 99 if err != nil { 100 return err 101 } 102 103 params := getParams(opts) 104 105 // If we don't provide any tag name, the API will remove the current tag from the release 106 if _, ok := params["tag_name"]; !ok { 107 params["tag_name"] = release.TagName 108 } 109 110 editedRelease, err := editRelease(httpClient, baseRepo, release.DatabaseID, params) 111 if err != nil { 112 return err 113 } 114 115 fmt.Fprintf(opts.IO.Out, "%s\n", editedRelease.URL) 116 117 return nil 118 } 119 120 func getParams(opts *EditOptions) map[string]interface{} { 121 params := map[string]interface{}{} 122 123 if opts.Body != nil { 124 params["body"] = opts.Body 125 } 126 127 if opts.DiscussionCategory != nil { 128 params["discussion_category_name"] = *opts.DiscussionCategory 129 } 130 131 if opts.Draft != nil { 132 params["draft"] = *opts.Draft 133 } 134 135 if opts.Name != nil { 136 params["name"] = opts.Name 137 } 138 139 if opts.Prerelease != nil { 140 params["prerelease"] = *opts.Prerelease 141 } 142 143 if opts.TagName != "" { 144 params["tag_name"] = opts.TagName 145 } 146 147 if opts.Target != "" { 148 params["target_commitish"] = opts.Target 149 } 150 151 if opts.IsLatest != nil { 152 // valid values: true/false/legacy 153 params["make_latest"] = fmt.Sprintf("%v", *opts.IsLatest) 154 } 155 156 return params 157 }