github.com/LGUG2Z/story@v0.4.1/cli/merge.go (about) 1 package cli 2 3 import ( 4 "context" 5 "fmt" 6 "net/http" 7 "time" 8 9 "github.com/LGUG2Z/story/git" 10 "github.com/LGUG2Z/story/manifest" 11 "github.com/fatih/color" 12 "github.com/google/go-github/github" 13 "github.com/spf13/afero" 14 "github.com/urfave/cli" 15 ) 16 17 func MergeCmd(fs afero.Fs) cli.Command { 18 return cli.Command{ 19 Name: "merge", 20 Usage: "Merges prepared code to master branches across the current story", 21 Flags: []cli.Flag{ 22 cli.BoolFlag{Name: "github", Usage: "Use the GitHub squash and merge implementation via API"}, 23 cli.StringFlag{Name: "github-api-token", EnvVar: "GITHUB_API_TOKEN", Usage: "GitHub API token to authenticate with"}, 24 }, 25 Action: cli.ActionFunc(func(c *cli.Context) error { 26 if !isStory { 27 return ErrNotWorkingOnAStory 28 } 29 30 if c.Args().Present() { 31 return ErrCommandTakesNoArguments 32 } 33 34 currentBranch, err := git.GetCurrentBranch(fs, ".") 35 if err != nil { 36 return err 37 } 38 39 story, err := manifest.LoadStoryFromBranchName(fs, currentBranch) 40 if err != nil { 41 return err 42 } 43 44 messages := []string{fmt.Sprintf("[story merge] Merge branch '%s'", story.Name)} 45 46 if c.Bool("github") { 47 if len(c.String("github-api-token")) == 0 { 48 return ErrGitHubAPITokenRequired 49 } 50 51 ctx := context.Background() 52 client := getGitHubClient(ctx, c.String("github-api-token")) 53 54 story.Projects[metarepo] = "" 55 56 for project := range story.Projects { 57 color.Green(project) 58 // Get the open pull request 59 openPullRequest, err := getOpenPullRequest(client, ctx, story, project) 60 if err != nil { 61 switch err.Error() { 62 // If there is no open pull request 63 case ErrCouldNotFindOpenPullRequest(story.Name).Error(): 64 // Get the closed pull request 65 closedPullRequest, err := getClosedPullRequest(client, ctx, story, project) 66 if err != nil { 67 switch err.Error() { 68 // If there is no closed pull request, a pull request was never opened 69 case ErrCouldNotFindClosedPullRequest(story.Name).Error(): 70 fmt.Printf("could not find an open or closed pull request for %s\n", story.Name) 71 continue 72 // Something else went wrong here with the call to list closed pull requests 73 default: 74 fmt.Println(err) 75 continue 76 } 77 } 78 79 // Report that the pull request has already been closed with a link 80 fmt.Println("pull request has already been closed") 81 fmt.Println(*closedPullRequest.HTMLURL) 82 continue 83 // Something else went wrong here with the call to list open pull requests 84 default: 85 return err 86 } 87 } 88 89 _, resp, err := client.PullRequests.Merge(ctx, story.Orgranisation, project, *openPullRequest.Number, "", &github.PullRequestOptions{ 90 CommitTitle: messages[0], 91 MergeMethod: "squash", 92 SHA: story.Hashes[project], 93 }) 94 95 if err != nil { 96 return err 97 } 98 99 switch resp.StatusCode { 100 case http.StatusOK: 101 fmt.Println("pull request successfully merged") 102 case http.StatusMethodNotAllowed: 103 fmt.Println("pull request is not mergeable") 104 case http.StatusConflict: 105 fmt.Println("head branch was modified, review and try the merge again") 106 } 107 108 fmt.Println(*openPullRequest.HTMLURL) 109 time.Sleep(1 * time.Second) 110 } 111 112 return nil 113 } 114 115 // Checkout master and merge story in all projects 116 for project := range story.Projects { 117 color.Green(project) 118 checkoutBranchOutput, err := git.CheckoutBranch(git.CheckoutBranchOpts{ 119 Branch: trunk, 120 Project: project, 121 Create: false, 122 }) 123 124 if err != nil { 125 return err 126 } 127 128 fmt.Printf("%s\n\n", checkoutBranchOutput) 129 130 mergeOutput, err := git.Merge(git.MergeOpts{ 131 SourceBranch: story.Name, 132 DestinationBranch: trunk, 133 Project: project, 134 Squash: true, 135 }) 136 137 if err != nil { 138 return err 139 } 140 141 fmt.Printf("%s\n\n", mergeOutput) 142 143 commitOutput, err := git.Commit( 144 git.CommitOpts{ 145 Project: project, 146 Messages: messages, 147 }, 148 ) 149 150 if err != nil { 151 return err 152 } 153 154 fmt.Println(commitOutput) 155 } 156 157 color.Green(metarepo) 158 checkoutBranchOutput, err := git.CheckoutBranch(git.CheckoutBranchOpts{ 159 Branch: trunk, 160 Create: false, 161 }) 162 163 if err != nil { 164 return err 165 } 166 167 fmt.Printf("%s\n\n", checkoutBranchOutput) 168 169 // Merge story into master on the metarepo 170 mergeOutput, err := git.Merge(git.MergeOpts{ 171 SourceBranch: story.Name, 172 DestinationBranch: trunk, 173 Squash: true, 174 }) 175 176 if err != nil { 177 return err 178 } 179 180 fmt.Printf("%s\n\n", mergeOutput) 181 182 commitOutput, err := git.Commit(git.CommitOpts{Messages: messages}) 183 if err != nil { 184 return err 185 } 186 187 fmt.Println(commitOutput) 188 189 return nil 190 }), 191 } 192 }