lindell / multi-gitter Goto Github PK
View Code? Open in Web Editor NEWUpdate multiple repositories in with one command
License: Apache License 2.0
Update multiple repositories in with one command
License: Apache License 2.0
How can newlines be added to the commit message or the PR text?
Sometimes I'd like to have my PR body text on multiple lines.
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.
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*
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:
multi-gitter/internal/multigitter/run.go
Line 202 in c12fb13
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.
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.
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?
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
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..
It would be awesome if multi-gitter supported adding GitHub PR labels!
Describe the bug
Should be able to understand signing commits
To Reproduce
Steps to reproduce the behavior:
multi-gitter run -xxx
git verify-commit HEAD
Expected behavior
Commits are signed
Additional context
Changing git-type
to cmd
does not work
git-type: cmd
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
This should is important for repos where different types of PR merges (merge, squash, rebase, etc.) is restricted.
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
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`
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
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
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
I think it would be a good enhancement to optionally specify pull request assignees (and not just 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.
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.
$ 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
Describe the bug
Multi-gitter does not seem to work with the fine-grained personal access tokens that are currently in beta
To Reproduce
Steps to reproduce the behavior:
multi-gitter merge ....
$ 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.
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
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.
Add a configuration option which allows you skip certain projects from a configuration, like this:
group:
- acme
skip-projects:
- acme/no-merge-request
Looking into the code and excusing my lack of Go knowledge:
I think it may be possible to the remove entries from the project list that gets generated.
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.
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.
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:
multi-gitter status
(did not try other commands)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 {
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
status
command for PR in step 1Expected 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 ๐๐ผ
@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
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
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:
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
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
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"'
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:
multi-gitter/internal/scm/gitlab/gitlab.go
Lines 70 to 80 in cb4701e
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! ๐๐พ
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!
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.
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
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.
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
multi-gitter/internal/scm/gitlab/gitlab.go
Line 393 in bb08990
Instead the Merge Request should be updated with the state_event: close
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.
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:
conflict-strategy: replace
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.
To be sure that no token exist in the logs when trace-logs are shared. Make sure to hide tokens in it.
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.
It would be nice if multi-gitter
run had a --draft
option to create GH PRs in draft mode. This is useful in case the run script doesn't support some edge case in one of the repos, and we can spot check PRs before marking them ready-for-review.
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:
multi-gitter merge -xxx
Expected behavior
The 422 error is caught and ignored. Processing of repositories continue
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).
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.
Just like the other commands, allow a YAML config for the status
command, since all required options are already configured there in my case.
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:
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 :)
Gitea is a popular self-hosted SCM and it would be good to have support for it in multi-gitter.
If anyone is familiar with Gitea 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
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:
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.
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:
multi-gitter run "python3 $PWD/change.py" --config spec.yaml --project owner/myproj --reviewers rev1,rev2,rev3 --assignees as1
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.