diff --git a/gbm-cli/Commands.md b/gbm-cli/Commands.md new file mode 100644 index 0000000..062bc73 --- /dev/null +++ b/gbm-cli/Commands.md @@ -0,0 +1,136 @@ +# `gbn-cli` +## Usage +Use `gbm-cli -h` to see the full list of available commands. + +## Flags +**`-v, -version`** Displays the current version of the tool + +**`-h, --help`** Displays the help menu + +### Commands + +### `completion` +This is automatically added to the command via the cli library used. It will generate a shell auto completion script. Follow [this guide](https://blog.chmouel.com/posts/cobra-completions/#installation) for how to add the auto completion to your shell. + +**Note**: The tool does not implement any custom auto completion and the default generated output has not been tested. + +### `render` + +#### Usage +The `render` command is responsible for generating the checklists that make up the release process. + +#### Flags +**`--c`** - Optional: if set any subcommand will send the output to the system clipboard. Otherwise the result is sent to stdout. + +#### Subcommands + +## `render checklist` + +### Usage +To generate the HTML output for a release checklist, run `checklist` as a subcommand and pass a version number with `-v`: + +``` +gbm-cli render checklist -v 1.106.0 +``` + +The command output can be copied to the clipboard with `--c`: + +``` +gbm-cli render checklist -v 1.106.0 --c +``` + +### Flags +**`-version -v=string`** - Required: This is the release version. If passed a non-zero patch value, the checklist will generate a patch specific checklist. Otherwise the result will be a scheduled checklist. The version must be a full semantic version of the format `X.Y.Z` or `vX.Y.Z`. Short versions which do not include the patch value are not allowed. + +**`-message|-m=string`** - Optional: This is an optional message that will be displayed in a light blue block at the top of the checklist. This is primarily used to explain the reason for a patch release but can also be used for scheduled releases. + +**`-date|-d=string`** - Optional: The `date` option only applies to scheduled releases. It is just an optional string value used to display the release date. If not provided the checklist generator will use the next Thursday from when the script runs + +**`-host-version|-V=string`** Optional: This sets the host app version. It defaults to "X.XX". Currently it is only used to generate the suggested notification message to be shared in the apps infrastructure slack channel. + +**`--a`** - Optional: If set, the checklist generator will check to see if the Aztec versions are correct and will omit the steps to update Aztec. see `aztec` sub command to render the aztec steps in the event the aztec versions are not valid when cutting the release + +--- + +### `release` + +#### Usage +The `release` command is used to create and review releases + +#### Flags +**`--keep`** Optional: Most release commands use a temporary directory which is cleaned up a the end of the command. `--keep` prevents the deletion of the temporary directory. This is useful for development. + +#### Subcommands + +#### `release prepare gb {version}` + +##### Usage +Prepares a release pr on Gutenberg for the version provided. It can be used to create scheduled release or patch releases. A list of pr numbers or commit shas should be provided when creating a patch release. + +Examples: + +Creating a scheduled release +``` +gbm-cli release prepare gb v1.0.0 +``` + +Creating a patch release +``` +gbm-cli release prepare gb v1.0.1 --prs=123,124 +``` + +##### Flags +**`--no-tag`** Optional: Prevents adding the tag to Gutenberg. If provided it will also skip the prompt to add the tag. + +**`--prs=string,string...`** Optional: Comma separated list of PR numbers. Only used for patch releases to cherry pick the merge commit associated with the pull request. + +**`--shas=string,string...`** Optional: Comma separated list of commits. Only used for patch releases to cherry pick commits. + + +#### `release prepare gbm {version}` + +##### Usage +Prepares a release pr on Gutenberg Mobile for the version provided. It can be used to create scheduled release or patch releases. +Examples: + +Creating a scheduled release +``` +gbm-cli release prepare gbm v1.0.0 +``` + +Creating a patch release +``` +gbm-cli release prepare gbm v1.0.1 +``` + +##### Flags + + +#### `release prepare all {version}` + +##### Usage +Prepares both Gutenberg and Gutenberg Mobile release prs. + + +#### `release integrate {version}` + +##### Usage +Create release integration PRs for the provided version. A host version is required if creating a patch version. A release pr will be created on both platforms unless specified by command flags. + +#### Flags +**`--android|-a`** Optional: Specifies that an Android release pr is created. If the `--ios` flag is not set then only the Android pr will be created. + +**`--ios|-i`** Optional: Specifies that an iOS release pr is created. If the `--android` flag is not set then only the iOS pr will be created. + +**`--host-version|-V`** Required for patch releases: The host app version that the release is targeting. + + +#### `release status {version}` + +##### Usage +Outputs the status of the release. + +##### Flags +**`watch`** Optional: Periodically refreshes the status output + +**`--time|-t`** Optional: Delay in seconds between refreshes (default 10) diff --git a/gbm-cli/README.md b/gbm-cli/README.md index ddc17bb..4470241 100644 --- a/gbm-cli/README.md +++ b/gbm-cli/README.md @@ -11,15 +11,19 @@ The current features include: Check the [latest release](https://github.com/wordpress-mobile/release-toolkit-gutenberg-mobile/releases/latest) in this repository for the binary builds. Currently we only build for MacOS arm64 (apple silicon). The script has only been tested on apple silicon but builds of other platforms should work as expected. See the official [go build](https://go.dev/ref/mod#go-install) documentation for alternative builds. -If using apple silicon, download the `gbm-cli` binary from the [latest release](https://github.com/wordpress-mobile/release-toolkit-gutenberg-mobile/releases/latest) -Place the executable in your `$PATH` and reload your shell. Try +If using apple silicon, fetch the `gbm-cli` binary from the [latest release](https://github.com/wordpress-mobile/release-toolkit-gutenberg-mobile/releases/latest) +Note: MacOS is very strict about downloading unsigned binaries. There is a work around to allowing them but the easier route is to use `wget`: ``` -$ gbm-cli --version +$ wget https://github.com/wordpress-mobile/release-toolkit-gutenberg-mobile/releases/latest/download/gbm-cli +chmod +x ./gbm-cli ``` -To verify installation. +Then place the executable in your `$PATH` and reload your shell. To verify installation run: +``` +$ gbm-cli --version +``` If `go` (above version `1.21`) is installed you can also use: @@ -37,7 +41,69 @@ The tool uses the same Github authentication as [`gh`](https://cli.github.com/). Otherwise follow these steps: 1. Create a [personal access token](https://github.blog/2013-05-16-personal-api-tokens/) -2. Export the token under the environment variable `GH_TOKEN` +2. Export the token under the environment variable `GH_TOKEN` or `GITHUB_TOKEN` + +## Commands + +### `gbn-cli` +#### Usage +Use `gbm-cli -h` to see the full list of available commands. + +#### Flags + +**`-v, -version`** Displays the current version of the tool + +**`-h, --help`** Displays the help menu + +### `render` + +#### Usage +The `render` command is responsible for generating the checklists that make up the release process. + +#### Flags + +**`--c`** - Optional: if set any subcommand will send the output to the system clipboard. Otherwise the result is sent to stdout. + +#### Subcommands + +#### `render checklist` + +##### Usage +To generate the HTML output for a release checklist, run `checklist` as a subcommand and pass a version number with `-v`: + +``` +gbm-cli render checklist -v 1.106.0 +``` + +The command output can be copied to the clipboard with `--c`: + +``` +gbm-cli render checklist -v 1.106.0 --c +``` + +##### Flags + +**`-version -v`** - Required: This is the release version. If passed a non-zero patch value, the checklist will generate a patch specific checklist. Otherwise the result will be a scheduled checklist. The version must be a full semantic version of the format `X.Y.Z` or `vX.Y.Z`. Short versions which do not include the patch value are not allowed. + +**`-message|-m `** - Optional: This is an optional message that will be displayed in a light blue block at the top of the checklist. This is primarily used to explain the reason for a patch release but can also be used for scheduled releases. + +**`-date|-d`** - Optional: The `date` option only applies to scheduled releases. It is just an optional string value used to display the release date. If not provided the checklist generator will use the next Thursday from when the script runs + +**`-host-version|-V`** Optional: This sets the host app version. It defaults to "X.XX". Currently it is only used to generate the suggested notification message to be shared in the apps infrastructure slack channel. + +**`--a`** - Optional: If set, the checklist generator will check to see if the Aztec versions are correct and will omit the steps to update Aztec. see `aztec` sub command to render the aztec steps in the event the aztec versions are not valid when cutting the release + + +### `release` + +#### Usage + +#### Flags + +#### Subcommands + + + ## Development Environment 1. Download and install the [Go package](https://go.dev/doc/install). Check `go.mod` for the current version of go required (Note: anything below `v1.21` will not work) diff --git a/gbm-cli/cmd/release/README.md b/gbm-cli/cmd/release/README.md deleted file mode 100644 index 619b546..0000000 --- a/gbm-cli/cmd/release/README.md +++ /dev/null @@ -1,63 +0,0 @@ -# release - -The `release` command is a parent command for running the release process. `release` consists of three subcommands, which represent the three phases of the release flow: - -### prepare -Used to prepare Gutenberg and Gutenberg Mobile PRs for the release. Contains three subcommands: - -- `all`: Prepare both Gutenberg and Gutenberg Mobile PRs release -- `gb`: Prepare Gutenberg PR for a mobile release -- `gbm`: Prepare Gutenberg Mobile PR release - -**Usage** - -Prepare a release for both platforms: - -``` -go run main.go release prepare all v1.107.0 -``` - -Prepare a release for Gutenberg only: - -``` -go run main.go release prepare gb v1.107.0 -``` - -Prepare a release for Gutenberg Mobile only: - -``` -go run main.go release prepare gbm v1.107.0 -``` - - -**Flags:** -- `--k`, `--keep`: Keep temporary directory after running command -- `--no-tag`: Prevent tagging the release -- `-h`, `--help`: Command line help for `prepare` - - -### integrate -Used to integrate a release into the main apps WordPress-iOS and WordPress-Android. If the Android or iOS flags are set, only that platform will be integrated. Otherwise, both will be integrated. - -**Usage** - -After the `prepare` command has been run and the CI has finished, the main apps integration PRs can be created: - -``` -go run main.go release integrate v1.107.0 -``` - -**Flags** -- `-a`, `--android`: Only integrate Android -- `-i`, `--ios`: Only integrate iOS -- `-h`, `--help`: Command line help for `integrate` command - -### status - -Command used to check the status of any given release: - -**Usage** - -``` -go run main.go release status 1.07.0 -``` \ No newline at end of file diff --git a/gbm-cli/cmd/release/integrate.go b/gbm-cli/cmd/release/integrate.go index 366b4d8..bef093a 100644 --- a/gbm-cli/cmd/release/integrate.go +++ b/gbm-cli/cmd/release/integrate.go @@ -16,6 +16,7 @@ import ( ) var android, ios, both bool +var hostVersion string var IntegrateCmd = &cobra.Command{ Use: "integrate", @@ -39,6 +40,14 @@ var IntegrateCmd = &cobra.Command{ GbmPr: gbmPr, } + // If this is a patch release, verify the host version is set and update the integration struct + if semver.IsPatchRelease() { + if hostVersion == "" { + exitIfError(errors.New("host version must be set for patch releases"), 1) + } + ri.BaseBranch = fmt.Sprintf("release/%s", hostVersion) + } + results := []gh.PullRequest{} createAndroidPr := func() { @@ -113,4 +122,5 @@ func init() { tempDir = workspace.Dir() IntegrateCmd.Flags().BoolVarP(&android, "android", "a", false, "Only integrate Android") IntegrateCmd.Flags().BoolVarP(&ios, "ios", "i", false, "Only integrate iOS") + IntegrateCmd.Flags().StringVarP(&hostVersion, "host-version", "V", "", "host app version") } diff --git a/gbm-cli/cmd/release/prepare/README.md b/gbm-cli/cmd/release/prepare/README.md deleted file mode 100644 index 2d46fa4..0000000 --- a/gbm-cli/cmd/release/prepare/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# prepare - -The `prepare` command is responsible for generating the pull requests that make up the release process. - -Contains three subcommands: - -- `all`: Prepare both Gutenberg and Gutenberg Mobile PRs release -- `gb`: Prepare Gutenberg PR for a mobile release -- `gbm`: Prepare Gutenberg Mobile PR release - -### Usage - -Prepare a release for both platforms: - -``` -go run main.go release prepare all v1.107.0 -``` - -Prepare a release for Gutenberg only: - -``` -go run main.go release prepare gb v1.107.0 -``` - -Prepare a release for Gutenberg Mobile only: - -``` -go run main.go release prepare gbm v1.107.0 -``` diff --git a/gbm-cli/cmd/release/prepare/all.go b/gbm-cli/cmd/release/prepare/all.go index f95d911..462dd9b 100644 --- a/gbm-cli/cmd/release/prepare/all.go +++ b/gbm-cli/cmd/release/prepare/all.go @@ -36,6 +36,7 @@ var allCmd = &cobra.Command{ Dir: gbDir, Version: version, UseTag: !noTag, + Repo: "gutenberg", Base: gh.Repo{ Ref: "trunk", }, @@ -61,6 +62,7 @@ var allCmd = &cobra.Command{ Base: gh.Repo{ Ref: "trunk", }, + Repo: "gutenberg-mobile", } if isPatch { diff --git a/gbm-cli/cmd/release/prepare/root.go b/gbm-cli/cmd/release/prepare/root.go index 44421e9..1334a0f 100644 --- a/gbm-cli/cmd/release/prepare/root.go +++ b/gbm-cli/cmd/release/prepare/root.go @@ -18,7 +18,7 @@ var keepTempDir, noTag bool var workspace wp.Workspace var tempDir string var version semver.SemVer -var prs []string +var prs, shas []string var PrepareCmd = &cobra.Command{ Use: "prepare", @@ -66,23 +66,26 @@ func init() { PrepareCmd.PersistentFlags().BoolVar(&keepTempDir, "keep", false, "Keep temporary directory after running command") PrepareCmd.PersistentFlags().BoolVar(&noTag, "no-tag", false, "Prevent tagging the release") PrepareCmd.PersistentFlags().StringSliceVar(&prs, "prs", []string{}, "prs to include in the release. Only used with patch releases") + PrepareCmd.PersistentFlags().StringSliceVar(&shas, "shas", []string{}, "shas to include in the release. Only used with patch releases") } func setupPatchBuild(tagName string, build *release.Build) { tag, err := gh.GetTag(build.Repo, tagName) exitIfError(err, 1) - + build.Depth = "--shallow-since=" + tag.Date build.Base = gh.Repo{Ref: tagName} // We don't usually pick prs from Gutenberg Mobile for patch releases if len(prs) != 0 { build.Prs = gh.GetPrs("gutenberg", prs) - build.Depth = "--shallow-since=" + tag.Date - if len(build.Prs) == 0 { exitIfError(errors.New("no PRs found for patch release"), 1) return } } + + if len(shas) != 0 { + build.Shas = shas + } } diff --git a/gbm-cli/cmd/render/README.md b/gbm-cli/cmd/render/README.md index 251d3be..174d352 100644 --- a/gbm-cli/cmd/render/README.md +++ b/gbm-cli/cmd/render/README.md @@ -2,23 +2,44 @@ The `render` command is responsible for generating the checklists that make up the release process. -### Usage -For further CLI usage information on render, run `go run main.go render -h` from the `cli` directory. +## Usage +For further CLI usage information on render, run `gbm-cli render -h`. Currently, `render` supports 2 subcommands: `checklist` and `aztec`: -#### `checklist` +## Flags + +**`--c`** - Optional: if set any subcommand will send the output to the system clipboard. Otherwise the result is sent to stdout. + +### `checklist` + +#### Flags + +**`-version -v`** - Required: This is the release version. If passed a non-zero patch value, the checklist will generate a patch specific checklist. Otherwise the result will be a scheduled checklist. The version must be a full semantic version of the format `X.Y.Z` or `vX.Y.Z`. Short versions which do not include the patch value are not allowed. + +**`-message|-m `** - Optional: This is an optional message that will be displayed in a light blue block at the top of the checklist. This is primarily used to explain the reason for a patch release but can also be used for scheduled releases. + +**`-date|-d`** - Optional: The `date` option only applies to scheduled releases. It is just an optional string value used to display the release date. If not provided the checklist generator will use the next Thursday from when the script runs. + +**`-host-version|-V`** Optional: This sets the host app version. It defaults to "X.XX". Currently it is only used to generate the suggested notification message to be shared in the apps infrastructure slack channel. + +**`--a`** - Optional: If set, the checklist generator will check to see if the Aztec versions are correct and will omit the steps to update Aztec. see `aztec` sub command to render the aztec steps in the event the aztec versions are not valid when cutting the release + + +#### Usage To generate the HTML output for a release checklist, run `checklist` as a subcommand and pass a version number with `-v`: ``` -go run main.go render checklist -v 1.106.0 +gbm-cli render checklist -v 1.106.0 ``` The command output can be copied to the clipboard with `--c`: ``` -go run main.go render checklist -v 1.106.0 --c +gbm-cli render checklist -v 1.106.0 --c ``` -#### `aztec` -In most release scenarios, Aztec is not updated. The result is that the "Update Aztec" steps are considered conditional and usually left unchecked. By default, the `checklist`` command keeps the conditional steps. However, there is a flag that changes this behavior: adding `--a` to the `checklist` command will remove the conditional Aztec section. It also makes the script reach out to the relevant Aztec configs to see if a release version is required. In this case, the checklist command will add the Aztec steps to the checklist but right after the "Before the Release" section, and also add a warning message about updating Aztec. \ No newline at end of file + +### `aztec` + +In most release scenarios, Aztec is not updated. The result is that the "Update Aztec" steps are considered conditional and usually left unchecked. By default, the `checklist` command keeps the conditional steps. However, there is a flag that changes this behavior: adding `--a` to the `checklist` command will remove the conditional Aztec section. It also makes the script reach out to the relevant Aztec configs to see if a release version is required. In this case, the checklist command will add the Aztec steps to the checklist but right after the "Before the Release" section, and also add a warning message about updating Aztec. \ No newline at end of file diff --git a/gbm-cli/pkg/release/gb.go b/gbm-cli/pkg/release/gb.go index 7ada822..d8af162 100644 --- a/gbm-cli/pkg/release/gb.go +++ b/gbm-cli/pkg/release/gb.go @@ -55,56 +55,34 @@ func CreateGbPR(build Build) (gh.PullRequest, error) { } if isPatch { - // We probably won't create a patch release with out PRS to cherry pick but - // for testing this is useful to allow and to skip. + err := git.Fetch("trunk", build.Depth) + if err != nil { + return pr, fmt.Errorf("error fetching the Gutenberg repository: %v", err) + } + if len(build.Prs) != 0 { console.Info("Cherry picking PRs") - err := git.Fetch("trunk", build.Depth) - if err != nil { - return pr, fmt.Errorf("error fetching the Gutenberg repository: %v", err) - } - for _, pr := range build.Prs { if pr.MergeCommit == "" { return pr, fmt.Errorf("error cherry picking PR %d: no merge commit", pr.Number) } console.Info("Cherry picking PR %d via commit %s", pr.Number, pr.MergeCommit) + if err := cherryPickCommit(git, dir, pr.MergeCommit); err != nil { + return pr, fmt.Errorf("error cherry picking PR %d: %v", pr.Number, err) + } + } + } - if err := git.CherryPick(pr.MergeCommit); err != nil { - - console.Print(console.Highlight, "\nThere was an issue cherry picking PR #%d", pr.Number) - conflicts, err := git.StatConflicts() - if len(conflicts) == 0 { - return pr, fmt.Errorf("error cherry picking PR %d: %v", pr.Number, err) - } - console.Print(console.HeadingRow, "\nThe conflict can be resolved by inspecting the following files:") - - if err != nil { - return pr, fmt.Errorf("error getting the list of conflicting files: %v", err) - } - for _, file := range conflicts { - console.Print(console.Row, "• "+filepath.Join(dir, file)) - } - - if err := openInEditor(dir, conflicts); err != nil { - console.Warn("There was an issue opening the conflicting files in your editor: %v", err) - } - - fixed := console.Confirm("Continue after resolving the conflict?") - - if fixed { - err := git.CherryPick("--continue") - if err != nil { - return pr, fmt.Errorf("error continuing the cherry pick: %v", err) - } - } else { - return pr, fmt.Errorf("error cherry picking PR %d: %v", pr.Number, err) - } + if len(build.Shas) != 0 { + console.Info("Cherry picking SHAs") + for _, sha := range build.Shas { + console.Info("Cherry picking SHA %s", sha) + if err := cherryPickCommit(git, dir, sha); err != nil { + return pr, fmt.Errorf("error cherry picking SHA %s: %v", sha, err) } } - } else { - console.Warn("No PRs to cherry pick") } + } console.Info("Updating package versions") @@ -127,23 +105,21 @@ func CreateGbPR(build Build) (gh.PullRequest, error) { return pr, fmt.Errorf("error updating the CHANGELOG: %v", err) } - // If this is a patch release we should prompt for the wrangler to manually update the change log if isPatch { - - console.Print(console.Highlight, "\nSince this is a patch release manually update the CHANGELOG") var prNumbers string for _, pr := range build.Prs { prNumbers += fmt.Sprintf("#%d ", pr.Number) } console.Print(console.Highlight, "Note: We just cherry picked these PRs: %s", prNumbers) + } + console.Info("Here are the proposed changes to the CHANGELOG:\n") + git.Diff("-U0", chnPath) + if err := openInEditor(dir, []string{chnPath}); err != nil { + console.Warn("There was an issue opening the CHANGELOG in your editor: %v", err) + } - if err := openInEditor(dir, []string{filepath.Join("packages", "react-native-editor", "CHANGELOG.md")}); err != nil { - console.Warn("There was an issue opening the CHANGELOG in your editor: %v", err) - } - - if cont := console.Confirm("Do you wish to continue after updating the CHANGELOG?"); !cont { - return pr, fmt.Errorf("exiting before creating PR, Stopping at CHANGELOG update") - } + if cont := console.Confirm("Do you wish to continue after updating the CHANGELOG?"); !cont { + return pr, fmt.Errorf("exiting before creating PR, Stopping at CHANGELOG update") } if err := git.CommitAll("Release script: Update CHANGELOG for version %s", version); err != nil { @@ -222,9 +198,12 @@ func CreateGbPR(build Build) (gh.PullRequest, error) { } if build.UseTag { - console.Info("Adding release tag") - if err := git.PushTag("rnmobile/" + version); err != nil { - console.Warn("Error tagging the release: %v", err) + tag := console.Confirm("Do you wish to tag the release now?") + if tag { + console.Info("Adding release tag") + if err := git.PushTag("rnmobile/" + version); err != nil { + console.Warn("Error tagging the release: %v", err) + } } } else { console.Warn("Skipping tag creation") @@ -252,3 +231,38 @@ func renderGbPrBody(version string, pr *gh.PullRequest) error { pr.Body = body return nil } + +func cherryPickCommit(git shell.GitCmds, dir, sha string) error { + if err := git.CherryPick(sha); err != nil { + + console.Print(console.Highlight, "\nThere was an issue cherry picking commit #%d", sha) + conflicts, err := git.StatConflicts() + if len(conflicts) == 0 { + return fmt.Errorf("error cherry picking commit %d: %v", sha, err) + } + console.Print(console.HeadingRow, "\nThe conflict can be resolved by inspecting the following files:") + + if err != nil { + return fmt.Errorf("error getting the list of conflicting files: %v", err) + } + for _, file := range conflicts { + console.Print(console.Row, "• "+filepath.Join(dir, file)) + } + + if err := openInEditor(dir, conflicts); err != nil { + console.Warn("There was an issue opening the conflicting files in your editor: %v", err) + } + + fixed := console.Confirm("Continue after resolving the conflict?") + + if fixed { + err := git.CherryPick("--continue") + if err != nil { + return fmt.Errorf("error continuing the cherry pick: %v", err) + } + } else { + return fmt.Errorf("error cherry picking commit %d: %v", sha, err) + } + } + return nil +} diff --git a/gbm-cli/pkg/release/main.go b/gbm-cli/pkg/release/main.go index dc75555..2d53a2b 100644 --- a/gbm-cli/pkg/release/main.go +++ b/gbm-cli/pkg/release/main.go @@ -11,6 +11,7 @@ type Build struct { UseTag bool Repo string Prs []gh.PullRequest + Shas []string Base gh.Repo Depth string } diff --git a/gbm-cli/pkg/release/search.go b/gbm-cli/pkg/release/search.go index 51889f2..2168bd3 100644 --- a/gbm-cli/pkg/release/search.go +++ b/gbm-cli/pkg/release/search.go @@ -10,7 +10,7 @@ import ( func FindGbReleasePr(version string) (gh.PullRequest, error) { label := fmt.Sprintf("label:\"%s\"", GbReleasePrLabel) title := fmt.Sprintf("v%s in:title", version) - filter := gh.BuildRepoFilter(repo.GutenbergRepo, "is:pr", label, title) + filter := gh.BuildRepoFilter(repo.GutenbergRepo, "is:pr", "is:open", label, title) pr, err := gh.SearchPr(filter) if err != nil { @@ -24,7 +24,7 @@ func FindGbmReleasePr(version string) (gh.PullRequest, error) { label := fmt.Sprintf("label:%s", GbmReleasePrLabel) title := fmt.Sprintf("%s in:title", version) - filter := gh.BuildRepoFilter(repo.GutenbergMobileRepo, "is:pr", label, title) + filter := gh.BuildRepoFilter(repo.GutenbergMobileRepo, "is:pr", "is:open", label, title) pr, err := gh.SearchPr(filter) if err != nil { return gh.PullRequest{}, err diff --git a/gbm-cli/pkg/shell/git.go b/gbm-cli/pkg/shell/git.go index 75a7869..c81d7af 100644 --- a/gbm-cli/pkg/shell/git.go +++ b/gbm-cli/pkg/shell/git.go @@ -24,6 +24,7 @@ type GitCmds interface { Log(...string) error CherryPick(string) error StatConflicts() ([]string, error) + Diff(...string) error } func (c *client) Clone(args ...string) error { @@ -106,6 +107,11 @@ func (c *client) Log(args ...string) error { return c.cmd(log...) } +func (c *client) Diff(args ...string) error { + diff := append([]string{"diff"}, args...) + return c.cmd(diff...) +} + func (c *client) CherryPick(commitOrContinue string) error { if commitOrContinue == "--continue" { c.cmd("add", "--all")