Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions cmd/submit.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,9 @@ func doSubmitPRs(g *git.Git, cfg *config.Config, root *tree.Node, branches []*tr
if err := ghClient.GenerateAndPostStackComment(root, b.Name, trunk, existingPR); err != nil {
fmt.Printf("Warning: failed to update stack comment for PR #%d: %v\n", existingPR, err)
}

// If PR is a draft and now targets trunk, offer to publish
maybeMarkPRReady(ghClient, existingPR, b.Name, parent, trunk)
}
} else if !updateOnly {
// Create new PR
Expand Down Expand Up @@ -459,9 +462,52 @@ func adoptExistingPR(ghClient *github.Client, cfg *config.Config, root *tree.Nod
fmt.Printf("Warning: failed to update stack comment: %v\n", err)
}

// If adopted PR is a draft and targets trunk, offer to publish
if existingPR.Draft && base == trunk {
promptMarkPRReady(ghClient, existingPR.Number, branch, trunk)
}

return existingPR.Number, nil
}

// maybeMarkPRReady checks if a PR is a draft targeting trunk and offers to publish it.
// This handles the case where a PR was created as a draft (middle of stack) but now
// targets trunk because its parent was merged.
func maybeMarkPRReady(ghClient *github.Client, prNumber int, branch, base, trunk string) {
// Only relevant if PR now targets trunk
if base != trunk {
return
}

// Check if PR is a draft
pr, err := ghClient.GetPR(prNumber)
if err != nil || !pr.Draft {
return
}

promptMarkPRReady(ghClient, prNumber, branch, trunk)
}

// promptMarkPRReady prompts to publish a draft PR and marks it ready if confirmed.
// Called when we already know the PR is a draft targeting trunk.
func promptMarkPRReady(ghClient *github.Client, prNumber int, branch, trunk string) {
fmt.Printf("PR #%d (%s) is a draft and now targets %s.\n", prNumber, branch, trunk)

// Skip prompt if --yes flag is set or non-interactive
shouldMarkReady := true
if !submitYesFlag && prompt.IsInteractive() {
shouldMarkReady, _ = prompt.Confirm("Mark as ready for review?", true) //nolint:errcheck // default is fine
}

if shouldMarkReady {
if readyErr := ghClient.MarkPRReady(prNumber); readyErr != nil {
fmt.Printf("Warning: failed to mark PR ready: %v\n", readyErr)
} else {
fmt.Printf("PR #%d marked as ready for review.\n", prNumber)
}
}
}

// generatePRBody creates a PR description from the commits between base and head.
// For a single commit: returns the commit body.
// For multiple commits: returns each commit as a markdown section.
Expand Down
14 changes: 0 additions & 14 deletions cmd/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,20 +298,6 @@ func runSync(cmd *cobra.Command, args []string) error {
if updateErr := gh.UpdatePRBase(rt.childPR, trunk); updateErr != nil {
fmt.Printf("Warning: failed to update PR #%d base: %v\n", rt.childPR, updateErr)
}

// Check if this was a draft and now targets trunk - offer to publish
pr, getPRErr := gh.GetPR(rt.childPR)
if getPRErr == nil && pr.Draft {
fmt.Printf("PR #%d (%s) now targets %s.\n", rt.childPR, rt.childName, trunk)
ready, _ := prompt.Confirm("Mark as ready for review?", true) //nolint:errcheck // default is fine
if ready {
if readyErr := gh.MarkPRReady(rt.childPR); readyErr != nil {
fmt.Printf("Warning: failed to mark PR ready: %v\n", readyErr)
} else {
fmt.Printf("PR #%d marked as ready for review.\n", rt.childPR)
}
}
}
}

// Rebase using --onto if we have a fork point
Expand Down