From 76b656dcc5108b513468465dc9d29532fc24e049 Mon Sep 17 00:00:00 2001 From: Danny Ranson Date: Fri, 3 Nov 2023 12:05:06 +0000 Subject: [PATCH 1/5] add PR review note to readme template --- cmd/init/templates/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/init/templates/README.md b/cmd/init/templates/README.md index bfde24b..543eba8 100644 --- a/cmd/init/templates/README.md +++ b/cmd/init/templates/README.md @@ -2,6 +2,8 @@ TODO: This file will serve as both a README and the description of the PR. Describe the pull request using markdown in this file. Make it clear why the change is being made, and make suggestions for anything that the reviewer may need to do. +By approving this PR, you are confirming that you have adequately and effectively reviewed this change. + ## How this change was made TODO: Describe the approach that was used to select repositories for this change TODO: Describe any shell commands, scripts, manual operations, etc, that were used to make changes From b52d2aacaacb41938d0a5e54ca438a78eebfa8aa Mon Sep 17 00:00:00 2001 From: Danny Ranson Date: Fri, 3 Nov 2023 12:17:46 +0000 Subject: [PATCH 2/5] add custom pr description option --- cmd/create_prs/create_prs.go | 11 +++++++---- internal/campaign/campaign.go | 19 +++++++++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/cmd/create_prs/create_prs.go b/cmd/create_prs/create_prs.go index c50905e..4f58e3a 100644 --- a/cmd/create_prs/create_prs.go +++ b/cmd/create_prs/create_prs.go @@ -35,9 +35,10 @@ var ( ) var ( - isDraft bool - repoFile string - sleep time.Duration + isDraft bool + repoFile string + prDescriptionFile string + sleep time.Duration ) func NewCreatePRsCmd() *cobra.Command { @@ -50,6 +51,7 @@ func NewCreatePRsCmd() *cobra.Command { cmd.Flags().DurationVar(&sleep, "sleep", 0, "Fixed sleep in between PR creations (to spread load on CI infrastructure)") cmd.Flags().BoolVar(&isDraft, "draft", false, "Creates the Pull Request as Draft PR") cmd.Flags().StringVar(&repoFile, "repos", "repos.txt", "A file containing a list of repositories to clone.") + cmd.Flags().StringVar(&prDescriptionFile, "description", "README.md", "A file containing the title and description for the PRs.") return cmd } @@ -57,9 +59,10 @@ func NewCreatePRsCmd() *cobra.Command { func run(c *cobra.Command, _ []string) { logger := logging.NewLogger(c) - readCampaignActivity := logger.StartActivity("Reading campaign data (%s)", repoFile) + readCampaignActivity := logger.StartActivity("Reading campaign data (%s, %s)", repoFile, prDescriptionFile) options := campaign.NewCampaignOptions() options.RepoFilename = repoFile + options.PrDescriptionFilename = prDescriptionFile dir, err := campaign.OpenCampaign(options) if err != nil { readCampaignActivity.EndWithFailure(err) diff --git a/internal/campaign/campaign.go b/internal/campaign/campaign.go index 22a8c21..f1f50f6 100644 --- a/internal/campaign/campaign.go +++ b/internal/campaign/campaign.go @@ -44,11 +44,15 @@ func (r Repo) FullRepoPath() string { } type CampaignOptions struct { - RepoFilename string + RepoFilename string + PrDescriptionFilename string } func NewCampaignOptions() *CampaignOptions { - return &CampaignOptions{RepoFilename: "repos.txt"} + return &CampaignOptions{ + RepoFilename: "repos.txt", + PrDescriptionFilename: "README.md", + } } func OpenCampaign(options *CampaignOptions) (*Campaign, error) { @@ -60,7 +64,7 @@ func OpenCampaign(options *CampaignOptions) (*Campaign, error) { return nil, err } - prTitle, prBody, err := readPrDescriptionFile() + prTitle, prBody, err := readPrDescriptionFile(options.PrDescriptionFilename) if err != nil { return nil, err } @@ -131,10 +135,13 @@ func readReposTxtFile(filename string) ([]Repo, error) { return repos, nil } -func readPrDescriptionFile() (string, string, error) { - file, err := os.Open("README.md") +func readPrDescriptionFile(filename string) (string, string, error) { + if filename == "" { + return "", "", errors.New("no PR description file to open") + } + file, err := os.Open(filename) if err != nil { - return "", "", errors.New("unable to open README.md file") + return "", "", fmt.Errorf("unable to open PR description file: %s", filename) } defer func() { closeErr := file.Close() From 452251610bc522bde915dfaded24ae9f7ce871b6 Mon Sep 17 00:00:00 2001 From: Danny Ranson Date: Fri, 3 Nov 2023 12:44:14 +0000 Subject: [PATCH 3/5] test custom pr description file --- internal/campaign/campaign_test.go | 34 ++++++++++++++++++++++++++++- internal/testsupport/testsupport.go | 9 ++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/internal/campaign/campaign_test.go b/internal/campaign/campaign_test.go index c347e9f..dda18d6 100644 --- a/internal/campaign/campaign_test.go +++ b/internal/campaign/campaign_test.go @@ -218,7 +218,39 @@ func TestItShouldAcceptADifferentRepoFileNotExist(t *testing.T) { func TestItShouldErrorWhenRepoFileIsEmpty(t *testing.T) { testsupport.PrepareTempCampaign(false) - options := &CampaignOptions{} + options := NewCampaignOptions() + options.RepoFilename = "" + _, err := OpenCampaign(options) + assert.Error(t, err) +} + +func TestItShouldAcceptADifferentPrDescriptionFile(t *testing.T) { + testsupport.PrepareTempCampaign(false) + + testsupport.CreateAnotherPrDescriptionFile("newprdescription.txt", "new PR title", "new PR body") + options := NewCampaignOptions() + options.PrDescriptionFilename = "newprdescription.txt" + campaign, err := OpenCampaign(options) + assert.NoError(t, err) + + assert.Equal(t, "new PR title", campaign.PrTitle) + assert.Equal(t, "new PR body", campaign.PrBody) +} + +func TestItShouldErrorWhenPrDescriptionFileDoesNotExist(t *testing.T) { + testsupport.PrepareTempCampaign(false) + + options := NewCampaignOptions() + options.PrDescriptionFilename = "newprdescription.txt" + _, err := OpenCampaign(options) + assert.Error(t, err) +} + +func TestItShouldErrorWhenPrDescriptionFileNameIsEmpty(t *testing.T) { + testsupport.PrepareTempCampaign(false) + + options := NewCampaignOptions() + options.PrDescriptionFilename = "" _, err := OpenCampaign(options) assert.Error(t, err) } diff --git a/internal/testsupport/testsupport.go b/internal/testsupport/testsupport.go index 60c82c2..fab85be 100644 --- a/internal/testsupport/testsupport.go +++ b/internal/testsupport/testsupport.go @@ -16,6 +16,7 @@ package testsupport import ( + "fmt" "io/ioutil" "os" "path" @@ -72,3 +73,11 @@ func CreateAnotherRepoFile(filename string, repos ...string) { panic(err) } } + +func CreateAnotherPrDescriptionFile(filename string, prTitle string, prBody string) { + prDescription := fmt.Sprintf("# %s\n%s", prTitle, prBody) + err := os.WriteFile(filename, []byte(prDescription), os.ModePerm|0o644) + if err != nil { + panic(err) + } +} From fe458531c055482a1f06c64bc5b2d90ba6780bfe Mon Sep 17 00:00:00 2001 From: Danny Ranson Date: Fri, 3 Nov 2023 15:38:16 +0000 Subject: [PATCH 4/5] update readme --- README.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index fabf73c..382b5df 100644 --- a/README.md +++ b/README.md @@ -172,12 +172,14 @@ Use `turbolift create-prs --sleep 30s` to, for example, force a 30s pause betwee > * create PRs in batches, for example by commenting out repositories in `repos.txt` > * Use the `--draft` flag to create the PRs as Draft -If you need to mass-close PRs, it is easy to do using `turbolift foreach` and the `gh` GitHub CLI ([docs](https://cli.github.com/manual/gh_pr_close)): +#### Working with multiple PR description files -For example: +Occasionally you may want to work with more than one PR title and description. When this is the case, use the flag `--description` to specify an alternative file when creating prs. +The first line of the file chosen will be used as the PR title and the rest as the description body. -``` -turbolift foreach gh pr close --delete-branch YOUR_USERNAME:CAMPAIGN_NAME +```console +turbolift create-prs --repos repoFile1.txt --description prDescriptionFile1.md +turbolift create-prs --repos repoFile2.txt --description prDescriptionFile2.md ``` ### After creating PRs From 50db77896582ff72b9fd5daa5e34bcd0653257f2 Mon Sep 17 00:00:00 2001 From: Danny Ranson Date: Thu, 30 Nov 2023 10:53:33 +0000 Subject: [PATCH 5/5] add custom file to error message --- internal/campaign/campaign.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/campaign/campaign.go b/internal/campaign/campaign.go index f1f50f6..e5f6490 100644 --- a/internal/campaign/campaign.go +++ b/internal/campaign/campaign.go @@ -165,7 +165,7 @@ func readPrDescriptionFile(filename string) (string, string, error) { } if err := scanner.Err(); err != nil { - return "", "", errors.New("unable to read README.md file") + return "", "", fmt.Errorf("unable to read PR description file: %s", filename) } return prTitle, strings.Join(prBodyLines, "\n"), nil