Repository: lindell/multi-gitter
Pull request #268 (2022-08-01 20:46:47)

fix: return open PRs only
# What does this change

Once a change was partially merged, no further merge operations were possible as mutli-gitter tried to merge already merged PRs and GitHub returned.

`PUT https://api.github.com/repos/XYZ/pulls/40/merge: 405 Pull Request is not mergeable []`

Instead of returning all PRs for a branch, return only open PRs as there is currently no way to interact with already closed PRs.

# Checklist
- [x] Made sure the PR follows the [CONTRIBUTING.md](CONTRIBUTING.md) guidelines
- [x] Tests if something new is added


lindell: Thanks for the PR! You are right that MG for GitHub give this error since the graphql rewrite for PRs. But the query itself seems to be correct since it's used for both the `status` and `merge` commands. 

But from the error you described, I can see that the mapping to the "merged" status was missed:
https://github.com/lindell/multi-gitter/commit/60bbbdf526ce6e87d0f952fdae4858e4c6954952#diff-306f5e07e3d5522cd6066012a3c6a077dd2b03d1cf23b58af3466bd02e60b4af

Which means it instead get "success" status and it then not filtered out from being merged again.
lindell: Changed the pr to reflect this. Could you please confirm this is working as intended for you @johanneswuerbach 😄 

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 46902aa..f217c0b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Changelog
 
+### [0.42.1](https://www.github.com/lindell/multi-gitter/compare/v0.42.0...v0.42.1) (2022-08-06)
+
+
+### Bug Fixes
+
+* **github:** allow only pull permission for print command ([#262](https://www.github.com/lindell/multi-gitter/issues/262)) ([582c706](https://www.github.com/lindell/multi-gitter/commit/582c70633e0dcef04699c62b160a57fedb50c00d))
+
+
+### Miscellaneous
+
+* **gitlab:** fixed subgroup spelling ([46f178a](https://www.github.com/lindell/multi-gitter/commit/46f178ab097fefb3d07b65f3522e3e516638107a))
+
+
+### Dependencies
+
+* update github.com/eiannone/keyboard digest to 0d22619 ([f38b2f5](https://www.github.com/lindell/multi-gitter/commit/f38b2f5b2bf17afab06ed709c6b5ba4c9c9a6075))
+* update golang.org/x/oauth2 digest to 128564f ([63eab95](https://www.github.com/lindell/multi-gitter/commit/63eab95d69715ca1794f05447e3a588b70d99e62))
+* update golang.org/x/oauth2 digest to 2104d58 ([c4605e2](https://www.github.com/lindell/multi-gitter/commit/c4605e2c8db5440fc68b5b779ee46b360c4459db))
+* update module github.com/sirupsen/logrus to v1.9.0 ([1c8201a](https://www.github.com/lindell/multi-gitter/commit/1c8201a3b748b511effeb02b98ae1485f0e97b31))
+* update module github.com/spf13/cobra to v1.5.0 ([eb15db4](https://www.github.com/lindell/multi-gitter/commit/eb15db4fc137d5a23f3d137a778e4235b26b4e74))
+* update module github.com/spf13/viper to v1.12.0 ([ffdf7ae](https://www.github.com/lindell/multi-gitter/commit/ffdf7ae901b1f98fdd279fd5d1aeb72095bf2ad2))
+* update module github.com/stretchr/testify to v1.8.0 ([81a757c](https://www.github.com/lindell/multi-gitter/commit/81a757c88d3942ff5295a8edfcec6ad99ff9e669))
+* update module github.com/xanzy/go-gitlab to v0.68.0 ([78ca7f3](https://www.github.com/lindell/multi-gitter/commit/78ca7f343b846c56a7fdc76f59ec6a7591d7c3da))
+* update module github.com/xanzy/go-gitlab to v0.68.2 ([dab0985](https://www.github.com/lindell/multi-gitter/commit/dab09851cf9b694096ec11084568685efcd860ff))
+
 ## [0.42.0](https://www.github.com/lindell/multi-gitter/compare/v0.41.0...v0.42.0) (2022-05-06)
 
 
diff --git a/cmd/cmd-close.go b/cmd/cmd-close.go
index b195801..a14eaf0 100644
--- a/cmd/cmd-close.go
+++ b/cmd/cmd-close.go
@@ -32,7 +32,7 @@ func close(cmd *cobra.Command, args []string) error {
 
 	branchName, _ := flag.GetString("branch")
 
-	vc, err := getVersionController(flag, true)
+	vc, err := getVersionController(flag, true, false)
 	if err != nil {
 		return err
 	}
diff --git a/cmd/cmd-merge.go b/cmd/cmd-merge.go
index f309dc4..f98ee40 100644
--- a/cmd/cmd-merge.go
+++ b/cmd/cmd-merge.go
@@ -33,7 +33,7 @@ func merge(cmd *cobra.Command, args []string) error {
 
 	branchName, _ := flag.GetString("branch")
 
-	vc, err := getVersionController(flag, true)
+	vc, err := getVersionController(flag, true, false)
 	if err != nil {
 		return err
 	}
diff --git a/cmd/cmd-print.go b/cmd/cmd-print.go
index 896bdeb..32139ae 100755
--- a/cmd/cmd-print.go
+++ b/cmd/cmd-print.go
@@ -62,7 +62,7 @@ func print(cmd *cobra.Command, args []string) error {
 		return err
 	}
 
-	vc, err := getVersionController(flag, true)
+	vc, err := getVersionController(flag, true, true)
 	if err != nil {
 		return err
 	}
diff --git a/cmd/cmd-run.go b/cmd/cmd-run.go
index 275917d..142b5a8 100755
--- a/cmd/cmd-run.go
+++ b/cmd/cmd-run.go
@@ -135,7 +135,7 @@ func run(cmd *cobra.Command, args []string) error {
 		}
 	}
 
-	vc, err := getVersionController(flag, true)
+	vc, err := getVersionController(flag, true, false)
 	if err != nil {
 		return err
 	}
diff --git a/cmd/cmd-status.go b/cmd/cmd-status.go
index cb60b9c..b015734 100644
--- a/cmd/cmd-status.go
+++ b/cmd/cmd-status.go
@@ -35,7 +35,7 @@ func status(cmd *cobra.Command, args []string) error {
 	branchName, _ := flag.GetString("branch")
 	strOutput, _ := flag.GetString("output")
 
-	vc, err := getVersionController(flag, true)
+	vc, err := getVersionController(flag, true, false)
 	if err != nil {
 		return err
 	}
diff --git a/cmd/platform.go b/cmd/platform.go
index baceb43..cf1e944 100644
--- a/cmd/platform.go
+++ b/cmd/platform.go
@@ -94,7 +94,7 @@ var OverrideVersionController multigitter.VersionController = nil
 
 // getVersionController gets the complete version controller
 // the verifyFlags parameter can be set to false if a complete vc is not required (during autocompletion)
-func getVersionController(flag *flag.FlagSet, verifyFlags bool) (multigitter.VersionController, error) {
+func getVersionController(flag *flag.FlagSet, verifyFlags bool, readOnly bool) (multigitter.VersionController, error) {
 	if OverrideVersionController != nil {
 		return OverrideVersionController, nil
 	}
@@ -102,7 +102,7 @@ func getVersionController(flag *flag.FlagSet, verifyFlags bool) (multigitter.Ver
 	platform, _ := flag.GetString("platform")
 	switch platform {
 	case "github":
-		return createGithubClient(flag, verifyFlags)
+		return createGithubClient(flag, verifyFlags, readOnly)
 	case "gitlab":
 		return createGitlabClient(flag, verifyFlags)
 	case "gitea":
@@ -114,7 +114,7 @@ func getVersionController(flag *flag.FlagSet, verifyFlags bool) (multigitter.Ver
 	}
 }
 
-func createGithubClient(flag *flag.FlagSet, verifyFlags bool) (multigitter.VersionController, error) {
+func createGithubClient(flag *flag.FlagSet, verifyFlags bool, readOnly bool) (multigitter.VersionController, error) {
 	gitBaseURL, _ := flag.GetString("base-url")
 	orgs, _ := flag.GetStringSlice("org")
 	users, _ := flag.GetStringSlice("user")
@@ -149,7 +149,7 @@ func createGithubClient(flag *flag.FlagSet, verifyFlags bool) (multigitter.Versi
 		Organizations: orgs,
 		Users:         users,
 		Repositories:  repoRefs,
-	}, mergeTypes, forkMode, forkOwner, sshAuth)
+	}, mergeTypes, forkMode, forkOwner, sshAuth, readOnly)
 	if err != nil {
 		return nil, err
 	}
@@ -294,7 +294,7 @@ func versionControllerCompletion(cmd *cobra.Command, flagName string, fn func(vc
 		// Make sure config files are loaded
 		_ = initializeConfig(cmd)
 
-		vc, err := getVersionController(cmd.Flags(), false)
+		vc, err := getVersionController(cmd.Flags(), false, false)
 		if err != nil {
 			return nil, cobra.ShellCompDirectiveError
 		}
diff --git a/internal/scm/github/github.go b/internal/scm/github/github.go
index 2a5a9c0..36948af 100755
--- a/internal/scm/github/github.go
+++ b/internal/scm/github/github.go
@@ -26,6 +26,7 @@ func New(
 	forkMode bool,
 	forkOwner string,
 	sshAuth bool,
+	readOnly bool,
 ) (*Github, error) {
 	ctx := context.Background()
 	ts := oauth2.StaticTokenSource(
@@ -54,6 +55,7 @@ func New(
 		ForkOwner:         forkOwner,
 		SSHAuth:           sshAuth,
 		ghClient:          client,
+		ReadOnly:          readOnly,
 		httpClient: &http.Client{
 			Transport: transportMiddleware(http.DefaultTransport),
 		},
@@ -71,6 +73,9 @@ type Github struct {
 	// In this package, it mainly determines which repos are possible to make changes on
 	Fork bool
 
+	// This determines when we are running in read only mode.
+	ReadOnly bool
+
 	// If set, the fork will happen to the ForkOwner value, and not the logged in user
 	ForkOwner string
 
@@ -143,7 +148,7 @@ func (g *Github) GetRepositories(ctx context.Context) ([]scm.Repository, error)
 		case !permissions["pull"]:
 			log.Debug("Skipping repository since the token does not have pull permissions")
 			continue
-		case !g.Fork && !permissions["push"]:
+		case !g.Fork && !g.ReadOnly && !permissions["push"]:
 			log.Debug("Skipping repository since the token does not have push permissions and the run will not fork")
 			continue
 		}
@@ -332,6 +337,7 @@ func (g *Github) GetPullRequests(ctx context.Context, branchName string) ([]scm.
 				headRefName
 				closed
 				url
+				merged
 				baseRepository {
 					name
 					owner {
diff --git a/internal/scm/github/graphql.go b/internal/scm/github/graphql.go
index 700aa60..722e6d2 100644
--- a/internal/scm/github/graphql.go
+++ b/internal/scm/github/graphql.go
@@ -116,6 +116,7 @@ type graphqlPR struct {
 	HeadRefName    string `json:"headRefName"`
 	Closed         bool   `json:"closed"`
 	URL            string `json:"url"`
+	Merged         bool   `json:"merged"`
 	BaseRepository struct {
 		Name  string `json:"name"`
 		Owner struct {
diff --git a/internal/scm/github/pullrequest.go b/internal/scm/github/pullrequest.go
index db88eed..69ef5e9 100644
--- a/internal/scm/github/pullrequest.go
+++ b/internal/scm/github/pullrequest.go
@@ -24,7 +24,9 @@ func convertGraphQLPullRequest(pr graphqlPR) pullRequest {
 	combinedStatus := pr.Commits.Nodes[0].Commit.StatusCheckRollup.State
 	status := scm.PullRequestStatusUnknown
 
-	if combinedStatus == nil {
+	if pr.Merged {
+		status = scm.PullRequestStatusMerged
+	} else if combinedStatus == nil {
 		status = scm.PullRequestStatusSuccess
 	} else {
 		switch *combinedStatus {
diff --git a/version.txt b/version.txt
index 787ffc3..339fd08 100644
--- a/version.txt
+++ b/version.txt
@@ -1,1 +1,1 @@
-0.42.0
+0.42.1


Test patch:
diff --git a/internal/scm/github/github_test.go b/internal/scm/github/github_test.go
index b162fdc..39d5e42 100644
--- a/internal/scm/github/github_test.go
+++ b/internal/scm/github/github_test.go
@@ -117,7 +117,7 @@ func Test_GetRepositories(t *testing.T) {
 	{
 		gh, err := github.New("", "", transport.Wrapper, github.RepositoryListing{
 			Organizations: []string{"test-org"},
-		}, []scm.MergeType{scm.MergeTypeMerge}, false, "", false)
+		}, []scm.MergeType{scm.MergeTypeMerge}, false, "", false, false)
 		require.NoError(t, err)
 
 		repos, err := gh.GetRepositories(context.Background())
@@ -137,7 +137,7 @@ func Test_GetRepositories(t *testing.T) {
 					Name:      "test1",
 				},
 			},
-		}, []scm.MergeType{scm.MergeTypeMerge}, false, "", false)
+		}, []scm.MergeType{scm.MergeTypeMerge}, false, "", false, false)
 		require.NoError(t, err)
 
 		repos, err := gh.GetRepositories(context.Background())
@@ -152,7 +152,7 @@ func Test_GetRepositories(t *testing.T) {
 	{
 		gh, err := github.New("", "", transport.Wrapper, github.RepositoryListing{
 			Users: []string{"test-user"},
-		}, []scm.MergeType{scm.MergeTypeMerge}, false, "", false)
+		}, []scm.MergeType{scm.MergeTypeMerge}, false, "", false, false)
 		require.NoError(t, err)
 
 		repos, err := gh.GetRepositories(context.Background())
@@ -174,7 +174,7 @@ func Test_GetRepositories(t *testing.T) {
 					Name:      "test1",
 				},
 			},
-		}, []scm.MergeType{scm.MergeTypeMerge}, false, "", false)
+		}, []scm.MergeType{scm.MergeTypeMerge}, false, "", false, false)
 		require.NoError(t, err)
 
 		repos, err := gh.GetRepositories(context.Background())