Skip to content

Commit

Permalink
Cli/gbm patch (#214)
Browse files Browse the repository at this point in the history
* Remove version funcs from utils

* Don't cast semver to string too quickly

* Use struct to build gb and gbm prs

* Add prs to gb build

* return a semver stuct from PriorVerion

* Add base to pr build struct

* Get basic pr cherry-picking working

* Use the tag to create a shallow clone

* Add the dir to the command client struct

* Add prompts to manually resolve conflicts and edit changelog

* Dont prompt to resovle a conflict if there are no conflicts

* Remove debug logs

* Clean up console prompts

* Guard against the commit not being available locally

* use 'keep' instead of 'k' to keep the temp directory

* print out files that are not opened

* Fix regression in 'all' command

* Fix regression in 'gbm' command

* Add repo to build struct

* Generalize the create patch function

* update preview function to handle grafted branches

* Skip cherry pick set up if there are no prs

This is mostly for local testing

* Update gbm release to handle patches

* Fix how nvm installs node

* Update all command to handle patches

* Go back to using the gh package preview PR function

* add binary
  • Loading branch information
jhnstn authored Nov 8, 2023
1 parent 11cbc24 commit c4126c4
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 82 deletions.
Binary file modified gbm-cli/bin/gbm
Binary file not shown.
17 changes: 17 additions & 0 deletions gbm-cli/cmd/release/prepare/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ var allCmd = &cobra.Command{
},
}

isPatch := version.IsPatchRelease()

if isPatch {
console.Info("Preparing a patch releases")
tagName := "rnmobile/" + version.PriorVersion().String()
setupPatchBuild(tagName, &build)
}

gbPr, err = release.CreateGbPR(build)
exitIfError(err, 1)
console.Info("Finished preparing Gutenberg PR")
Expand All @@ -50,7 +58,16 @@ var allCmd = &cobra.Command{
build = release.Build{
Dir: gbmDir,
Version: version,
Base: gh.Repo{
Ref: "trunk",
},
}

if isPatch {
tagName := version.PriorVersion().Vstring()
setupPatchBuild(tagName, &build)
}

pr, err := release.CreateGbmPR(build)
exitIfError(err, 1)
console.Info("Finished preparing Gutenberg Mobile PR")
Expand Down
4 changes: 3 additions & 1 deletion gbm-cli/cmd/release/prepare/gb.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@ var gbCmd = &cobra.Command{
Dir: tempDir,
Version: version,
UseTag: !noTag,
Repo: "gutenberg",
Base: gh.Repo{
Ref: "trunk",
},
}

if version.IsPatchRelease() {
console.Info("Preparing a patch release")
setupPatchBuild(&build)
tagName := "rnmobile/" + version.PriorVersion().String()
setupPatchBuild(tagName, &build)
}

console.Info("Preparing Gutenberg for release %s", version)
Expand Down
7 changes: 7 additions & 0 deletions gbm-cli/cmd/release/prepare/gbm.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ var gbmCmd = &cobra.Command{
Base: gh.Repo{
Ref: "trunk",
},
Repo: "gutenberg-mobile",
}

if version.IsPatchRelease() {
console.Info("Preparing a patch release")
tagName := version.PriorVersion().Vstring()
setupPatchBuild(tagName, &build)
}

pr, err := release.CreateGbmPR(build)
Expand Down
23 changes: 12 additions & 11 deletions gbm-cli/cmd/release/prepare/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,20 +68,21 @@ func init() {
PrepareCmd.PersistentFlags().StringSliceVar(&prs, "prs", []string{}, "prs to include in the release. Only used with patch releases")
}

func setupPatchBuild(build *release.Build) {
func setupPatchBuild(tagName string, build *release.Build) {

// Get the ref to the prior release
priorVersion := version.PriorVersion()

tag, err := gh.GetTag("gutenberg", "rnmobile/"+priorVersion.String())
tag, err := gh.GetTag(build.Repo, tagName)
exitIfError(err, 1)

build.Base = gh.Repo{Ref: "rnmobile/" + priorVersion.String()}
build.Prs = gh.GetPrs("gutenberg", prs)
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(build.Prs) == 0 {
exitIfError(errors.New("no PRs found for patch release"), 1)
return
}
}
}
6 changes: 4 additions & 2 deletions gbm-cli/pkg/gh/gh.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ func labelRequest(rpo string, prNum int, labels []string) ([]Label, error) {
return resp, nil
}

func PreviewPr(rpo, dir string, pr PullRequest) {
func PreviewPr(rpo, dir, branchFrom string, pr PullRequest) {
org := repo.GetOrg(rpo)
row := console.Row

Expand All @@ -441,11 +441,13 @@ func PreviewPr(rpo, dir string, pr PullRequest) {
white := color.New(color.FgWhite).SprintFunc()

console.Print(row, "Repo: %s/%s", white(org), white(rpo))
console.Print(row, "Base: %s", white(pr.Base.Ref))
console.Print(row, "Head: %s", white(pr.Head.Ref))
console.Print(row, "Title: %s", white(pr.Title))
console.Print(row, "Body:\n%s", white(pr.Body))
console.Print(row, "Commits:")

git := shell.NewGitCmd(shell.CmdProps{Dir: dir, Verbose: true})

git.Log(pr.Base.Ref+"...HEAD", "--oneline", "--no-merges", "-10")
git.Log(branchFrom+"...HEAD", "--oneline", "--no-merges", "-10")
}
74 changes: 40 additions & 34 deletions gbm-cli/pkg/release/gb.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,49 +55,55 @@ func CreateGbPR(build Build) (gh.PullRequest, error) {
}

if isPatch {
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)
// 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.
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)
}
console.Info("Cherry picking PR %d via commit %s", pr.Number, pr.MergeCommit)

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))
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 := openInEditor(dir, conflicts); err != nil {
console.Warn("There was an issue opening the conflicting files in your editor: %v", err)
}
if err := git.CherryPick(pr.MergeCommit); err != nil {

fixed := console.Confirm("Continue after resolving the conflict?")
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 fixed {
err := git.CherryPick("--continue")
if err != nil {
return pr, fmt.Errorf("error continuing the cherry pick: %v", err)
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)
}
} else {
return pr, fmt.Errorf("error cherry picking PR %d: %v", pr.Number, err)
}
}
} else {
console.Warn("No PRs to cherry pick")
}
}

Expand Down Expand Up @@ -194,7 +200,7 @@ func CreateGbPR(build Build) (gh.PullRequest, error) {
},
}

previewPr("gutenberg", dir, build.Base.Ref, pr)
gh.PreviewPr("gutenberg", dir, build.Base.Ref, pr)

prompt := fmt.Sprintf("\nReady to create the PR on %s/gutenberg?", org)
cont := console.Confirm(prompt)
Expand Down
31 changes: 19 additions & 12 deletions gbm-cli/pkg/release/gbm.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ func CreateGbmPR(build Build) (gh.PullRequest, error) {
return pr, nil
} else {
console.Info("Cloning Gutenberg Mobile to %s", dir)
err := git.Clone(repo.GetRepoPath("gutenberg-mobile"), "--depth=1", "--recursive", ".")
err := git.Clone(repo.GetRepoPath("gutenberg-mobile"), "--branch", build.Base.Ref, "--depth=1", "--recursive", ".")
if err != nil {
return pr, fmt.Errorf("error cloning the Gutenberg Mobile repository: %v", err)
}

console.Info("Checking out branch %s", branch)
console.Info("Setting up the branch %s", branch)
err = git.Switch("-c", branch)
if err != nil {
return pr, fmt.Errorf("error checking out the branch: %v", err)
return pr, fmt.Errorf("error switching to the branch: %v", err)
}
}

Expand Down Expand Up @@ -92,14 +92,9 @@ func CreateGbmPR(build Build) (gh.PullRequest, error) {
return pr, fmt.Errorf("error running npm run bundle: %v", err)
}

// Commit the updated Gutenberg submodule ref
if git.IsPorcelain() {
console.Info("Nothing to commit after bundling")
} else {
// Commit the updated bundle output
if err := git.CommitAll("Release script: Update bundle for %s", version); err != nil {
return pr, fmt.Errorf("error committing the bundle update: %v", err)
}
// Commit the updated strings
if err := git.CommitAll("Release script: Update i18n files for %s", version); err != nil {
return pr, fmt.Errorf("error committing the bundle update: %v", err)
}

if err := updateXcFramework(version, dir, git); err != nil {
Expand All @@ -112,6 +107,18 @@ func CreateGbmPR(build Build) (gh.PullRequest, error) {
if err := UpdateReleaseNotes(version, chnPath); err != nil {
return pr, fmt.Errorf("error updating the release notes: %v", err)
}
// If this is a patch release we should prompt for the wrangler to manually update the release notes
if build.Version.IsPatchRelease() {
console.Print(console.Highlight, "\nSince this is a patch release manually update the release notes")

if err := openInEditor(dir, []string{"RELEASE-NOTES.txt"}); err != nil {
console.Warn("There was an issue opening RELEASE-NOTES.txt in your editor: %v", err)
}

if cont := console.Confirm("Do you wish to continue after updating RELEASE-NOTES.txt?"); !cont {
return pr, fmt.Errorf("exiting before creating PR, Stopping at RELEASE-NOTES.txt update")
}
}

if err := git.CommitAll("Release script: Update release notes for version %s", version); err != nil {
return pr, fmt.Errorf("error committing the release notes update: %v", err)
Expand All @@ -135,7 +142,7 @@ func CreateGbmPR(build Build) (gh.PullRequest, error) {
}}

// Display PR preview
gh.PreviewPr("gutenberg-mobile", dir, pr)
gh.PreviewPr("gutenberg-mobile", dir, build.Base.Ref, pr)

// Add prompt to confirm PR creation
prompt := fmt.Sprintf("\nReady to create the PR on %s/gutenberg-mobile?", org)
Expand Down
2 changes: 1 addition & 1 deletion gbm-cli/pkg/release/integrate/integrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ func (ri *ReleaseIntegration) createPR(dir string, gbmPr gh.PullRequest) (gh.Pul
}}

rpo := ri.Target.GetRepo()
gh.PreviewPr(rpo, dir, pr)
gh.PreviewPr(rpo, dir, ri.BaseBranch, pr)

if err := gh.CreatePr(rpo, &pr); err != nil {
return pr, err
Expand Down
1 change: 1 addition & 0 deletions gbm-cli/pkg/release/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type Build struct {
Version semver.SemVer
Dir string
UseTag bool
Repo string
Prs []gh.PullRequest
Base gh.Repo
Depth string
Expand Down
21 changes: 0 additions & 21 deletions gbm-cli/pkg/release/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ import (
"strconv"
"strings"

"github.com/fatih/color"
"github.com/wordpress-mobile/release-toolkit-gutenberg-mobile/gbm-cli/pkg/console"
"github.com/wordpress-mobile/release-toolkit-gutenberg-mobile/gbm-cli/pkg/gh"
"github.com/wordpress-mobile/release-toolkit-gutenberg-mobile/gbm-cli/pkg/repo"
"github.com/wordpress-mobile/release-toolkit-gutenberg-mobile/gbm-cli/pkg/shell"
)

func CollectReleaseChanges(version string, changelog, relnotes []byte) ([]ReleaseChanges, error) {
Expand Down Expand Up @@ -191,24 +188,6 @@ func readWriteNotes(version, path string, updater func(string, []byte) []byte) e
return nil
}

func previewPr(rpo, dir, branchFrom string, pr gh.PullRequest) {
org := repo.GetOrg(rpo)
row := console.Row

console.Print(console.Heading, "\nPr Preview")

white := color.New(color.FgWhite).SprintFunc()

console.Print(row, "Repo: %s/%s", white(org), white(rpo))
console.Print(row, "Title: %s", white(pr.Title))
console.Print(row, "Body:\n%s", white(pr.Body))
console.Print(row, "Commits:")

git := shell.NewGitCmd(shell.CmdProps{Dir: dir, Verbose: true})

git.Log(branchFrom+"...HEAD", "--oneline", "--no-merges", "-10")
}

func openInEditor(dir string, files []string) error {
editor := os.Getenv("EDITOR")

Expand Down

0 comments on commit c4126c4

Please sign in to comment.