// postAssignedReviewRequest can be used to post // the commits associated with the given story for review. func postAssignedReviewRequest( config *moduleConfig, owner string, repo string, story common.Story, commits []*git.Commit, opts map[string]interface{}, ) (*github.Issue, []*git.Commit, error) { // Search for an existing review issue for the given story. task := fmt.Sprintf("Search for an existing review issue for story %v", story.ReadableId()) log.Run(task) client := ghutil.NewClient(config.Token) issue, err := ghissues.FindReviewIssueForStory(client, owner, repo, story.ReadableId()) if err != nil { return nil, nil, errs.NewError(task, err) } // Decide what to do next based on the search results. if issue == nil { // No review issue found for the given story, create a new issue. issue, err := createAssignedReviewRequest(config, owner, repo, story, commits, opts) if err != nil { return nil, nil, err } return issue, commits, nil } // An existing review issue found, extend it. return extendReviewRequest(config, owner, repo, issue, commits, opts) }
// createAssignedReviewRequest can be used to create a new review issue // for the given commits that is associated with the story passed in. func createAssignedReviewRequest( config *moduleConfig, owner string, repo string, story common.Story, commits []*git.Commit, opts map[string]interface{}, ) (*github.Issue, error) { task := fmt.Sprintf("Create review issue for story %v", story.ReadableId()) // Prepare the issue object. reviewIssue := ghissues.NewStoryReviewIssue( story.ReadableId(), story.URL(), story.Title(), story.IssueTracker().ServiceName(), story.Tag()) for _, commit := range commits { reviewIssue.AddCommit(false, commit.SHA, commit.MessageTitle) } // Get the right review milestone to add the issue into. milestone, err := getOrCreateMilestoneForCommit( config, owner, repo, commits[len(commits)-1].SHA) if err != nil { return nil, errs.NewError(task, err) } // Create a new review issue. var implemented bool implementedOpt, ok := opts["implemented"] if ok { implemented = implementedOpt.(bool) } issue, err := createIssue( task, config, owner, repo, reviewIssue.FormatTitle(), reviewIssue.FormatBody(), optValueString(opts["reviewer"]), milestone, implemented) if err != nil { return nil, errs.NewError(task, err) } return issue, nil }
// postAssignedReviewRequest can be used to post // the commits associated with the given story for review. func postAssignedReviewRequest( config Config, owner string, repo string, story common.Story, commits []*git.Commit, opts map[string]interface{}, ) error { // Search for an existing review issue for the given story. task := fmt.Sprintf("Search for an existing review issue for story %v", story.ReadableId()) log.Run(task) query := fmt.Sprintf( "\"Review story %v\" repo:%v/%v label:%v type:issue in:title", story.ReadableId(), owner, repo, config.ReviewLabel()) client := ghutil.NewClient(config.Token()) result, _, err := client.Search.Issues(query, &github.SearchOptions{}) if err != nil { return errs.NewError(task, err) } // Decide what to do next based on the search results. switch len(result.Issues) { case 0: // No review issue found for the given story, create a new issue. return createAssignedReviewRequest(config, owner, repo, story, commits, opts) case 1: // An existing review issue found, extend it. return extendReviewRequest(config, owner, repo, &result.Issues[0], commits, opts) default: // Multiple review issue found for the given story, that is clearly wrong // since there is always just a single review issue for every story. err := errors.New("inconsistency detected: multiple story review issues found") return errs.NewError("Make sure the review issue can be created", err) } }
// createAssignedReviewRequest can be used to create a new review issue // for the given commits that is associated with the story passed in. func createAssignedReviewRequest( config Config, owner string, repo string, story common.Story, commits []*git.Commit, opts map[string]interface{}, ) error { var ( task = fmt.Sprintf("Create review issue for story %v", story.ReadableId()) issueTitle = fmt.Sprintf("Review story %v: %v", story.ReadableId(), story.Title()) ) // Generate the issue body. var issueBody bytes.Buffer fmt.Fprintf(&issueBody, "Story being reviewed: [%v](%v)\n\n", story.ReadableId(), story.URL()) fmt.Fprintf(&issueBody, "SF-Issue-Tracker: %v\n", story.IssueTracker().ServiceName()) fmt.Fprintf(&issueBody, "SF-Story-Key: %v\n\n", story.Tag()) fmt.Fprintf(&issueBody, "The associated commits are following:") for _, commit := range commits { fmt.Fprintf(&issueBody, "\n- [ ] %v: %v", commit.SHA, commit.MessageTitle) } // Get the right review milestone to add the issue into. milestone, err := getOrCreateMilestoneForCommit( config, owner, repo, commits[len(commits)-1].SHA) if err != nil { return err } // Create a new review issue. issue, err := createIssue(task, config, owner, repo, issueTitle, issueBody.String(), milestone) if err != nil { return err } // Open the issue if requested. if _, open := opts["open"]; open { return openIssue(issue) } return nil }