github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/cmd/step/create/pr/step_create_pr.go (about) 1 package pr 2 3 import ( 4 "os" 5 6 "github.com/olli-ai/jx/v2/pkg/cmd/opts/step" 7 8 "github.com/olli-ai/jx/v2/pkg/gits/operations" 9 10 "github.com/jenkins-x/jx-logging/pkg/log" 11 12 "github.com/olli-ai/jx/v2/pkg/cmd/helper" 13 "github.com/olli-ai/jx/v2/pkg/cmd/opts" 14 "github.com/olli-ai/jx/v2/pkg/gits" 15 "github.com/olli-ai/jx/v2/pkg/util" 16 "github.com/pkg/errors" 17 "github.com/spf13/cobra" 18 ) 19 20 //StepCreatePrOptions are the common options for all PR creation steps 21 type StepCreatePrOptions struct { 22 step.StepCreateOptions 23 Results *gits.PullRequestInfo 24 BranchName string 25 GitURLs []string 26 Base string 27 Fork bool 28 SrcGitURL string 29 Component string 30 Version string 31 DryRun bool 32 SkipCommit bool 33 SkipAutoMerge bool 34 Labels []string 35 } 36 37 // NewCmdStepCreatePr Steps a command object for the "step" command 38 func NewCmdStepCreatePr(commonOpts *opts.CommonOptions) *cobra.Command { 39 options := &StepCreatePrOptions{ 40 StepCreateOptions: step.StepCreateOptions{ 41 StepOptions: step.StepOptions{ 42 CommonOptions: commonOpts, 43 }, 44 }, 45 } 46 47 cmd := &cobra.Command{ 48 Use: "pullrequest", 49 Aliases: []string{"pr"}, 50 Short: "create pullrequest [command]", 51 Run: func(cmd *cobra.Command, args []string) { 52 options.Cmd = cmd 53 options.Args = args 54 err := options.Run() 55 helper.CheckErr(err) 56 }, 57 } 58 cmd.AddCommand(NewCmdStepCreatePullRequestBrew(commonOpts)) 59 cmd.AddCommand(NewCmdStepCreatePullRequestChart(commonOpts)) 60 cmd.AddCommand(NewCmdStepCreatePullRequestDocker(commonOpts)) 61 cmd.AddCommand(NewCmdStepCreatePullRequestGo(commonOpts)) 62 cmd.AddCommand(NewCmdStepCreatePullRequestMake(commonOpts)) 63 cmd.AddCommand(NewCmdStepCreatePullRequestQuickStarts(commonOpts)) 64 cmd.AddCommand(NewCmdStepCreatePullRequestRegex(commonOpts)) 65 cmd.AddCommand(NewCmdStepCreatePullRequestRepositories(commonOpts)) 66 cmd.AddCommand(NewCmdStepCreatePullRequestVersion(commonOpts)) 67 return cmd 68 } 69 70 // Run implements this command 71 func (o *StepCreatePrOptions) Run() error { 72 return o.Cmd.Help() 73 } 74 75 //AddStepCreatePrFlags adds the common flags for all PR creation steps to the cmd and stores them in o 76 func AddStepCreatePrFlags(cmd *cobra.Command, o *StepCreatePrOptions) { 77 cmd.Flags().StringArrayVarP(&o.GitURLs, "repo", "r", []string{}, "Git repo to update") 78 cmd.Flags().StringVarP(&o.BranchName, "branch", "", "master", "Branch to clone and generate a pull request from") 79 cmd.Flags().StringVarP(&o.Base, "base", "", "master", "The branch to create the pull request into") 80 cmd.Flags().StringVarP(&o.SrcGitURL, "src-repo", "", "", "The git repo which caused this change; if this is a dependency update this will cause commit messages to be generated which can be parsed by jx step changelog. By default this will be read from the environment variable REPO_URL") 81 cmd.Flags().StringVarP(&o.Component, "component", "", "", "The component of the git repo which caused this change; useful if you have a complex or monorepo setup and want to differentiate between different components from the same repo") 82 cmd.Flags().StringVarP(&o.Version, "version", "v", "", "The version to change. If no version is supplied the latest version is found") 83 cmd.Flags().BoolVarP(&o.DryRun, "dry-run", "", false, "Perform a dry run, the change will be generated and committed, but not pushed or have a PR created") 84 cmd.Flags().BoolVarP(&o.SkipAutoMerge, "skip-auto-merge", "", false, "Disable auto merge of the PR if status checks pass") 85 cmd.Flags().StringArrayVarP(&o.Labels, "labels", "", []string{}, "Labels to add to the created PR") 86 } 87 88 // ValidateOptions validates the common options for all PR creation steps 89 func (o *StepCreatePrOptions) ValidateOptions(allowEmptyVersion bool) error { 90 if o.SrcGitURL == "" { 91 o.SrcGitURL = os.Getenv("REPO_URL") 92 if o.SrcGitURL != "" { 93 log.Logger().Infof("Using %s as source for change discovered from env var REPO_URL", o.SrcGitURL) 94 } else { 95 // see if we're in a git repo and use it 96 wd, err := os.Getwd() 97 if err != nil { 98 return errors.Wrapf(err, "getting working directory") 99 } 100 gitInfo, err := o.FindGitInfo(wd) 101 if err != nil { 102 log.Logger().Debugf("Unable to discover git info from current directory because %v", err) 103 } else { 104 o.SrcGitURL = gitInfo.HttpsURL() 105 log.Logger().Infof("Using %s as source for change discovered from git repo in %s", o.SrcGitURL, wd) 106 } 107 } 108 109 } 110 if o.SrcGitURL == "" { 111 return errors.Errorf("unable to determine source url, no argument provided, env var REPO_URL is empty and working directory is not a git repo") 112 } 113 if !allowEmptyVersion && o.Version == "" { 114 return util.MissingOption("version") 115 } 116 if len(o.GitURLs) == 0 { 117 return util.MissingOption("repo") 118 } 119 return nil 120 } 121 122 // CreatePullRequest will fork (if needed) and pull a git repo, then perform the update, and finally create or update a 123 // PR for the change. Any open PR on the repo with the `updatebot` label will be updated. 124 func (o *StepCreatePrOptions) CreatePullRequest(kind string, update operations.ChangeFilesFn) error { 125 if o.DryRun { 126 log.Logger().Infof("--dry-run specified. Change will be created and committed to local git repo, but not pushed. No pull request will be created or updated. A fork will still be created.") 127 } 128 op := o.createPullRequestOperation() 129 var err error 130 o.Results, err = op.CreatePullRequest(kind, update) 131 if err != nil { 132 return errors.Wrap(err, "unable to create pull request") 133 } 134 return nil 135 } 136 137 func (o *StepCreatePrOptions) createPullRequestOperation() operations.PullRequestOperation { 138 op := operations.PullRequestOperation{ 139 CommonOptions: o.CommonOptions, 140 GitURLs: o.GitURLs, 141 BranchName: o.BranchName, 142 SrcGitURL: o.SrcGitURL, 143 Base: o.Base, 144 Version: o.Version, 145 Component: o.Component, 146 DryRun: o.DryRun, 147 SkipCommit: o.SkipCommit, 148 SkipAutoMerge: o.SkipAutoMerge, 149 Labels: o.Labels, 150 } 151 authorName, authorEmail, err := gits.EnsureUserAndEmailSetup(o.Git()) 152 if err != nil { 153 op.AuthorName = authorName 154 op.AuthorEmail = authorEmail 155 } 156 return op 157 }