diff --git a/cmd/content.go b/cmd/content.go index f157449..2f621ce 100644 --- a/cmd/content.go +++ b/cmd/content.go @@ -25,6 +25,7 @@ var contentCmd = &cobra.Command{ } func init() { + contentCmd.Flags().Bool("create-branch", true, "create missing target branch") viper.BindPFlag("create-branch", contentCmd.Flags().Lookup("create-branch")) viper.BindEnv("create-branch", "GHUP_CREATE_BRANCH") @@ -177,9 +178,34 @@ func runContentCmd(cmd *cobra.Command, args []string) (err error) { return errors.Wrap(err, "CommitOnBranchV4") } - if title := viper.GetString("pr-title"); newBranch && title != "" { + + + if title := viper.GetString("pr-title"); title != "" { + existingPR, err := client.GetOpenPullRequestV4(owner, repo, branch, baseBranch) + if err != nil { + return errors.Wrap(err, "GetOpenPullRequestV4") + } + + if existingPR != nil { + log.Infof("existing pull request found: %s", existingPR.URL) + return nil + } + + if title := viper.GetString("pr-title"); (newBranch || (existingPR == nil)) && title != "" { body := githubv4.String(viper.GetString("pr-body")) log.Infof("opening pull request from %q to %q", branch, baseBranch) + + existingPR, err := client.GetOpenPullRequestV4(owner, repo, branch, baseBranch) + if err != nil { + return errors.Wrap(err, "GetOpenPullRequestV4") + } + + if existingPR != nil { + log.Infof("existing pull request found: %s", existingPR.URL) + fmt.Println(existingPR.URL) + return nil + } + input := githubv4.CreatePullRequestInput{ RepositoryID: repoInfo.NodeID, BaseRefName: githubv4.String(baseBranch), @@ -197,5 +223,6 @@ func runContentCmd(cmd *cobra.Command, args []string) (err error) { } else { fmt.Println(commitUrl) } + return } diff --git a/internal/remote/client.go b/internal/remote/client.go index 911da08..dc1a134 100644 --- a/internal/remote/client.go +++ b/internal/remote/client.go @@ -32,6 +32,12 @@ type RepositoryInfo struct { TargetBranch BranchInfo } +type PullRequest struct { + Number int + Title string + URL string +} + type RepositoryInfoQuery struct { Repository struct { Id githubv4.String @@ -229,6 +235,43 @@ func (c *TokenClient) GetRefOidV4(owner string, repo string, refName string) (oi return } +func (c *TokenClient) GetOpenPullRequestV4(owner, repo, headRefName, baseRefName string) (*PullRequest, error) { + var query struct { + Repository struct { + PullRequests struct { + Nodes []struct { + Number int + Title string + URL string + } + } `graphql:"pullRequests(states: OPEN, headRefName: $headRefName, baseRefName: $baseRefName, first: 1)"` + } `graphql:"repository(owner: $owner, name: $repo)"` + } + + variables := map[string]interface{}{ + "owner": githubv4.String(owner), + "repo": githubv4.String(repo), + "headRefName": githubv4.String(headRefName), + "baseRefName": githubv4.String(baseRefName), + } + + err := c.V4.Query(c.Context, &query, variables) + if err != nil { + return nil, err + } + + if len(query.Repository.PullRequests.Nodes) > 0 { + pr := query.Repository.PullRequests.Nodes[0] + return &PullRequest{ + Number: pr.Number, + Title: pr.Title, + URL: pr.URL, + }, nil + } + + return nil, nil +} + func (c *TokenClient) CreateRefV4(input githubv4.CreateRefInput) (err error) { var mutation CreateRefV4Mutation