Giter Site home page Giter Site logo

lindell / multi-gitter Goto Github PK

View Code? Open in Web Editor NEW
808.0 808.0 62.0 1.6 MB

Update multiple repositories in with one command

License: Apache License 2.0

Go 96.42% Shell 3.58%
automation cli commandline developer-tools devops devtools git github gitlab go golang productivity script

multi-gitter's Introduction

multi-gitter's People

Contributors

artuross avatar berreek avatar cburch824 avatar chaoscypher avatar daemocles avatar dependabot[bot] avatar devcharmander avatar dnwe avatar fabasoad avatar filipkrayem avatar github-actions[bot] avatar gustavkj avatar jamestelfer avatar jetersen avatar johanneswuerbach avatar josealdaco avatar kasonbraley avatar lindell avatar mareksimunek avatar martincostello avatar nitram509 avatar raffis avatar renovate-bot avatar renovate[bot] avatar ryancurrah avatar step-security-bot avatar syphernl avatar tadam313 avatar tmeijn avatar wstrm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

multi-gitter's Issues

Support caching repositories

Hello!

When using multi-gitter I noticed that on every run the respective repos are always pulled.

It would be great if this could be cached, to avoid long wait times to pull many repositories (especially when the entire org is specified).

Changeable git backend

As of now, multi-gitter is using go-git for all git-related operations. This does make multi-gitter completely self-contained since it does not have any dependencies. But it could be useful to have the option to switch to the main git implementation by running the git command instead, since there seems to be some minor bugs in go-git that could be solved by making it optional.

Search through subgroups in Gitlab

Hello,

This tool is awesome and I love it. One thing I noticed is that when using -G with Gitlab it won't find any subgroups under the one specified in the command so you have to run the tool multiple times for each location. A way to wildcard or search through subgroups would be awesome.

Example:
multi-gitter run ./somescript.sh -G my/cool/path/
won't find
my/cool/path/subgroup1/targetproject1
my/cool/path/subgroup2/targetproject2

Maybe another option would to be able to wildcard projects like targetproject*

Gitlab: Does not support nested groups

Describe the bug
When using the project attribute in the yaml config or on the command line it does not support sub-groups on GitLab.

When running a config that has:

project:
  - group-org/subgroup/project

It fails with the following message:

could not parse repository reference: group-org/subgroup/project

Looking through the code it seems that it fails on this validation function:

// ParseProjectReference parses a repository reference from the format "ownerName/repoName"
func ParseProjectReference(val string) (ProjectReference, error) {
split := strings.Split(val, "/")
if len(split) != 2 {
return ProjectReference{}, fmt.Errorf("could not parse repository reference: %s", val)
}
return ProjectReference{
OwnerName: split[0],
Name: split[1],
}, nil
}

It splits on slashes and errors when the parts are not equal to 2.

Changing the second slash to URI encoded slash (group-org/subgroup%2Fproject) allows me to pass the validation function but then it errors when actually trying to fetch the repository.

Expected behavior
I'd expect it to allow projects in nested groups on Gitlab.

Hope this is clear enough! Nice tool BTW! ๐Ÿ‘๐Ÿพ

Multi-gitter doesnt attempt to open pull requests for branches that already exist

Describe the bug
When running the run command, if you lose connection to github between when the branch is created and when the pull request is opened then you will be unable to open a pull request with the created branch using multi-gitter. I've also noticed if you hit the pull request rate limiting when concurrency is enabled then multi-gitter will continue to create branches but won't re-attempt to open any pull requests. Re-running the tool just tells you the branch already exists, but I would expect if the branch already exists but there isn't a pull request that it would try to create a pull request based on that branch.

Expected behavior
Branches that exist but don't have an associated pull request attempt to open a pull request

multi-gitter run does not sign commits

Describe the bug
Should be able to understand signing commits

To Reproduce
Steps to reproduce the behavior:

  1. Run multi-gitter run -xxx
  2. git verify-commit HEAD

Expected behavior
Commits are signed

Additional context
Changing git-type to cmd does not work

git-type: cmd

You have exceeded a secondary rate limit

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

Run multi-gitter with this config:
https://github.com/hmcts/multi-gitter-backstage/tree/b52250d5554d1f4b903d81e1dfc667137e9b4eff

After about 50 repositories I started getting this quite frequently:

INFO[0395] POST https://api.github.com/repos/hmcts/fpl-ccd-configuration/pulls: 403 You have exceeded a secondary rate limit and have been temporarily blocked from content creation. Please retry your request again later. []

Expected behavior

Create the pull requests slow enough that you don't get rate limited (and also sleep and retry if it does happen)

Additional context
Was supposed to be fixed by #207

GitLab 14.10.2: 401 Unauthorized

Describe the bug

Running multi-gitter against a self-hosted GitLab server fails after upgrade from GitLab 14.9.3 to 14.10.2. I wrote a script to update multiple projects and did a dry-run to confirm it all works. Due to a deadline the update had to wait and didn't get applied, while an upgrade to the GitLab server was applied in the meantime. The script is unchanged, but all of a sudden I can't access any GitLab project anymore through multi-gitter.

To Reproduce

Steps to reproduce the behavior:

  1. Run multi-gitter run "python3 $PWD/change.py" --config spec.yaml --project owner/myproj --reviewers rev1,rev2,rev3 --assignees as1
  2. Returns could not fetch repositories: GET https://self.hosted/api/v4/projects/owner/myproj: 401 {message: 401 Unauthorized}

Expected behavior

I expect to be able to run the change and create a merge request as specified in the YAML.

Additional context

Cloning using the Personal Access Token from command line as follows git clone https://oauth2:<token>@self.hosted/owner/myproj.git also works just fine. So the Personal Access Token seems to work, except in combination with multi-gitter. Which made me clueless where this error originates.

GitHub actions Window Server test failing

When running the multi-gitter tests on Windows server (2019) via GitHub actions, most tests will fail.

This seems to be due to local cloning via file://"C:/xxx/xxx.git" not working and resulting in: "could not clone from the remote: repository not found" when multi-gitter is expected to clone the repo.

This works on (my machine on) Windows 10.

I have verified that the C:/xxx/xxx.git repo exists and that it is a git folder. But still can't get the tests to work.

Help wanted from anyone that might be able to reproduce this locally and are able to debug it.

Ability to filter repos

Right now it seems like the repositories used are all or nothing. Our use case for this tool would be more like "add this PR for all repositories that use Ruby as its main language", or possibly 'all repositories that have the text "circleci" in the file "ci.yml"'. GitHub supports these filters/searches, so it would be great if we could use that in this tool.

[Github] status command looks at latest, instead of specified PR

Describe the bug
When using this config file for status command, it returns me the status of latest PR in repository, instead of PR created from specified branch:

branch: [name-of-the-branch-omitted]
repo:
- [name-of-repo-1-omitted]
- [name-of-repo-2-omitted]
multi-gitter status --config=status.yaml
...
[org]/[name-of-repo-2-omitted] #218: Merged

I.e. it returns status for PR#218, while the expected PR is #217

To Reproduce

  • Open a new PR with multi-gitter in a Github repo
  • Create a new PR manually in the same repo
  • Run status command for PR in step 1

Expected behavior
Return status for correct PR.

Additional context
This could also apply to other commands for Github, namely close. We had a situation where we unintentionally closed PRs of some other team by running multi-gitter close command - but status is easier for me to double-check and verify right now.

Digging a big deeper - and not being an expert on Github API (not sure if I'm looking at docs of correct version as implemented by go-github lib that is used here), but I noticed here that head is documented to be in format user:ref-name or organization:ref-name, and not just ref-name (found the implementation here.)

Indeed, when I manually run this curl against Github API, it returns me the latest PR:

curl -v -u "$GITHUB_USER:$GITHUB_TOKEN" 'https://api.github.com/repos/${ORG}/${REPO}/pulls?direction=desc&head=${BRANCH}&per_page=1&state=all'

returns latest PR

Only when I run it with head=${ORG}:${BRANCH}, it returns the proper PR:

curl -v -u "$GITHUB_USER:$GITHUB_TOKEN" 'https://api.github.com/repos/${ORG}/${REPO}/pulls?direction=desc&head=urlencoded(${ORG}:${BRANCH})&per_page=1&state=all'

returns proper desired PR

Hope this helps ๐Ÿ™๐Ÿผ

Add ability to configure repository clone directory (currently system temp)

I'm running multi-gitter inside a Docker / VS Code devcontainer environment.
It would be nice to configure the directory where multi-gitter clones the repositories.
Currently this is the system temporary directory:

tmpDir, err := os.MkdirTemp(os.TempDir(), "multi-git-changer-")

This would allow mounting a Docker volume and examine the GIT changes in interactive mode with a GIT GUI of choice on the Docker host.
Currently I have to map the system temporary directory to the Docker host which is not nice.

Error after merging a Github repo

Describe the bug
When merging a GitHub repository which is set to "Automatically delete head branches" a 422 Reference does not exist [] error is returned and processing of repositories is halted

To Reproduce
Steps to reproduce the behavior:

  1. Create a repo which has "Automatically delete head branches" in Options
  2. Run multi-gitter merge -xxx
  3. See error - this does not happen on all runs - I think this depends on timing

Expected behavior
The 422 error is caught and ignored. Processing of repositories continue

Add bulk pull request approval support

Additional / optional pull request approval support would be nice for the merge command.

When you have e.g. GitHub branch protections which do not allow administrator bypassing you cannot bulk merge the changes you created with the run command..

Add ability to skip specific projects/repos

Problem to solve

In my use-case in GitLab, you can either list individual projects and/or specify a group. If you have a group with hundreds of projects and want to open a Merge Request for all projects included in the group except for one or two, your only option is to specify all the individual projects.

Proposal

Add a configuration option which allows you skip certain projects from a configuration, like this:

group:
  - acme

skip-projects:
  - acme/no-merge-request

Further details

Looking into the code and excusing my lack of Go knowledge:

https://github.com/lindell/multi-gitter/blob/633a2ccc973070790b0cb644aa9029727a220e20/internal/scm/gitlab/gitlab.go#L129:L144

I think it may be possible to the remove entries from the project list that gets generated.

Notes

I can see that this request is a bit related to #122 and that this particular problem could be solved in the same way, but I think the ability to filter specific repos is a helpful addition without adding a full search capability.

unknown command when using --interactive

$ multi-gitter --interactive run ls          
Error: unknown command "ls" for "multi-gitter"
Run 'multi-gitter --help' for usage.
unknown command "ls" for "multi-gitter"
$ multi-gitter version  
multi-gitter version: 0.42.3
Release-Date: 2022-08-12
Go version: go1.19
Commit: e4bc83aa64aa709ded9cfd04e8e40d8ebe65e988

Feature Request: Sync file(s) across repositories

Currently we have identical files in multiple repositories (protobuf definitions) and when we make a change in one repository, we would like to make the identical change in the other repository. The directory in one repo is not the same as the directory in the other repository.

Multi-gitter would be even more useful if it could automate this for us. Thanks for a cool tool regardless!

Interactive mode

Right now, we can do dry runs or full out PRs. It would be amazing if we could be shown the diffs before the commit and allow us to approve or reject the change before the PR is created.

Deleting files produces empty commits

Describe the bug
Deleting a file produces empty commits instead of deleting them

To Reproduce

Run the following command on a test repository containing a README.md (you can fork mine):

multi-gitter run "rm README.md" -R klieret/multi-gitter-delete-bug-demonstration -m "Remove file"

Expected behavior

I expect a commit that has README.md deleted.

What happens instead

The output looks normal:

INFO[0000] Running on 1 repositories
INFO[0000] Cloning and running script                    repo=klieret/multi-gitter-delete-bug-demonstration
INFO[0000] Pushing changes to remote                     repo=klieret/multi-gitter-delete-bug-demonstration
INFO[0001] Creating pull request                         repo=klieret/multi-gitter-delete-bug-demonstration
Repositories with a successful run:
  klieret/multi-gitter-delete-bug-demonstration #1

But you get a PR with an empty commit. Which is bad because the README.md should be deleted, but also bad because empty commits shouldn't be added by multi-gitter.

Feature request: Add project maintainers as reviewers

Recently I used multi-gitter to do updates across 40 repositories. Each of the repositories has its own maintainers whom must merge the pull request. So what I wanted is to automatically get a list of the maintainers via GitLab API and add (a couple of) them as reviewer. Ultimately I ended up using a Python script that got the maintainers for a repository, then called multi-gitter. It would be useful if this could become a feature within multi-gitter.

What do you think about adding such feature to multi-gitter? Looking through the source of both multi-gitter and go-gitlab it's seems like it would require to add an extra commandline argument and grabbing the maintainers using the following function provided by go-gitlab. I'm not sure if this feature is too platform specific however.

multi-gitter doesnt work with github app

multi-gitter works fine with a PAT, however when switching to a github app and using an auth token multi-gitter won't run on any repos.

If debug is set to trace it appears to be pulling in a ton of repo information, perhaps it's using a different API?

conflict-strategy: replace should only force push on actual changes

Describe the bug
conflict-strategy: replace currently force pushes a commit to the existing branch even if there are no actual changes to process. This causes CI to run unnecessarily

To Reproduce
Steps to reproduce the behavior:

  1. multi-gitter with conflict-strategy: replace
  2. make change to repository
  3. run multi-gitter
  4. run multi-gitter again

Expected behavior
Multi-Gitter should ideally check if there is an actual delta between the existing branch and the current changes and only force push (replace) then there are changes.

Cannot create PR in Github enterprise instance.

Describe the bug
No PR is created when running multi-gitter run ... in our GitHub enterprise instance. The following error is produced json: cannot unmarshal array into Go value of type github.PullRequest. This happens for all repos within the organization, and not only for a specific one.

To Reproduce
Steps to reproduce the behavior:

  1. Try to create a PR on a GitHub enterprise instance.
  2. Run multi-gitter run ./upgrade-deps.sh -O <MY_ORGANISATION> -m "Upgraded dependencies and go version" -B upgrade-dependencies -g http://<GITHUB_ENTERPRISE_URL> --conflict-strategy replace
  3. It produces the error json: cannot unmarshal array into Go value of type github.PullRequest

Expected behavior
I expect PRs to be created for each change in each repo.

Context
The version of the GitHub enterprise version is currently 3.3.1

index out of range error when using multiline commit messages

Describe the bug
Multi-line commit messages don't work and lead to the following error

panic: runtime error: index out of range [2] with length 2

goroutine 1 [running]:
github.com/lindell/multi-gitter/cmd.run(0xc000191b80, {0xc0001ec180, 0x4, 0x4})
	/home/runner/work/multi-gitter/multi-gitter/cmd/cmd-run.go:112 +0xe5e
github.com/spf13/cobra.(*Command).execute(0xc000191b80, {0xc0001ec140, 0x4, 0x4})
	/home/runner/go/pkg/mod/github.com/spf13/[email protected]/command.go:856 +0x60e
github.com/spf13/cobra.(*Command).ExecuteC(0xc000191900)
	/home/runner/go/pkg/mod/github.com/spf13/[email protected]/command.go:974 +0x3bc
github.com/spf13/cobra.(*Command).Execute(...)
	/home/runner/go/pkg/mod/github.com/spf13/[email protected]/command.go:902
main.main()
	/home/runner/work/multi-gitter/multi-gitter/main.go:19 +0xe5
Error: panic: runtime error: index out of range [2] with length 2

To Reproduce
Steps to reproduce the behavior:

multi-gitter run 'echo "something"' --repo some/repo --branch some-branch --commit-message $'foo\nbar'

or via config.yaml:

commit-message: |
  foo
  bar

Expected behavior
There is no error

Additional context
v0.38.2 on Mac

`status` command should also read the configuration file

Problem

Currently, it's seems that the status command does not accept a YAML config. This makes this command more cumbersome to use than needed IMHO.

Proposal

Just like the other commands, allow a YAML config for the status command, since all required options are already configured there in my case.

Yaml based config.

It would nice to be able to feed MG a yaml(s) with a set of jobs to run instead of having to specify each flag on the commandline. This would be beneficial for running these jobs many times or scheduling them.

Example:

---
update_something_one:
  script: job_1.py
  platform: "gitlab"
  groups: "gitlab/group/path" 
  include_subgroups: True
  commit_message: "Update something" 
  branch_name: "hotfix/update-something"
  merge_request:
    body: "Update something body"
    title: "MR title update something"
  dry_run: True
  
bin_true:
  script: bin_true.sh
  platform: "gitlab"
  groups: "gitlab/some/other/path" 
  commit_message: "Run second job" 
  branch_name: "hotfix/second job"
  merge_request:
    body: "Try second job"
    title: "Second MR"

Then you would run:

multi-gitter run -y path/to/job.yaml

Fork mode

Add the ability to fork the repository and make the changes on the fork instead of only allowing on a branch in the same repo.

The owner of the fork should probably be an option since you can fork both under your own name and under an organization.

This ticket was created after some discussions on #122

[GitLab] only list projects with Merge Requests enabled

Describe the bug
In GitLab a project can disable Merge Requests. Multi-Gitter currently does not exclude these projects.

To Reproduce
Steps to reproduce the behavior:

  1. Have a group with a project that has Merge Requests disabled
  2. Run multi-gitter status (did not try other commands)
  3. Command fails with GET https://gitlab.com/api/v4/projects/xxxxxxxxx/merge_requests: 403 {message: 403 Forbidden}

Expected behavior
Multi-Gitter should exclude projects with Merge Requests disabled

Additional context
The GitLab Groups API has an option to only list projects with Merge Requests enabled.

In go-gitlab it's this option: https://github.com/xanzy/go-gitlab/blob/7859f4617e05e4d1e31afa4dffda24c6ea86147f/groups.go#L370:2

So I think the change to resolve this issue could be in gitlab.go:

func (g *Gitlab) getGroupProjects(ctx context.Context, groupName string) ([]*gitlab.Project, error) {
	var allProjects []*gitlab.Project
	for i := 1; ; i++ {
		projects, _, err := g.glClient.Groups.ListGroupProjects(groupName, &gitlab.ListGroupProjectsOptions{
			ListOptions: gitlab.ListOptions{
				PerPage: 100,
				Page:    i,
			},
			IncludeSubgroups: &g.Config.IncludeSubgroups,
+                       WithMergeRequestsEnabled: true
		}, gitlab.WithContext(ctx))
		if err != nil {

Allow interactive mode to be used with concurrency

Currently, interactive mode can't be activated at the same time as concurrency > 1.

This would be beneficial since while manually looking at some changes, MG could look for new ones.

To archive, this, locking of the interactive part has to take place, and any logging during this time has to be suspended (at least when writing to stdout) and then resumed when the user is no longer making decisions.

Some more discussion around this was held in the issue around creating the interactive mode #123

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Location: renovate.json
Error type: The renovate configuration file contains some invalid settings
Message: Invalid packageRules[0].schedule: 'Invalid schedule: Failed to parse "first day of the month"', Invalid packageRules[1].schedule: 'Invalid schedule: Failed to parse "first day of the month"'

Rely on git changes instead of branches in making PRs

Right now multi-gitter relies on the branch to exist to determine if it should make a PR. I would nice to not have to keep branches around for this.

Instead would be more nice if it used git's built in understanding of modified, added, deleted etc. to create a PR.

Gitlab: close Merge Requests instead of deleting them

Describe the bug
Currently when Multi-Gitter is called with the close command, the GitLab implementation actually deletes the Merge Request instead of closing it. This results in the Merge Request not being able to be found anymore. Furthermore, this requires admin or owner level privileges, which is not necessarily required for Multi-Gitter to work.

Expected behavior
Instead of deleting, the Merge Request should be closed

Additional context
The function that should close the Merge Request actually calls the DeleteMergeRequest, which calls the DELETE method on the api

_, err := g.glClient.MergeRequests.DeleteMergeRequest(pr.targetPID, pr.iid, gitlab.WithContext(ctx))

Instead the Merge Request should be updated with the state_event: close

Support for Repo's SSH URL

Hi there,
I was looking to use this tool as a quick way to update the reference version of CI templates in GitLab across multiple repos, as GitLab doesn't allow for variables to be set in the ref and I don't want to have all my repos reference the master branch.
My repos' gitlab-ci.yml looks something like this:

include:
  - project:  "templates/gitlab-ci"
    ref:      "v2.3.1" # can also be a branch name - variables do not expand here
    file:     "helm.yml"

However I've run into an issue - I cannot use the HTTP URL to clone a repo.

To give a little backstory on this, I work in a self-hosted GitLab environment that has the HTTPS URL disabled (and I'm not in charge of the platform so it can't be enabled), meaning that whenever I try to use multi-gitter I get a permission denied when it goes to clone a repo because it's reliant on the HTTPS URL. I thought I could maybe get around this by defining in git something like:

git config --global url."[email protected]:".insteadOf "https://private.gitlab.com/"

and switching the multi-gitter config to use git-type: cmd, but it seems like however multi-gitter is calling git ignores this setting.

I'm wondering if it would be possible to add an option for use of the SSH URL instead of the HTTP URL to clone a repo when using the run command. My Golang knowledge isn't very strong but I poked around in the code and it seems like in the convertProject function in internal/scm/gitlab/repository.go explicitly uses project.HTTPURLToRepo as the source for its clone URL.

Trace of when I try to use run command:

multi-gitter run ./update_gitlab_template_ref.sh --config=./config.yaml
...
INFO[0000] Running on 1 repositories                    
INFO[0000] Cloning and running script                    repo=helm/postgresql
INFO[0000] could not clone from the remote: authorization failed  repo=helm/postgresql
TRAC[0000] github.com/lindell/multi-gitter/internal/git/gogit.(*Git).Clone
	/home/runner/work/multi-gitter/multi-gitter/internal/git/gogit/git.go:36
github.com/lindell/multi-gitter/internal/multigitter.(*Runner).runSingleRepo
	/home/runner/work/multi-gitter/multi-gitter/internal/multigitter/run.go:207
github.com/lindell/multi-gitter/internal/multigitter.(*Runner).Run.func2
	/home/runner/work/multi-gitter/multi-gitter/internal/multigitter/run.go:118
github.com/lindell/multi-gitter/internal/multigitter.runInParallel.func1
	/home/runner/work/multi-gitter/multi-gitter/internal/multigitter/run.go:169
runtime.goexit
	/opt/hostedtoolcache/go/1.17.2/x64/src/runtime/asm_amd64.s:1581 
Could not clone from the remote: authorization failed:
  helm/postgresql

BitBucket cloud support

BitBucket is one of the biggest SCMs after GitHub and GitLab and support for it would be useful for a lot of people.

If anyone is familiar with BitBucket and is willing to help out. The VersionController interface can be implemented and be placed in this package: https://github.com/lindell/multi-gitter/tree/master/internal/scm

Update: Thanks to @ryancurrah mutli-gitter now have bitbucket-server support since v0.33.0. It still missed BitBucket cloud support, making this ticket still relevant.

Need to push changes only to specific repos under an org

Need to push changes only to specific repos under an org. is there a way to do that for specific repos alone instead of running it for all the repos.. I do see a skip repo option, however, i could see a specific repo option

Github actions are not used when determining PR status

Unless I have missed the way to do it, it looks like the merge sub-command will just forcibly merge PRs, even if status checks have not passed, or a reviewer has not approved it.

I think this would be quite a nice option to add. I could currently run multi-gitter status to generate a list of repos with status Approved, and then use this to call multi-gitter merge, but mistakes could still be made, and PRs could be merged by accident.

Perhaps two boolean flags could be added:

  • --require-approval
  • --require-status-checks

To clarify, this is a problem because I am an administrator and can bypass branch protection rules.

Need to push changes only to specific repos under an org -

@lindell I tried using the --repo option but it still pushes to all the repos under that org.. i am i missing something ?

arunk@hjgj7m3:~/personal$ multi-gitter run ./script.sh -O arun-291091 -m "testing" -b main --repo=arun-291091/semgrep --skip-pr=true
INFO[0000] Running on 4 repositories
INFO[0000] Cloning and running script repo=arun-291091/test-1
INFO[0001] Pushing changes to remote repo=arun-291091/test-1
INFO[0002] Cloning and running script repo=arun-291091/test-2
INFO[0003] Pushing changes to remote repo=arun-291091/test-2
INFO[0004] Cloning and running script repo=arun-291091/test-3
INFO[0005] Pushing changes to remote repo=arun-291091/test-3
INFO[0006] Cloning and running script repo=arun-291091/semgrep
INFO[0006] Pushing changes to remote repo=arun-291091/semgrep
Repositories with a successful run:
arun-291091/test-1
arun-291091/test-2
arun-291091/test-3
arun-291091/semgrep

multi-gitter unable to run against returned repos when using github app installation token

Describe the bug
When using a github app installation token with multi-gitter, all repos can be listed, but multi-gitter doesn't run against them. Using the same token, I am able to create pull requests using curl. The issue appears to be specific to multi-gitter, I wonder if parsing the repositories is the problem?

response with multi-gitter
{ 2022-01-27T07:00:15.0920886Z "host": "api.github.com", 2022-01-27T07:00:15.0921276Z "level": "trace", 2022-01-27T07:00:15.0921608Z "msg": "http request", 2022-01-27T07:00:15.0923119Z "request": "GET /orgs/xxxx/repos?page=1\u0026per_page=100 HTTP/1.1\r\nHost: api.github.com\r\nUser-Agent: go-github\r\nAccept: application/vnd.github.mercy-preview+json, application/vnd.github.nebula-preview+json\r\nAuthorization: Basic \u003cCENSORED\u003e\nAccept-Encoding: gzip\r\n\r\n", 2022-01-27T07:00:15.2640493Z "response": "HTTP/2.0 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset\r\nCache-Control: private, max-age=60, s-maxage=60\r\nContent-Security-Policy: default-src 'none'\r\nContent-Type: application/json; charset=utf-8\r\nDate: Thu, 27 Jan 2022 07:00:15 GMT\r\nEtag: W/\"122717a36610aa3b6881db1871bc5285493eea207663614e64af2d6e83c4dfa8\"\r\nLink: \u003chttps://api.github.com/organizations/1874256/repos?page=2\u0026per_page=100\u003e; rel=\"next\", \u003chttps://api.github.com/organizations/1874256/repos?page=5\u0026per_page=100\u003e; rel=\"last\"\r\nReferrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin\r\nServer: GitHub.com\r\nStrict-Transport-Security: max-age=31536000; includeSubdomains; preload\r\nVary: Accept, Authorization, Cookie, X-GitHub-OTP\r\nVary: Accept-Encoding, Accept, X-Requested-With\r\nX-Content-Type-Options: nosniff\r\nX-Frame-Options: deny\r\nX-Github-Media-Type: github.mercy-preview; param=nebula-preview; format=json\r\nX-Github-Request-Id: 0740:7B0E:5B2CF6:C2FED9:61F242FD\r\nX-Ratelimit-Limit: 15000\r\nX-Ratelimit-Remaining: 14914\r\nX-Ratelimit-Reset: 1643267605\r\nX-Ratelimit-Resource: core\r\nX-Ratelimit-Used: 86\r\nX-Xss-Protection: 0\r\n\r\n[{\"id\":4307171,\"node_id\":\"MDEwOlJlcG9zaXRvcnk0MzA3MTcx\",\"name\":\"repo-xxxx\",\"full_name\":\"xxxx/repo-xxxx\",\"private\":false,\"owner\":{\"login\":\"xxxx\",\"id\":1874256,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjE4NzQyNTY=\",\"avatar_url\":\"https://avatars.githubusercontent.com/u/1874256?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/xxxx\",\"html_url\":\"https://github.com/xxxx\",\"followers_url\":\"https://api.github.com/users/xxxx/followers\",\"following_url\":\"https://api.github.com/users/xxxx/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/xxxx/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/xxxx/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/xxxx/subscriptions\",\"organizations_url\":\"https://api.github.com/users/xxxx/orgs\",\"repos_url\":\"https://api.github.com/users/xxxx/repos\",\"events_url\":\"https://api.github.com/users/xxxx/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/xxxx/received_events\",\"type\":\"Organization\",\"site_admin\":false},\"html_url\":\"https://github.com/xxxx/repo-xxxx\",\"description\":\"xxxx\",\"fork\":false,\"url\":\"https://api.github.com/repos/xxxx/repo-xxxx\",\"forks_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/forks\",\"keys_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/teams\",\"hooks_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/hooks\",\"issue_events_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/events\",\"assignees_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/tags\",\"blobs_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/languages\",\"stargazers_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/stargazers\",\"contributors_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/contributors\",\"subscribers_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/subscribers\",\"subscription_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/subscription\",\"commits_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/merges\",\"archive_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/downloads\",\"issues_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/xxxx/repo-xxxx/deployments\",\"created_at\":\"2012-05-12T14:47:15Z\",\"updated_at\":\"2021-06-14T02:46:19Z\",\"pushed_at\":\"2021-12-12T11:43:20Z\",\"git_url\":\"git://github.com/xxxx/repo-xxxx.git\",\"ssh_url\":\"[email protected]:xxxx/repo-xxxx.git\",\"clone_url\":\"https://github.com/xxxx/repo-xxxx.git\",\"svn_url\":\"https://github.com/xxxx/repo-xxxx\",\"homepage\":null,\"size\":147,\"stargazers_count\":85,\"watchers_count\":85,\"language\":\"Ruby\",\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":false,\"has_pages\":false,\"forks_count\":68,\"mirror_url\":null,\"archived\":false,\"disabled\":false,\"open_issues_count\":6,\"license\":null,\"allow_forking\":true,\"is_template\":false,\"topics\":[],\"visibility\":\"public\",\"forks\":68,\"open_issues\":6,\"watchers\":85,\"default_branch\":\"master\",\"permissions\":{\"admin\":false,\"maintain\":false,\"push\":false,\"triage\":false,\"pull\":false}}, 2022-01-27T15:49:36.0650855Z { 2022-01-27T15:49:36.0651395Z "level": "info", 2022-01-27T15:49:36.0652074Z "msg": "Running on 0 repositories", 2022-01-27T15:49:36.0653241Z "time": "2022-01-27T15:49:36Z" 2022-01-27T15:49:36.0660835Z }

Running a curl command with the exact same token given to multi-gitter works successfully

Run curl -u :*** -d '{"title":"testPR","base":"main", "head":"test-pr"}' https://api.github.com/repos/xxxx/xxxx/pulls

{
    "url": "https://api.github.com/repos/xxxx/xxxx/pulls/119",
    "id": 833163921,
    "node_id": "PR_kwDOF-zsSs4xqRKR",
    "html_url": "https://github.com/xxxx/xxxx/pull/119",
    "diff_url": "https://github.com/xxxx/xxxx/pull/119.diff",
    "patch_url": "https://github.com/xxxx/xxxx/pull/119.patch",
    "issue_url": "https://api.github.com/repos/xxxx/xxxx/issues/119",
    "number": 119,
    "state": "open",
    "locked": false,
    "title": "testPR",
    "user": {
      "login": "xxxx[bot]",
      "id": 93331094,
      "node_id": "BOT_kgDOBZAelg",
      "avatar_url": "https://avatars.githubusercontent.com/u/1874256?v=4",
      "gravatar_id": "",
      "url": "https://api.github.com/users/xxxx%5Bbot%5D",
      "html_url": "https://github.com/apps/xxxx",
      "followers_url": "https://api.github.com/users/xxxx%5Bbot%5D/followers",
      "following_url": "https://api.github.com/users/xxxx%5Bbot%5D/following{/other_user}",
      "gists_url": "https://api.github.com/users/xxxx%5Bbot%5D/gists{/gist_id}",
      "starred_url": "https://api.github.com/users/xxxx%5Bbot%5D/starred{/owner}{/repo}",
      "subscriptions_url": "https://api.github.com/users/xxxx%5Bbot%5D/subscriptions",
      "organizations_url": "https://api.github.com/users/xxxx%5Bbot%5D/orgs",
      "repos_url": "https://api.github.com/users/xxxx%5Bbot%5D/repos",
      "events_url": "https://api.github.com/users/xxxx%5Bbot%5D/events{/privacy}",
      "received_events_url": "https://api.github.com/users/xxxx%5Bbot%5D/received_events",
      "type": "Bot",
      "site_admin": false
    },
    "body": null,
    "created_at": "2022-01-27T08:29:13Z",
    "updated_at": "2022-01-27T08:29:13Z",
    "closed_at": null,
    "merged_at": null,
    "merge_commit_sha": null,
    "assignee": null,
    "assignees": [
  
    ],
    "requested_reviewers": [
  
    ],
    "requested_teams": [
      {
        "name": "xxxx",
        "id": 5003304,
        "node_id": "T_kwDOAByZUM4ATFgo",
        "slug": "xxxx",
        "description": "",
        "privacy": "closed",
        "url": "https://api.github.com/organizations/1874256/team/5003304",
        "html_url": "https://github.com/orgs/xxxx/teams/xxxx",
        "members_url": "https://api.github.com/organizations/1874256/team/5003304/members{/member}",
        "repositories_url": "https://api.github.com/organizations/1874256/team/5003304/repos",
        "permission": "pull",
        "parent": null
      }
    ],
    "labels": [
  
    ],
    "milestone": null,
    "draft": false,
    "commits_url": "https://api.github.com/repos/xxxx/xxxx/pulls/119/commits",
    "review_comments_url": "https://api.github.com/repos/xxxx/xxxx/pulls/119/comments",
    "review_comment_url": "https://api.github.com/repos/xxxx/xxxx/pulls/comments{/number}",
    "comments_url": "https://api.github.com/repos/xxxx/xxxx/issues/119/comments",
    "statuses_url": "https://api.github.com/repos/xxxx/xxxx/statuses/0b850dbb4f98bd4f6f68d2f595f8fe15752a72c0",
    "head": {
      "label": "xxxx:xxxx",
      "ref": "xxxx",
      "sha": "0b850dbb4f98bd4f6f68d2f595f8fe15752a72c0",
      "user": {
        "login": "xxxx",
        "id": 1874256,
        "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NzQyNTY=",
        "avatar_url": "https://avatars.githubusercontent.com/u/1874256?v=4",
        "gravatar_id": "",
        "url": "https://api.github.com/users/xxxx",
        "html_url": "https://github.com/xxxx",
        "followers_url": "https://api.github.com/users/xxxx/followers",
        "following_url": "https://api.github.com/users/xxxx/following{/other_user}",
        "gists_url": "https://api.github.com/users/xxxx/gists{/gist_id}",
        "starred_url": "https://api.github.com/users/xxxx/starred{/owner}{/repo}",
        "subscriptions_url": "https://api.github.com/users/xxxx/subscriptions",
        "organizations_url": "https://api.github.com/users/xxxx/orgs",
        "repos_url": "https://api.github.com/users/xxxx/repos",
        "events_url": "https://api.github.com/users/xxxx/events{/privacy}",
        "received_events_url": "https://api.github.com/users/xxxx/received_events",
        "type": "Organization",
        "site_admin": false
      },
      "repo": {
        "id": 401402954,
        "node_id": "MDEwOlJlcG9zaXRvcnk0MDE0MDI5NTQ=",
        "name": "xxxx",
        "full_name": "xxxx/xxxx",
        "private": true,
        "owner": {
          "login": "xxxx",
          "id": 1874256,
          "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NzQyNTY=",
          "avatar_url": "https://avatars.githubusercontent.com/u/1874256?v=4",
          "gravatar_id": "",
          "url": "https://api.github.com/users/xxxx",
          "html_url": "https://github.com/xxxx",
          "followers_url": "https://api.github.com/users/xxxx/followers",
          "following_url": "https://api.github.com/users/xxxx/following{/other_user}",
          "gists_url": "https://api.github.com/users/xxxx/gists{/gist_id}",
          "starred_url": "https://api.github.com/users/xxxx/starred{/owner}{/repo}",
          "subscriptions_url": "https://api.github.com/users/xxxx/subscriptions",
          "organizations_url": "https://api.github.com/users/xxxx/orgs",
          "repos_url": "https://api.github.com/users/xxxx/repos",
          "events_url": "https://api.github.com/users/xxxx/events{/privacy}",
          "received_events_url": "https://api.github.com/users/xxxx/received_events",
          "type": "Organization",
          "site_admin": false
        },
        "html_url": "https://github.com/xxxx/xxxx",
        "description": "xxxx",
        "fork": false,
        "url": "https://api.github.com/repos/xxxx/xxxx",
        "forks_url": "https://api.github.com/repos/xxxx/xxxx/forks",
        "keys_url": "https://api.github.com/repos/xxxx/xxxx/keys{/key_id}",
        "collaborators_url": "https://api.github.com/repos/xxxx/xxxx/collaborators{/collaborator}",
        "teams_url": "https://api.github.com/repos/xxxx/xxxx/teams",
        "hooks_url": "https://api.github.com/repos/xxxx/xxxx/hooks",
        "issue_events_url": "https://api.github.com/repos/xxxx/xxxx/issues/events{/number}",
        "events_url": "https://api.github.com/repos/xxxx/xxxx/events",
        "assignees_url": "https://api.github.com/repos/xxxx/xxxx/assignees{/user}",
        "branches_url": "https://api.github.com/repos/xxxx/xxxx/branches{/branch}",
        "tags_url": "https://api.github.com/repos/xxxx/xxxx/tags",
        "blobs_url": "https://api.github.com/repos/xxxx/xxxx/git/blobs{/sha}",
        "git_tags_url": "https://api.github.com/repos/xxxx/xxxx/git/tags{/sha}",
        "git_refs_url": "https://api.github.com/repos/xxxx/xxxx/git/refs{/sha}",
        "trees_url": "https://api.github.com/repos/xxxx/xxxx/git/trees{/sha}",
        "statuses_url": "https://api.github.com/repos/xxxx/xxxx/statuses/{sha}",
        "languages_url": "https://api.github.com/repos/xxxx/xxxx/languages",
        "stargazers_url": "https://api.github.com/repos/xxxx/xxxx/stargazers",
        "contributors_url": "https://api.github.com/repos/xxxx/xxxx/contributors",
        "subscribers_url": "https://api.github.com/repos/xxxx/xxxx/subscribers",
        "subscription_url": "https://api.github.com/repos/xxxx/xxxx/subscription",
        "commits_url": "https://api.github.com/repos/xxxx/xxxx/commits{/sha}",
        "git_commits_url": "https://api.github.com/repos/xxxx/xxxx/git/commits{/sha}",
        "comments_url": "https://api.github.com/repos/xxxx/xxxx/comments{/number}",
        "issue_comment_url": "https://api.github.com/repos/xxxx/xxxx/issues/comments{/number}",
        "contents_url": "https://api.github.com/repos/xxxx/xxxx/contents/{+path}",
        "compare_url": "https://api.github.com/repos/xxxx/xxxx/compare/{base}...{head}",
        "merges_url": "https://api.github.com/repos/xxxx/xxxx/merges",
        "archive_url": "https://api.github.com/repos/xxxx/xxxx/{archive_format}{/ref}",
        "downloads_url": "https://api.github.com/repos/xxxx/xxxx/downloads",
        "issues_url": "https://api.github.com/repos/xxxx/xxxx/issues{/number}",
        "pulls_url": "https://api.github.com/repos/xxxx/xxxx/pulls{/number}",
        "milestones_url": "https://api.github.com/repos/xxxx/xxxx/milestones{/number}",
        "notifications_url": "https://api.github.com/repos/xxxx/xxxx/notifications{?since,all,participating}",
        "labels_url": "https://api.github.com/repos/xxxx/xxxx/labels{/name}",
        "releases_url": "https://api.github.com/repos/xxxx/xxxx/releases{/id}",
        "deployments_url": "https://api.github.com/repos/xxxx/xxxx/deployments",
        "created_at": "2021-08-30T15:58:05Z",
        "updated_at": "2022-01-06T21:20:03Z",
        "pushed_at": "2022-01-27T08:28:16Z",
        "git_url": "git://github.com/xxxx/xxxx.git",
        "ssh_url": "[email protected]:xxxx/xxxx.git",
        "clone_url": "https://github.com/xxxx/xxxx.git",
        "svn_url": "https://github.com/xxxx/xxxx",
        "homepage": "",
        "size": 37501,
        "stargazers_count": 0,
        "watchers_count": 0,
        "language": "Python",
        "has_issues": false,
        "has_projects": false,
        "has_downloads": false,
        "has_wiki": false,
        "has_pages": false,
        "forks_count": 0,
        "mirror_url": null,
        "archived": false,
        "disabled": false,
        "open_issues_count": 4,
        "license": null,
        "allow_forking": true,
        "is_template": false,
        "topics": [
  
        ],
        "visibility": "internal",
        "forks": 0,
        "open_issues": 4,
        "watchers": 0,
        "default_branch": "main"
      }
    },
    "base": {
      "label": "xxxx:main",
      "ref": "main",
      "sha": "f38a4b8bb8a1ee8a72e045fb94f73ca009b5bff7",
      "user": {
        "login": "xxxx",
        "id": 1874256,
        "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NzQyNTY=",
        "avatar_url": "https://avatars.githubusercontent.com/u/1874256?v=4",
        "gravatar_id": "",
        "url": "https://api.github.com/users/xxxx",
        "html_url": "https://github.com/xxxx",
        "followers_url": "https://api.github.com/users/xxxx/followers",
        "following_url": "https://api.github.com/users/xxxx/following{/other_user}",
        "gists_url": "https://api.github.com/users/xxxx/gists{/gist_id}",
        "starred_url": "https://api.github.com/users/xxxx/starred{/owner}{/repo}",
        "subscriptions_url": "https://api.github.com/users/xxxx/subscriptions",
        "organizations_url": "https://api.github.com/users/xxxx/orgs",
        "repos_url": "https://api.github.com/users/xxxx/repos",
        "events_url": "https://api.github.com/users/xxxx/events{/privacy}",
        "received_events_url": "https://api.github.com/users/xxxx/received_events",
        "type": "Organization",
        "site_admin": false
      },
      "repo": {
        "id": 401402954,
        "node_id": "MDEwOlJlcG9zaXRvcnk0MDE0MDI5NTQ=",
        "name": "xxxx",
        "full_name": "xxxx/xxxx",
        "private": true,
        "owner": {
          "login": "xxxx",
          "id": 1874256,
          "node_id": "MDEyOk9yZ2FuaXphdGlvbjE4NzQyNTY=",
          "avatar_url": "https://avatars.githubusercontent.com/u/1874256?v=4",
          "gravatar_id": "",
          "url": "https://api.github.com/users/xxxx",
          "html_url": "https://github.com/xxxx",
          "followers_url": "https://api.github.com/users/xxxx/followers",
          "following_url": "https://api.github.com/users/xxxx/following{/other_user}",
          "gists_url": "https://api.github.com/users/xxxx/gists{/gist_id}",
          "starred_url": "https://api.github.com/users/xxxx/starred{/owner}{/repo}",
          "subscriptions_url": "https://api.github.com/users/xxxx/subscriptions",
          "organizations_url": "https://api.github.com/users/xxxx/orgs",
          "repos_url": "https://api.github.com/users/xxxx/repos",
          "events_url": "https://api.github.com/users/xxxx/events{/privacy}",
          "received_events_url": "https://api.github.com/users/xxxx/received_events",
          "type": "Organization",
          "site_admin": false
        },
        "html_url": "https://github.com/xxxx/xxxx",
        "description": "xxxx",
        "fork": false,
        "url": "https://api.github.com/repos/xxxx/xxxx",
        "forks_url": "https://api.github.com/repos/xxxx/xxxx/forks",
        "keys_url": "https://api.github.com/repos/xxxx/xxxx/keys{/key_id}",
        "collaborators_url": "https://api.github.com/repos/xxxx/xxxx/collaborators{/collaborator}",
        "teams_url": "https://api.github.com/repos/xxxx/xxxx/teams",
        "hooks_url": "https://api.github.com/repos/xxxx/xxxx/hooks",
        "issue_events_url": "https://api.github.com/repos/xxxx/xxxx/issues/events{/number}",
        "events_url": "https://api.github.com/repos/xxxx/xxxx/events",
        "assignees_url": "https://api.github.com/repos/xxxx/xxxx/assignees{/user}",
        "branches_url": "https://api.github.com/repos/xxxx/xxxx/branches{/branch}",
        "tags_url": "https://api.github.com/repos/xxxx/xxxx/tags",
        "blobs_url": "https://api.github.com/repos/xxxx/xxxx/git/blobs{/sha}",
        "git_tags_url": "https://api.github.com/repos/xxxx/xxxx/git/tags{/sha}",
        "git_refs_url": "https://api.github.com/repos/xxxx/xxxx/git/refs{/sha}",
        "trees_url": "https://api.github.com/repos/xxxx/xxxx/git/trees{/sha}",
        "statuses_url": "https://api.github.com/repos/xxxx/xxxx/statuses/{sha}",
        "languages_url": "https://api.github.com/repos/xxxx/xxxx/languages",
        "stargazers_url": "https://api.github.com/repos/xxxx/xxxx/stargazers",
        "contributors_url": "https://api.github.com/repos/xxxx/xxxx/contributors",
        "subscribers_url": "https://api.github.com/repos/xxxx/xxxx/subscribers",
        "subscription_url": "https://api.github.com/repos/xxxx/xxxx/subscription",
        "commits_url": "https://api.github.com/repos/xxxx/xxxx/commits{/sha}",
        "git_commits_url": "https://api.github.com/repos/xxxx/xxxx/git/commits{/sha}",
        "comments_url": "https://api.github.com/repos/xxxx/xxxx/comments{/number}",
        "issue_comment_url": "https://api.github.com/repos/xxxx/xxxx/issues/comments{/number}",
        "contents_url": "https://api.github.com/repos/xxxx/xxxx/contents/{+path}",
        "compare_url": "https://api.github.com/repos/xxxx/xxxx/compare/{base}...{head}",
        "merges_url": "https://api.github.com/repos/xxxx/xxxx/merges",
        "archive_url": "https://api.github.com/repos/xxxx/xxxx/{archive_format}{/ref}",
        "downloads_url": "https://api.github.com/repos/xxxx/xxxx/downloads",
        "issues_url": "https://api.github.com/repos/xxxx/xxxx/issues{/number}",
        "pulls_url": "https://api.github.com/repos/xxxx/xxxx/pulls{/number}",
        "milestones_url": "https://api.github.com/repos/xxxx/xxxx/milestones{/number}",
        "notifications_url": "https://api.github.com/repos/xxxx/xxxx/notifications{?since,all,participating}",
        "labels_url": "https://api.github.com/repos/xxxx/xxxx/labels{/name}",
        "releases_url": "https://api.github.com/repos/xxxx/xxxx/releases{/id}",
        "deployments_url": "https://api.github.com/repos/xxxx/xxxx/deployments",
        "created_at": "2021-08-30T15:58:05Z",
        "updated_at": "2022-01-06T21:20:03Z",
        "pushed_at": "2022-01-27T08:28:16Z",
        "git_url": "git://github.com/xxxx/xxxx.git",
        "ssh_url": "[email protected]:xxxx/xxxx.git",
        "clone_url": "https://github.com/xxxx/xxxx.git",
        "svn_url": "https://github.com/xxxx/xxxx",
        "homepage": "",
        "size": 37501,
        "stargazers_count": 0,
        "watchers_count": 0,
        "language": "Python",
        "has_issues": false,
        "has_projects": false,
        "has_downloads": false,
        "has_wiki": false,
        "has_pages": false,
        "forks_count": 0,
        "mirror_url": null,
        "archived": false,
        "disabled": false,
        "open_issues_count": 4,
        "license": null,
        "allow_forking": true,
        "is_template": false,
        "topics": [
  
        ],
        "visibility": "internal",
        "forks": 0,
        "open_issues": 4,
        "watchers": 0,
        "default_branch": "main"
      }
    },
    "_links": {
      "self": {
        "href": "https://api.github.com/repos/xxxx/xxxx/pulls/119"
      },
      "html": {
        "href": "https://github.com/xxxx/xxxx/pull/119"
      },
      "issue": {
        "href": "https://api.github.com/repos/xxxx/xxxx/issues/119"
      },
      "comments": {
        "href": "https://api.github.com/repos/xxxx/xxxx/issues/119/comments"
      },
      "review_comments": {
        "href": "https://api.github.com/repos/xxxx/xxxx/pulls/119/comments"
      },
      "review_comment": {
        "href": "https://api.github.com/repos/xxxx/xxxx/pulls/comments{/number}"
      },
      "commits": {
        "href": "https://api.github.com/repos/xxxx/xxxx/pulls/119/commits"
      },
      "statuses": {
        "href": "https://api.github.com/repos/xxxx/xxxx/statuses/0b850dbb4f98bd4f6f68d2f595f8fe15752a72c0"
      }
    },
    "author_association": "NONE",
    "auto_merge": null,
    "active_lock_reason": null,
    "merged": false,
    "mergeable": null,
    "rebaseable": null,
    "mergeable_state": "unknown",
    "merged_by": null,
    "comments": 0,
    "review_comments": 0,
    "maintainer_can_modify": false,
    "commits": 1,
    "additions": 17,
    "deletions": 0,
    "changed_files": 1
  }

Expected behavior
multi-gitter includes an option(or just accepts) to use a github app installation token and runs against repos it finds.

This is related to #223

Unable to commit to main branch with 'confict-strategy=replace' "A branch named 'main' already exists.

Describe the bug
A clear and concise description of what the bug is.

Even with conflict strategy set to 'replace' I still cannot get multi gitter to create a commit directly to main.

To Reproduce
Steps to reproduce the behavior:

  1. Run multi-gitter with branch set to 'main' and conflict-strategy set to replace with dry-run=true
multi-gitter run -B main -L debug --dry-run=true --repo <redacted> --conflict-strategy=replace --commit-message=TEST --git-type=cmd ./update_namespace.sh
INFO[0000] Running on 1 repositories                    
INFO[0000] Cloning and running script                    repo=<redacted>
INFO[0001] A branch named 'main' already exists.         repo=<redacted>
A branch named 'main' already exists.:
  <redacted>

Expected behavior

Multi gitter to display the diff between current main and proposed changes.

Additional context
I have tried with both types of git (cmd and go) with the same result. I have also tried setting the configuration from the config.yml and the command line options.

Any help much appreciated :)

Add flag to update a pull request thats already opened

After I've run multi-gitter and opened my prs, it would be great to have the ability to update my pr in the scenario where maybe I've missed something, or make a mistake and need to update.

Something like a 'multi-gitter run --update-pr`

Support GitHub App Tokens

Describe the bug
It would be great if this tool supported GitHub Apps (https://docs.github.com/en/developers/apps/building-github-apps/authenticating-with-github-apps), rather than having to use a PAT tied to a specific user, one could implement "bot" like behaviours. An installation token provided by the github app is very similar to a users PAT, and could be run from github actions. Right now when running multi-gitter with trace debugging, I can see it can read all of the repos in an org, but it won't open any PRs.

To Reproduce
Steps to reproduce the behavior:

  1. Install a github app in an organization
  2. Retrieve an installation token from the app
  3. Use the installation token with multi-gitter

Additional context

2022-01-25T05:46:32.0830234Z   "host": "api.github.com",
2022-01-25T05:46:32.0830929Z   "level": "trace",
2022-01-25T05:46:32.0831238Z   "msg": "http request",
2022-01-25T05:46:32.0832527Z   "request": "GET /orgs/xxxxx/repos?page=1\u0026per_page=100 HTTP/1.1\r\nHost: api.github.com\r\nUser-Agent: go-github\r\nAccept: application/vnd.github.mercy-preview+json, application/vnd.github.nebula-preview+json\r\nAccept-Encoding: gzip\r\n\r\n",

โซ returned all of the repos I was expecting

2022-01-25T05:46:36.0067099Z   "level": "info",
2022-01-25T05:46:36.0067356Z   "msg": "Running on 0 repositories",
2022-01-25T05:46:36.0067650Z   "time": "2022-01-25T05:46:35Z"
2022-01-25T05:46:36.0067851Z }

But it ran against none of them. If I switch to a PAT, this works as expected but isn't ideal for large workloads.

Fine-grained personal access tokens not supported by multi-gitter

Describe the bug
Multi-gitter does not seem to work with the fine-grained personal access tokens that are currently in beta

image

To Reproduce
Steps to reproduce the behavior:

  1. Create a fine-grained personal access token
  2. Run multi-gitter merge ....
  3. See error
$ multi-gitter merge -U klieret --branch "dependabot/github_actions/actions/upload-artifact-3" --merge-type squash  

Error: unexpected end of JSON input
Usage:
  multi-gitter merge [flags]

Flags:
  -g, --base-url string      Base URL of the GitHub API, needs to be changed if GitHub enterprise is used. Or the url to a self-hosted GitLab instance.
  -B, --branch string        The name of the branch where changes are committed. (default "multi-gitter-branch")
      --config string        Path of the config file.
      --fork                 Use pull requests made from forks instead of from the same repository.
      --fork-owner string    If set, use forks from the defined value instead of the logged in user.
  -G, --group strings        The name of a GitLab organization. All repositories in that group will be used.
  -h, --help                 help for merge
      --include-subgroups    Include GitLab subgroups when using the --group flag.
      --insecure             Insecure controls whether a client verifies the server certificate chain and host name. Used only for Bitbucket server.
      --log-file string      The file where all logs should be printed to. "-" means stdout. (default "-")
      --log-format string    The formating of the logs. Available values: text, json, json-pretty. (default "text")
  -L, --log-level string     The level of logging that should be made. Available values: trace, debug, info, error. (default "info")
      --merge-type strings   The type of merge that should be done (GitHub). Multiple types can be used as backup strategies if the first one is not allowed. (default [merge,squash,rebase])
  -O, --org strings          The name of a GitHub organization. All repositories in that organization will be used.
  -p, --platform string      The platform that is used. Available values: github, gitlab, gitea, bitbucket_server. (default "github")
  -P, --project strings      The name, including owner of a GitLab project in the format "ownerName/repoName".
  -R, --repo strings         The name, including owner of a GitHub repository in the format "ownerName/repoName".
      --ssh-auth             Use SSH cloning URL instead of HTTPS + token. This requires that a setup with ssh keys that have access to all repos and that the server is already in known_hosts.
  -T, --token string         The GitHub/GitLab personal access token. Can also be set using the GITHUB_TOKEN/GITLAB_TOKEN/GITEA_TOKEN/BITBUCKET_SERVER_TOKEN environment variable.
  -U, --user strings         The name of a user. All repositories owned by that user will be used.
  -u, --username string      The Bitbucket server username.

unexpected end of JSON input

Additional context

I double checked that I had copied the token correctly.
After switching back to a classical token, everything worked as expected.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.