Skip to content

Commit 9c910e3

Browse files
committed
--release
1 parent e073dc4 commit 9c910e3

File tree

1 file changed

+71
-33
lines changed

1 file changed

+71
-33
lines changed

tools/gonyx/cmd/cherry-pick.go

Lines changed: 71 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,40 @@ import (
1111
"github.com/spf13/cobra"
1212
)
1313

14+
// CherryPickOptions holds options for the cherry-pick command
15+
type CherryPickOptions struct {
16+
Releases []string
17+
}
18+
1419
// NewCherryPickCommand creates a new cherry-pick command
1520
func NewCherryPickCommand() *cobra.Command {
21+
opts := &CherryPickOptions{}
22+
1623
cmd := &cobra.Command{
1724
Use: "cherry-pick <commit-sha>",
1825
Short: "Cherry-pick a commit to a release branch",
1926
Long: `Cherry-pick a commit to a release branch and create a PR.
2027
2128
This command will:
22-
1. Find the nearest stable version tag (v*.*.*)
29+
1. Find the nearest stable version tag (v*.*.* if --release not specified)
2330
2. Fetch the corresponding release branch (release/vMAJOR.MINOR)
2431
3. Create a hotfix branch with the cherry-picked commit
2532
4. Push and create a PR using the GitHub CLI
26-
5. Switch back to the original branch`,
33+
5. Switch back to the original branch
34+
35+
The --release flag can be specified multiple times to cherry-pick to multiple release branches.`,
2736
Args: cobra.ExactArgs(1),
28-
Run: runCherryPick,
37+
Run: func(cmd *cobra.Command, args []string) {
38+
runCherryPick(cmd, args, opts)
39+
},
2940
}
3041

42+
cmd.Flags().StringSliceVar(&opts.Releases, "release", []string{}, "Release version(s) to cherry-pick to (e.g., v1.0, v1.1). Can be specified multiple times.")
43+
3144
return cmd
3245
}
3346

34-
func runCherryPick(cmd *cobra.Command, args []string) {
47+
func runCherryPick(cmd *cobra.Command, args []string, opts *CherryPickOptions) {
3548
commitSHA := args[0]
3649
log.Debugf("Cherry-picking commit: %s", commitSHA)
3750

@@ -48,67 +61,92 @@ func runCherryPick(cmd *cobra.Command, args []string) {
4861
shortSHA = shortSHA[:8]
4962
}
5063

51-
// Find the nearest stable tag
52-
version, err := findNearestStableTag(commitSHA)
64+
// Determine which releases to target
65+
var releases []string
66+
if len(opts.Releases) > 0 {
67+
releases = opts.Releases
68+
log.Infof("Using specified release versions: %v", releases)
69+
} else {
70+
// Find the nearest stable tag
71+
version, err := findNearestStableTag(commitSHA)
72+
if err != nil {
73+
log.Fatalf("Failed to find nearest stable tag: %v", err)
74+
}
75+
releases = []string{version}
76+
log.Infof("Auto-detected release version: %s", version)
77+
}
78+
79+
// Get commit message for PR title
80+
commitMsg, err := getCommitMessage(commitSHA)
5381
if err != nil {
54-
log.Fatalf("Failed to find nearest stable tag: %v", err)
82+
log.Warnf("Failed to get commit message, using default title: %v", err)
83+
commitMsg = fmt.Sprintf("Hotfix: cherry-pick %s", shortSHA)
84+
}
85+
86+
// Process each release
87+
prURLs := []string{}
88+
for _, release := range releases {
89+
log.Infof("\n--- Processing release %s ---", release)
90+
prURL, err := cherryPickToRelease(commitSHA, shortSHA, release, commitMsg, originalBranch)
91+
if err != nil {
92+
// Switch back to original branch before exiting on error
93+
runGitCommand("checkout", originalBranch)
94+
log.Fatalf("Failed to cherry-pick to release %s: %v", release, err)
95+
}
96+
prURLs = append(prURLs, prURL)
97+
}
98+
99+
// Switch back to the original branch
100+
log.Infof("\nSwitching back to original branch: %s", originalBranch)
101+
if err := runGitCommand("checkout", originalBranch); err != nil {
102+
log.Warnf("Failed to switch back to original branch: %v", err)
55103
}
56-
log.Infof("Found nearest stable version: %s", version)
57104

105+
// Print all PR URLs
106+
log.Info("\n=== Summary ===")
107+
for i, prURL := range prURLs {
108+
log.Infof("PR %d: %s", i+1, prURL)
109+
}
110+
}
111+
112+
// cherryPickToRelease cherry-picks a commit to a specific release branch
113+
func cherryPickToRelease(commitSHA, shortSHA, version, commitMsg, originalBranch string) (string, error) {
58114
releaseBranch := fmt.Sprintf("release/%s", version)
59-
hotfixBranch := fmt.Sprintf("hotfix/%s", shortSHA)
115+
hotfixBranch := fmt.Sprintf("hotfix/%s-%s", shortSHA, version)
60116

61117
// Fetch the release branch
62118
log.Infof("Fetching release branch: %s", releaseBranch)
63119
if err := runGitCommand("fetch", "origin", releaseBranch); err != nil {
64-
log.Fatalf("Failed to fetch release branch %s: %v", releaseBranch, err)
120+
return "", fmt.Errorf("failed to fetch release branch %s: %w", releaseBranch, err)
65121
}
66122

67123
// Create the hotfix branch from the release branch
68124
log.Infof("Creating hotfix branch: %s", hotfixBranch)
69125
if err := runGitCommand("checkout", "-b", hotfixBranch, fmt.Sprintf("origin/%s", releaseBranch)); err != nil {
70-
log.Fatalf("Failed to create hotfix branch: %v", err)
126+
return "", fmt.Errorf("failed to create hotfix branch: %w", err)
71127
}
72128

73129
// Cherry-pick the commit
74130
log.Infof("Cherry-picking commit: %s", commitSHA)
75131
if err := runGitCommand("cherry-pick", commitSHA); err != nil {
76-
// Switch back to original branch before exiting on error
77-
runGitCommand("checkout", originalBranch)
78-
log.Fatalf("Failed to cherry-pick commit: %v", err)
132+
return "", fmt.Errorf("failed to cherry-pick commit: %w", err)
79133
}
80134

81135
// Push the hotfix branch
82136
log.Infof("Pushing hotfix branch: %s", hotfixBranch)
83137
if err := runGitCommand("push", "-u", "origin", hotfixBranch); err != nil {
84-
// Switch back to original branch before exiting on error
85-
runGitCommand("checkout", originalBranch)
86-
log.Fatalf("Failed to push hotfix branch: %v", err)
87-
}
88-
89-
// Get commit message for PR title
90-
commitMsg, err := getCommitMessage(commitSHA)
91-
if err != nil {
92-
log.Warnf("Failed to get commit message, using default title: %v", err)
93-
commitMsg = fmt.Sprintf("Hotfix: cherry-pick %s", shortSHA)
138+
return "", fmt.Errorf("failed to push hotfix branch: %w", err)
94139
}
95140

96141
// Create PR using GitHub CLI
97142
log.Info("Creating PR...")
98143
prURL, err := createPR(hotfixBranch, releaseBranch, commitMsg, commitSHA)
99144
if err != nil {
100-
// Switch back to original branch before exiting on error
101-
runGitCommand("checkout", originalBranch)
102-
log.Fatalf("Failed to create PR: %v", err)
145+
return "", fmt.Errorf("failed to create PR: %w", err)
103146
}
104147

105148
log.Infof("PR created successfully: %s", prURL)
106-
107-
// Switch back to the original branch
108-
log.Infof("Switching back to original branch: %s", originalBranch)
109-
if err := runGitCommand("checkout", originalBranch); err != nil {
110-
log.Warnf("Failed to switch back to original branch: %v", err)
111-
}
149+
return prURL, nil
112150
}
113151

114152
// getCurrentBranch returns the name of the current git branch

0 commit comments

Comments
 (0)