Giter Site home page Giter Site logo

marge-bot's Introduction

Marge-bot Test

Marge-bot is a merge-bot for GitLab that, beside other goodies, implements the Not Rocket Science Rule Of Software Engineering:

automatically maintain a repository of code that always passes all the tests.

— Graydon Hoare, main author of Rust

This simple rule of thumb is still nowadays surprisingly difficult to implement with the state-of-the-art tools, and more so in a way that scales with team size (also see our blog post).

Take, for instance, GitHub's well-known pull-request workflow. Here, CI needs to pass on the branch before the pull request can be accepted but after that, the branch is immediately merged (or rebased) into master. By the time this happens, enough changes may have occurred to induce test breakage, but this is only to be found out when the commits have already landed.

GitLab (in their enterprise edition), offers an important improvement here with their semi-linear history and fast-forward merge request methods: in both cases a merge request can only be accepted if the resulting master branch will be effectively the same as the merge request branch on which CI has passed. If master has changed since the tests were last run, it is the user's responsibility to rebase the changes and retry. But this just doesn't scale: if you have, a mono-repo, a large team working on short-lived branches, a CI pipeline that takes 5-10 minutes to complete... then the number of times one need's to rebase-and-try-to-accept starts to become unbearable.

Marge-bot offers the simplest of workflows: when a merge-request is ready, just assign it to its user, and let her do all the rebase-wait-retry for you. If anything goes wrong (merge conflicts, tests that fail, etc.) she'll leave a message on the merge-request, so you'll get notified. Marge-bot can handle an adversarial environment where some developers prefer to merge their own changes, so the barrier for adoption is really low.

Whether marge-bot will or not wait for pipeline to succeed depends on the value of "✓ Pipelines must succeed" checkbox in your repo. It is available in all Gitlab versions, so should not be a barrier.

Since she is at it, she can optionally provide some other goodies like tagging of commits (e.g. Reviewed-by: ...) or preventing merges during certain hours.

Configuring

Args that start with '--' (eg. --auth-token) can also be set in a config file (specified via --config-file). The config file uses YAML syntax and must represent a YAML 'mapping' (for details, see http://learn.getgrav.org/advanced/yaml). If an arg is specified in more than one place, then commandline values override environment variables which override config file values which override defaults.

optional arguments:
  -h, --help            show this help message and exit
  --config-file CONFIG_FILE
                        config file path   [env var: MARGE_CONFIG_FILE] (default: None)
  --auth-token TOKEN    Your GitLab token.
                        DISABLED because passing credentials on the command line is insecure:
                        You can still set it via ENV variable or config file, or use "--auth-token-file" flag.
                           [env var: MARGE_AUTH_TOKEN] (default: None)
  --auth-token-file FILE
                        Path to your GitLab token file.
                           [env var: MARGE_AUTH_TOKEN_FILE] (default: None)
  --gitlab-url URL      Your GitLab instance, e.g. "https://gitlab.example.com".
                           [env var: MARGE_GITLAB_URL] (default: None)
  --use-https           use HTTP(S) instead of SSH for GIT repository access
                           [env var: MARGE_USE_HTTPS] (default: False)
  --ssh-key KEY         The private ssh key for marge so it can clone/push.
                        DISABLED because passing credentials on the command line is insecure:
                        You can still set it via ENV variable or config file, or use "--ssh-key-file" flag.
                           [env var: MARGE_SSH_KEY] (default: None)
  --ssh-key-file FILE   Path to the private ssh key for marge so it can clone/push.
                           [env var: MARGE_SSH_KEY_FILE] (default: None)
  --embargo INTERVAL[,..]
                        Time(s) during which no merging is to take place, e.g. "Friday 1pm - Monday 9am".
                           [env var: MARGE_EMBARGO] (default: None)
  --use-merge-strategy  Use git merge instead of git rebase to update the *source* branch (EXPERIMENTAL)
                        If you need to use a strict no-rebase workflow (in most cases
                        you don't want this, even if you configured gitlab to use merge requests
                        to use merge commits on the *target* branch (the default).)
                           [env var: MARGE_USE_MERGE_STRATEGY] (default: False)
  --rebase-remotely     Instead of rebasing in a local clone of the repository, use GitLab's
                        built-in rebase functionality, via their API. Note that Marge can't add
                        information in the commits in this case.
                           [env var: MARGE_REBASE_REMOTELY] (default: False)
  --add-tested          Add "Tested: marge-bot <$MR_URL>" for the final commit on branch after it passed CI.
                           [env var: MARGE_ADD_TESTED] (default: False)
  --batch               Enable processing MRs in batches
                           [env var: MARGE_BATCH] (default: False)
  --add-part-of         Add "Part-of: <$MR_URL>" to each commit in MR.
                           [env var: MARGE_ADD_PART_OF] (default: False)
  --add-reviewers       Add "Reviewed-by: $approver" for each approver of MR to each commit in MR.
                           [env var: MARGE_ADD_REVIEWERS] (default: False)
  --impersonate-approvers
                        Marge-bot pushes effectively don't change approval status.
                           [env var: MARGE_IMPERSONATE_APPROVERS] (default: False)
  --merge-order {created_at,updated_at,assigned_at}
                        Order marge merges assigned requests. created_at (default), updated_at or assigned_at.
                           [env var: MARGE_MERGE_ORDER] (default: created_at)
  --approval-reset-timeout APPROVAL_RESET_TIMEOUT
                        How long to wait for approvals to reset after pushing.
                        Only useful with the "new commits remove all approvals" option in a project's settings.
                        This is to handle the potential race condition where approvals don't reset in GitLab
                        after a force push due to slow processing of the event.
                           [env var: MARGE_APPROVAL_RESET_TIMEOUT] (default: 0s)
  --project-regexp PROJECT_REGEXP
                        Only process projects that match; e.g. 'some_group/.*' or '(?!exclude/me)'.
                           [env var: MARGE_PROJECT_REGEXP] (default: .*)
  --ci-timeout CI_TIMEOUT
                        How long to wait for CI to pass.
                           [env var: MARGE_CI_TIMEOUT] (default: 15min)
  --max-ci-time-in-minutes MAX_CI_TIME_IN_MINUTES
                        Deprecated; use --ci-timeout.
                           [env var: MARGE_MAX_CI_TIME_IN_MINUTES] (default: None)
  --git-timeout GIT_TIMEOUT
                        How long a single git operation can take.
                           [env var: MARGE_GIT_TIMEOUT] (default: 120s)
  --git-reference-repo GIT_REFERENCE_REPO
                        A reference repo to be used when git cloning.
                           [env var: MARGE_GIT_REFERENCE_REPO] (default: None)
  --branch-regexp BRANCH_REGEXP
                        Only process MRs whose target branches match the given regular expression.
                           [env var: MARGE_BRANCH_REGEXP] (default: .*)
  --source-branch-regexp SOURCE_BRANCH_REGEXP
                        Only process MRs whose source branches match the given regular expression.
                           [env var: MARGE_SOURCE_BRANCH_REGEXP] (default: .*)
  --debug               Debug logging (includes all HTTP requests etc).
                           [env var: MARGE_DEBUG] (default: False)
  --cli                 Run marge-bot as a single CLI command, not as a long-running service.
                        This may be used to run marge-bot in scheduled CI pipelines or cronjobs.
                           [env var: MARGE_CLI] (default: False)
  --use-no-ff-batches   Disable fast forwarding when merging MR batches   [env var: MARGE_USE_NO_FF_BATCHES] (default: False)
  --use-merge-commit-batches
                        Use merge commit when creating batches, so that the commits in the batch MR will be the same with in individual MRs. Requires sudo scope in the access token.
                           [env var: MARGE_USE_MERGE_COMMIT_BATCHES] (default: False)
  --skip-ci-batches     Skip CI when updating individual MRs when using batches   [env var: MARGE_SKIP_CI_BATCHES] (default: False)

Here is a config file example

add-part-of: true
add-reviewers: true
add-tested: true
# choose one way of specifying the Auth token
#auth-token: TOKEN
auth-token-file: token.FILE
branch-regexp: .*
ci-timeout: 15min
embargo: Friday 1pm - Monday 9am
batch: false
git-timeout: 120s
gitlab-url: "https://gitlab.example.com"
impersonate-approvers: true
project-regexp: .*
# choose one way of specifying the SSH key
#ssh-key: KEY
ssh-key-file: token.FILE
# OR use HTTPS instead of SSH
#use-https: true

For more information about configuring marge-bot see --help

Running

First, create a user for Marge-bot on your GitLab. We'll use marge-bot as username here as well. GitLab sorts users by Name, so we recommend you pick one that starts with a space, e.g.  Marge Bot, so it is quicker to assign to (our code strips trailing whitespace in the name, so it won't show up elsewhere). Then add marge-bot to your projects as Developer or Maintainer, the latter being required if she will merge to protected branches.

For certain features, namely, --impersonate-approvers, and --add-reviewers, you will need to grant marge-bot admin privileges as well. In the latter, so that she can query the email of the reviewers to include it in the commit. Note that if you're trying to run marge-bot against a GitLab instance you don't have yourself admin access to (e.g. https://www.gitlab.com), you won't be able to use features that require admin for marge-bot.

Second, you need an authentication token for the marge-bot user. You will need to select the api and read_user scopes in all cases.

If marge-bot was made an admin to handle approver impersonation and/or adding a reviewed-by field, then you will also need to add sudo scope under Impersonation Tokens in the User Settings. Assuming your GitLab install is install is https://your-gitlab.example.com the link will be at https://your-gitlab.example.com/admin/users/marge-bot/impersonation_tokens).

On older GitLab installs, to be able to use impersonation features if marge-bot was made an admin, use the PRIVATE TOKEN found in marge-bot's Profile Settings; otherwise just use a personal token (you will need to impersonate the marge-bot user via the admin UI to get the private token, it should then be at http://my-gitlab.example.com/profile/personal_access_tokens reachable via Profile Settings -> Acess Tokens).

Once you have the token, put it in a file, e.g. marge-bot.token.

Finally, create a new ssh key-pair, e.g like so

ssh-keygen -t ed25519 -C marge-bot@invalid -f marge-bot-ssh-key -P ''

Add the public key (marge-bot-ssh-key.pub) to the user's SSH Keys in GitLab and keep the private one handy.

Running marge-bot in docker using SSH (what we do)

Assuming you have already got docker installed, the quickest and most minimal way to run marge is like so (but see note about passing secrets on the commandline below):

docker run --restart=on-failure \ # restart if marge crashes because GitLab is flaky
  -e MARGE_AUTH_TOKEN="$(cat marge-bot.token)" \
  -e MARGE_SSH_KEY="$(cat marge-bot-ssh-key)" \
  smarkets/marge-bot \
  --gitlab-url='http://your.gitlab.instance.com'

Note that other users on the machine can see the secrets in ps, because although they are env vars inside docker, we used a commandline switch to set them for docker run.

To avoid that you have several options. You can just use a yaml file and mount that into the container, for example this is how we actually run marge-bot at Smarkets ourselves:

# marge-bot-config.yml
add-part-of: true
add-reviewers: true
add-tested: true
impersonate-approvers: true
gitlab-url: "https://git.corp.smarkets.com"
project-regexp: "smarkets/smarkets$"
auth-token: "WoNtTelly0u"
ssh-key: |
    -----BEGIN OPENSSH PRIVATE KEY-----
    [...]
    -----END OPENSSH PRIVATE KEY-----
docker run --restart=on-failure \
  -v "$(pwd)":/configuration \
  smarkets/marge-bot \
  --config-file=/configuration/marge-bot-config.yaml

By default docker will use the latest tag, which corresponds to the latest stable version. You can also use the stable tag to make this more explicit. If you want a development version, you can use the master tag to obtain an image built from the HEAD commit of the master branch. Note that this image may contain bugs.

You can also specify a particular version as a tag, e.g. smarkets/marge-bot:0.7.0.

Running marge-bot in docker using HTTPS

It is also possible to use Git over HTTPS instead of Git over SSH. To use HTTPS instead of SSH, add the --use-https flag and do not provide any SSH keys. Alternatively you can set the environment variable MARGE_USE_HTTPS or the config file property use-https.

docker run --restart=on-failure \ # restart if marge crashes because GitLab is flaky
  -e MARGE_AUTH_TOKEN="$(cat marge-bot.token)" \
  smarkets/marge-bot \
  --use-https \
  --gitlab-url='http://your.gitlab.instance.com'

HTTPS can be used using any other deployment technique as well.

Running marge-bot in kubernetes

It's also possible to run marge in kubernetes, e.g. here's how you use a ktmpl template:

ktmpl ./deploy.yml \
--parameter APP_NAME "marge-bot" \
--parameter APP_IMAGE "smarkets/marge-bot" \
--parameter KUBE_NAMESPACE "marge-bot" \
--parameter MARGE_GITLAB_URL 'http://your.gitlab.instance.com' \
--parameter MARGE_AUTH_TOKEN "$(cat marge-bot.token)" \
--parameter MARGE_SSH_KEY "$(cat marge-bot-ssh-key)" \
--parameter REPLICA_COUNT 1 | kubectl -n=${KUBE_NAMESPACE} apply --force -f -

Once running, the bot will continuously monitor all projects that have its user as a member and will pick up any changes in membership at runtime.

Running marge-bot in Swarm

Or you can run marge in Docker Swarm, e.g. here's how you use a compose file:

version: '3.8'
services:
  marge-bot:
    image: smarkets/marge-bot:latest
    configs:
      - source: marge_bot_config
        target: /configuration/marge-bot-config.yaml
    command:
      - "--config-file=/configuration/marge-bot-config.yaml"
    deploy:
      mode: replicated
      replicas: 1
      restart_policy:
        condition: on-failure
      resources:
        limits:
          memory: 256M

configs:
  marge_bot_config:
    file: ./marge-bot-config.yaml
    name: marge_bot_config

Running marge-bot in CI

You can also run marge-bot directly in your existing CI via scheduled pipelines if you'd like to avoid setting up any additional infrastructure.

This way, you can inject secrets for marge-bot's credentials at runtime inside the ephemeral container for each run by adding them to protected CI/CD variables in a dedicated marge-bot runner project, as well as store execution logs as artifacts for evidence.

You can also configure multiple setups in different CI schedules by supplying MARGE_* environment variables per-schedule, such as running a different set of projects or settings at different times.

Note that in this case, marge-bot will be slower than when run as a service, depending on the frequency of your pipeline schedules.

Create a marge-bot runner project, and add the variables MARGE_AUTH_TOKEN (of type Variable) and MARGE_SSH_KEY_FILE (of type File) in your CI/CD Variables settings.

Then add a scheduled pipeline run to your project with the following minimal .gitlab-ci.yml config:

run:
  image:
    name: smarkets/marge-bot:latest
    entrypoint: [""]
  only:
    - schedules
  variables:
    MARGE_CLI: "true"
    MARGE_GITLAB_URL: "$CI_SERVER_URL"
  script: marge.app

Running marge-bot as a plain python app

Installing marge-bot with nix

Alternatively, if you prefer not to use docker, you can also directly run marge. If you use nix do nix-env --install -f default.nix.

The nix install should be fully reproducible on any version of linux (and also work on OS X, although this is not something we properly test). If you don't want to use docker we recommend you give nix a try.

Installing marge-bot the old-fashioned way

Finally, although this is our least preferred alternative, you can always do python3 setup.py install (note that you can use python3.6 to python3.9).

Afterwards, the minimal way to run marge is as follows.

marge.app --auth-token-file marge-bot.token \
          --gitlab-url 'http://your.gitlab.instance.com' \
          --ssh-key-file marge-bot-ssh-key

However, we suggest you use a systemd unit file or some other mechanism to automatically restart marge-bot in case of intermittent GitLab problems.

Suggested workflow

  1. Alice creates a new merge request and assigns Bob and Charlie as reviewers

  2. Both review the code and after all issues they raise are resolved by Alice, they approve the merge request and assign it to marge-bot for merging.

  3. Marge-bot rebases the latest target branch (typically master) into the merge-request branch and pushes it. Once the tests have passed and there is a sufficient number of approvals (if a minimal approvals limit has been set on the project), Marge-bot will merge (or rebase, depending on project settings) the merge request via the GitLab API. It can also add some headers to all commits in the merge request as described in the next section.

Adding Reviewed-by:, Tested: and Part-of: to commit messages

Marge-bot supports automated addition of the following two standardized git commit trailers: Reviewed-by and Tested-by. For the latter it uses Marge Bot <$MERGE_REQUEST_URL> as a slight abuse of the convention (here Marge Bot is the name of the marge-bot user in GitLab).

If you pass --add-reviewers and the list of approvers is non-empty and you have enough approvers to meet the required approver count, Marge will add the following header to each commit message and each reviewer as it rebases the target branch into your PR branch:

Reviewed-by: A. Reviewer <[email protected]>

All existing Reviewed-by: trailers on commits in the branch will be stripped. This feature requires marge to run with admin privileges due to a peculiarity of the GitLab API: only admin users can obtain email addresses of other users, even ones explicitly declared as public (strangely this limitation is particular to email, Skype handles etc. are visible to everyone).

If you pass --add-tested the final commit message in a PR will be tagged with Tested-by: marge-bot <$MERGE_REQUEST_URL> trailer. This can be very useful for two reasons:

  1. Seeing where stuff "came from" in a rebase-based workflow
  2. Knowing that a commit has been tested, which is e.g. important for bisection so you can easily and automatically git bisect --skip untested commits.

Additionally, by using --add-part-of, all commit messages will be tagged with a Part-of: <$MERGE_REQUEST_URL> trailer to the merge request on which they were merged. This is useful, for example, to go from a commit shown in git blame to the merge request on which it was introduced or to easily revert a all commits introduced by a single Merge Request when using a fast-forward/rebase based merge workflow.

Impersonating approvers

If you want a full audit trail, you will configure GitLab require approvals for PRs and also turn on reset approvals on push. Unfortunately, since Marge-bot's flow is based on pushing to the source branch, this means it will reset the approval status if the latter option is enabled. However, if you have given Marge-bot admin privileges and turned on --impersonate-approvers, she will re-approve the merge request assuming after its own push, but by impersonating the existing approvers.

Merge embargoes

Marge-bot can be configured not to merge during certain periods. E.g., to prevent her from merging during weekends, add --embargo 'Friday 6pm - Monday 9am'. This is useful for example if you automatically deploy from master and want to prevent shipping late on a Friday, but still want to allow marking merge requests as "to be merged on Monday": just assign them to marge-bot as any other day.

More than one embargo period can be specified, separated by commas. Any merge request assigned to her during an embargo period, will be merged in only once all embargoes are over.

Batching Merge Requests

The flag --batch enables testing and merging merge requests in batches. This can significantly speed up the rate at which marge-bot processes jobs - not just because merge requests can be tested together, but because marge-bot will ensure the whole set of merge requests is mergeable first. This includes, for example, checking if a merge request is marked as WIP, or does not have enough approvals. Essentially, users get faster feedback if there is an issue. Note that you probably won't need this unless you have tens of merge requests a day (or extremely slow CI).

How it works

If marge-bot finds multiple merge requests to deal with, she attempts to create a batch job. She filters the merge requests such that they have all have a common target branch, and eliminates those that have not yet passed CI (a heuristic to help guarantee the batch will pass CI later).

Once the merge requests have been gathered, a batch branch is created using the commits from each merge request in sequence. Any merge request that cannot be merged to this branch (e.g. due to a rebase conflict) is filtered out. A new merge request is then created for this branch, and tested in CI.

If CI passes, the original merge requests will be merged one by one.

If the batch job fails for any reason, we fall back to merging the first merge request, before attempting a new batch job.

Limitations

  • Currently we still add the tested-by trailer for each merge request's final commit in the batch, but it would probably be more correct to add the trailer only to the last commit in the whole batch request (since that's the only one we know passed for sure in that combination). We might change this in the future or make it configurable, but note that there's still a much stronger chance all intermittent final commits also passed then when just testing on each source branch, because we know the final linearization of all commits passes in that all MRs passed individually on their branches.

  • As trailers are added to the original merge requests only, their branches would need to be pushed to in order to reflect this change. This would trigger CI in each of the branches again that would have to be passed before merging, which effectively defeats the point of batching. To workaround this, the current implementation merges to the target branch through git, instead of the GitLab API. GitLab will detect the merge request as having been merged, and update the merge request status accordingly, regardless of whether it has passed CI. This does still mean the triggered CI jobs will be running even though the merge requests are merged. marge-bot will attempt to cancel these pipelines, although this doesn't work too effectively if external CI is used.

  • There is what can be considered to be a flaw in this implementation that could potentially result in a non-green master; consider the following situation:

    1. A batch merge request is created, and passes CI.
    2. Several merge requests are then merged to master, but one could fail (perhaps due to someone pushing directly to master in between).
    3. At this point, marge-bot will abort the batch job, resulting in a subset of the batch merge requests having been merged.

    We've guaranteed that individually, each of these merge requests pass CI, and together with some extra merge requests they also pass CI, but this does not guarantee that the subset will. However, this would only happen in a rather convoluted situation that can be considered to be very rare.

Restricting the list of projects marge-bot considers

By default marge-bot will work on all projects that she is a member of. Sometimes it is useful to restrict a specific instance of marge-bot to a subset of projects. You can specify a regexp that projects must match (anchored at the start of the string) with --project-regexp.

One use-case is if you want to use different configurations (e.g. --add-reviewers on one project, but not the others). A simple way of doing is run two instances of marge-bot passing --add-reviewers --project-regexp project/with_reviewers to the first instance and --project-regexp (?!project/with_reviewers) to the second ones. The latter regexp is a negative look-ahead and will match any string not starting with project/with_reviewers.

Restricting the list of branches marge-bot considers

It is also possible to restrict the branches marge-bot watches for incoming merge requests. By default, marge-bot will process MRs targeted for any branch. You may specify a regexp that target branches must match with --branch-regexp.

This could be useful, if for instance, you wanted to set a regular freeze interval on your master branches for releases. You could have one instance of marge-bot with --embargo "Friday 1pm - Monday 9am" --branch-regexp master and the other with --branch-regexp (?!master). This would allow development to continue on other branches during the embargo on master.

It is possible to restrict the source branches with --source-branch-regexp.

Some handy git aliases

Only git bisect run on commits that have passed CI (requires running marge-bot with --add-tested):

git config --global alias.bisect-run-tested \
 'f() { git bisect run /bin/sh -c "if !(git log -1 --format %B | fgrep -q \"Tested-by: Marge Bot\"); then exit 125; else "$@"; fi"; }; f'

E.g. git bisect-run-tested ./test-for-some-bug.sh.

Revert a whole MR, in a rebase based workflow (requires running marge-bot with --add-part-of):

git config --global alias.mr-revs '!f() { git log --grep "^Part-of.*/""$1"">" --pretty="%H"; }; f'
git config --global alias.mr-url '!f() { git log -1 --grep "^Part-of.*/""$1"">" --pretty="%b" | grep "^Part-of.*/""$1"">"  | sed "s/.*<\\(.*\\)>/\\1/"; }; f'
git config --global alias.revert-mr '!f() { REVS=$(git mr-revs "$1"); URL="$(git mr-url "$1")";  git revert --no-commit $REVS;  git commit -m "Revert <$URL>$(echo;echo; echo "$REVS" | xargs -I% echo "This reverts commit %.")"; }; f'

E.g. git revert-mr 123. This will create a single commit reverting all commits that are part of MR 123 with a commit message that looks like this:

Revert <http://gitlab.example.com/mygropup/myproject/merge_requests/123>

This reverts commit 86a3d35d9bc12e735efbf72f3e2fb895c0158713.
This reverts commit e862330a6df463e36137664f316c18b5836a4df7.
This reverts commit 0af5b70a98858c9509c895da2a673ebdb31e20b1.

E.g. git revert-mr 123.

Troubleshooting

Marge-bot continuously logs what she is doing, so this is a good place to look in case of issues. In addition, by passing the --debug flag, additional info such as REST requests and responses will be logged. When opening an issue, please include a relevant section of the log, ideally ran with --debug enabled.

The most common source of issues is the presence of git-hooks that reject Marge-bot as a committer. These may have been explicitly installed by someone in your organization or they may come from the project configuration. E.g., if you are using Settings -> Repository -> Commit author's email, you may need to whitelist marge-bot's email.

Some versions of GitLab are not good at reporting merge failures due to hooks (the REST API may even claim the merge operation succeeded), you can find this in gitlab-rails/githost.log, under GitLab's logs directory.

marge-bot's People

Contributors

alexandear avatar benjamb avatar commodis avatar dalamar42 avatar david-duncan avatar dependabot[bot] avatar gforcada avatar ggreif avatar hi-angel avatar hiloyt avatar jaimelennox avatar leguminator avatar martin-sucha avatar mathyoudawson avatar matthiasbalke avatar mdevlamynck avatar micheelengronne avatar misaon avatar mrusu91 avatar nejch avatar nithyashree675 avatar qqshfox avatar rhysm avatar riklas avatar robertkirk avatar sg70 avatar snim2 avatar sobolevn avatar tclh123 avatar viatorus 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

marge-bot's Issues

Parallel Builds

In projects that have lots of merges and long build times, a synchronous build queue is not viable.

See https://gitlab.com/gitlab-org/gitlab-ce/issues/4176

Each merge request in the queue would need to be proactively rebased on the previous one before it is finished so that the builds could continue in parallel.

Downsides:

  • The implementation would require rebasing the entire queue when a build fails
  • The commit log and diff would contain unrelated changes (temporarily until master catches up)

Barriers to marge-bot working with GitHub?

Hi,

This project seems pretty interesting, and potentially quite useful. And I'm a big fan of GitLab. However, many organizations prefer GitHub to GitLab, which unfortunately means that, because marge-bot is built for GitLab, many organizations can't use this tool.

That makes me curious about what could be done to support either platform. I was hoping that those familiar with the project could outline what currently prevents marge-bot from working with GitHub, and perhaps we can then brainstorm some ideas for how we could get around some of these issues. (I'm imagining that most WebHook Events and APIs needed by marge-bot would exist on both platforms, so I'm hoping that maybe the idea of working on both platforms isn't too far out there...?)

Even if using marge-bot with GitHub came with some caveats that don't apply to GitLab use, having something could certainly be better than nothing for organizations that are currently "stuck" on GitHub. But if there are some legitimate deal-breakers that completely prevent marge-bot from working in any capacity with GitHub, just listing those would also be a satisfactory answer to this issue. Either way, I think discussing this is worthwhile :)

Thanks!

Edit: Of course, one big difference between the two is that GitLab has built-in CI. But I'm wondering how significant this difference is if we can assume that the GitHub repositories using this would have some CI service reporting status checks on each PR.

Syntax error for using bare asterisk as function args

As I known, in Python, you can use this syntax to force caller of function to use keyword args after *:

def func(a, b, *, c=None, d=None):
    ....

Which means, caller have to call func with:

result = func(a, b, c="c-value", d="d-value")

Other than:

result = func(a, b, "c-value", "d-value")

However, in marge-bot source code, I found such examples:

class Bot(object):                                                              
    def __init__(self, *, api, config):                                          
        self._api = api                                                         
        self._config = config
        ....
...

class MergeJob(object):

    def __init__(self, *, api, user, project, merge_request, repo, options):
        self._api = api
        self._user = user
        self._project = project
        ....

And I got SyntaxError for those lines in both Python2 and Python3.

Just wondering what am doing wrong, and why didn't other people encount this error?

Provide a Dockerfile to simplify deploying

The Dockerfile should provide at least:

  • Code and python dependencies
  • A version of git that supports GIT_SSH_COMMAND
  • Some hooks to provide credentials (environment variables?)
  • Ensure the certificate of gitlab host is added to ~/.ssh/known_host/ before starting

add --gitlab-url env equivalent

seems from documentation that --gitlab-url='http://your.gitlab.instance.com' can be specified only via commandline.

please add MARGE_GITLAB_URL env var support, so i could use this easily via docker-compose.yml

probably should unify configuration that all commandline options are working via env vars as well (and vice versa). maybe click can help in this.

Crash if no pipeline is run

I was testing what happens if no pipeline is run for the MR. Here's what I got (using merge strategy, if it matters):

2018-05-19 15:19:53,666 INFO Commit id to merge '8a8a087a54ea54e464af4dcf2bd457933b00dbe7' (into: '946a97b54cbcd4a47f21a1bed828e87c715a401b')
2018-05-19 15:19:59,405 INFO Waiting for CI to pass
2018-05-19 15:20:00,419 ERROR Unexpected Exception
Traceback (most recent call last):
  File "/home/ubuntu/marge-bot/marge/job.py", line 59, in execute
    self.update_merge_request_and_accept(approvals)
  File "/home/ubuntu/marge-bot/marge/job.py", line 152, in update_merge_request_and_accept
    self.wait_for_ci_to_pass(source_project.id, actual_sha, merge_request.source_branch)
  File "/home/ubuntu/marge-bot/marge/job.py", line 224, in wait_for_ci_to_pass
    assert current_pipeline.sha == commit_sha
AssertionError

I guess this is because there's no pipeline at all (configured with only: master, and master is the target branch, not the source). A graceful handling and a post in the MR would have been much better.

Rebase a branch without merge to keep it up to date

Sometimes you have a branch which lasts on a long term development (sereral weeks or months).
The merge operation can be painfull after waiting so long and one is not interested in regularly rebasing himself that branch.

Could Marge do it for me please ?

TypeError: 'NoneType' object is not subscriptable

We're trying to get marge-bot up and running on our own gitlab instance, and might have found a bug?

> marge/project.py
>> return AccessLevel(self.info['permissions']['project_access']['access_level'])
>> TypeError: 'NoneType' object is not subscriptable

After looking into this a bit, it looks like gitlabs api will return permissions only on the /projects/:id request, but not for /projects.

Better handling of missing approvals after rebase when not asked to reapprove

If the merge request has approvals and marge is not asked to reapprove, then after a rebase she won't be able to merge and will get confused / report the wrong error.

The right logic is to: refetch approvals immediately after the rebase, if there are missing approvals and was asked to reapprove, then reapprove, otherwise, fail with a proper error.

"Too Many Requests"

I got this log:

2018-08-31 16:23:55,992 INFO Waiting for CI to pass for MR !12
2018-08-31 18:11:34,929 ERROR Unexpected Exception
Traceback (most recent call last):
  File "/home/molcas-test/marge-bot/marge/single_merge_job.py", line 24, in execute
    self.update_merge_request_and_accept(approvals)
  File "/home/molcas-test/marge-bot/marge/single_merge_job.py", line 73, in update_merge_request_and_accept
    self.wait_for_ci_to_pass(merge_request, actual_sha)
  File "/home/molcas-test/marge-bot/marge/job.py", line 191, in wait_for_ci_to_pass
    ci_status = self.get_mr_ci_status(merge_request, commit_sha=commit_sha)
  File "/home/molcas-test/marge-bot/marge/job.py", line 129, in get_mr_ci_status
    pipelines = Pipeline.pipelines_by_branch(pid, ref, self._api)
  File "/home/molcas-test/marge-bot/marge/pipeline.py", line 29, in pipelines_by_branch
    params,
  File "/home/molcas-test/marge-bot/marge/gitlab.py", line 58, in call
    raise error(response.status_code, err_message)
marge.gitlab.UnexpectedError: (429, 'Too Many Requests')

as you can see, after waiting a couple of hours for the CI to finish (this is not a problem, the pipeline was running fine, it just takes a long time), marge got 429, 'Too Many Requests' from gitlab.com and crashed.

A better protection against this kind of error would be welcome, or maybe it's just a matter of increasing waiting_time_in_secs.

Have option for Marge to automatically remove WIP status of branches to merge

By default, branches named "wip_" will get rejected by Marge as the merge request that is generated will start with "wip" and be marked in progress.

https://docs.gitlab.com/ce/user/project/merge_requests/work_in_progress_merge_requests.html

Typically developers will work on a development branch and label it as "wip_" to distinguish it from production branches, then decide to Marge it - in which case they will expect Marge to remove the WIP tag. Presently, their work flow would have to be:

  1. Create development branch (wip...)
  2. Submit MR
  3. Watch MR get rejected unexpected by Marge as its WIP.
  4. Rename their branch after figuring out the problem.
  5. Resubmit

This is less than ideal and could be solved if Marge automatically removed the WIP tag. As some teams might actually want this protection in place, I would make it an optional setting of Marge so teams can decide the behaviour they want.

Handle GitLab setting merge request as WIP after pushing

Because of this GitLab feature, we can have the following interaction:

  1. Someone creates a merge request containing a commit with WIP in its name. GitLab doesn't consider the Merge Request as WIP at this point.
  2. Merge request is assigned to Marge; it checks that the merge requests is not WIP and proceeds.
    1 The branch is rebased and pushed again.
  3. Because we have just pushed a commit that contains WIP (even if it was in one of the original commits), GitLab marks the merge request as WIP (it even reports "Marge Bot marked as Work In Progress").
  4. After CI passes, she tries to merge, but GitLab now refuses to merge and we fail with "had some issue with gitlab"

We should test for WIP status before merging or, perhaps better, after the merge failed and we don't know why.

Marge fails to fetch projects, 0.7.0 regression

Gitlab instance: Gitlab CE 11.1 gitlab.gnome.org

Using the docker image:

When running the 0.7.0 tag and try to merge an MR from a fork, we get the following error.
The MR in question is here, it happened with other MRs too. This specific MR has comments from months ago when we were hitting this gitlab bug that prevented from using marge, You can ignore those and only focus on the ones from this day.

2018-08-13 04:19:11,202 INFO Processing !4 - 'Add a non-working test, from a branch'
2018-08-13 04:19:13,219 INFO Ensuring MR !4 is mergeable
2018-08-13 04:19:15,781 ERROR Unexpected Exception
Traceback (most recent call last):
  File "/nix/store/77wrcwqx8p2wbw3n0v5v4lsvh7bwn01w-python3.6-marge-0.7.0/lib/python3.6/site-packages/marge/single_merge_job.py", line 24, in execute
    self.update_merge_request_and_accept(approvals)
  File "/nix/store/77wrcwqx8p2wbw3n0v5v4lsvh7bwn01w-python3.6-marge-0.7.0/lib/python3.6/site-packages/marge/single_merge_job.py", line 50, in update_merge_request_and_accept
    source_project, source_repo_url, _ = self.fetch_source_project(merge_request)
  File "/nix/store/77wrcwqx8p2wbw3n0v5v4lsvh7bwn01w-python3.6-marge-0.7.0/lib/python3.6/site-packages/marge/job.py", line 200, in fetch_source_project
    remote_url=remote_url,
TypeError: fetch() got an unexpected keyword argument 'remote'
2018-08-13 04:19:17,796 INFO Unassigning from MR !4
Traceback (most recent call last):
  File "/nix/store/77wrcwqx8p2wbw3n0v5v4lsvh7bwn01w-python3.6-marge-0.7.0/bin/.marge.app-wrapped", line 4, in <module>
    marge.app.main()
  File "/nix/store/77wrcwqx8p2wbw3n0v5v4lsvh7bwn01w-python3.6-marge-0.7.0/lib/python3.6/site-packages/marge/app.py", line 261, in main
    marge_bot.start()
  File "/nix/store/77wrcwqx8p2wbw3n0v5v4lsvh7bwn01w-python3.6-marge-0.7.0/lib/python3.6/site-packages/marge/bot.py", line 41, in start
    self._run(repo_manager)
  File "/nix/store/77wrcwqx8p2wbw3n0v5v4lsvh7bwn01w-python3.6-marge-0.7.0/lib/python3.6/site-packages/marge/bot.py", line 59, in _run
    projects,
  File "/nix/store/77wrcwqx8p2wbw3n0v5v4lsvh7bwn01w-python3.6-marge-0.7.0/lib/python3.6/site-packages/marge/bot.py", line 97, in _process_projects
    self._process_merge_requests(repo_manager, project, merge_requests)
  File "/nix/store/77wrcwqx8p2wbw3n0v5v4lsvh7bwn01w-python3.6-marge-0.7.0/lib/python3.6/site-packages/marge/bot.py", line 164, in _process_merge_requests
    merge_job.execute()
  File "/nix/store/77wrcwqx8p2wbw3n0v5v4lsvh7bwn01w-python3.6-marge-0.7.0/lib/python3.6/site-packages/marge/single_merge_job.py", line 24, in execute
    self.update_merge_request_and_accept(approvals)
  File "/nix/store/77wrcwqx8p2wbw3n0v5v4lsvh7bwn01w-python3.6-marge-0.7.0/lib/python3.6/site-packages/marge/single_merge_job.py", line 50, in update_merge_request_and_accept
    source_project, source_repo_url, _ = self.fetch_source_project(merge_request)
  File "/nix/store/77wrcwqx8p2wbw3n0v5v4lsvh7bwn01w-python3.6-marge-0.7.0/lib/python3.6/site-packages/marge/job.py", line 200, in fetch_source_project
    remote_url=remote_url,
TypeError: fetch() got an unexpected keyword argument 'remote'

Then I setup an instance from the 0.6.1 tag and it succeded.

2018-08-13 04:29:31,163 INFO Fetching merge requests assigned to me in alatiera/Bors-test...
2018-08-13 04:29:33,107 INFO Got 1 requests to merge; will try to merge the oldest
2018-08-13 04:29:33,107 INFO Running git clone --origin=origin [email protected]:alatiera/Bors-test.git /tmpubhyfb3i/tmpggc__srt
2018-08-13 04:29:36,851 INFO Running git -C /tmpubhyfb3i/tmpggc__srt config user.email [email protected]
2018-08-13 04:29:36,856 INFO Running git -C /tmpubhyfb3i/tmpggc__srt config user.name 'Merge Bot, Bors Wannabe'
2018-08-13 04:29:36,861 INFO Processing !4 - 'Add a non-working test, from a branch'
2018-08-13 04:29:40,206 INFO Running git -C /tmpubhyfb3i/tmpggc__srt fetch --prune origin
2018-08-13 04:29:43,478 INFO Running git -C /tmpubhyfb3i/tmpggc__srt remote rm source
2018-08-13 04:29:43,483 WARNING git returned 128
2018-08-13 04:29:43,483 WARNING stdout: b''
2018-08-13 04:29:43,483 WARNING stderr: b'fatal: No such remote: source\n'
2018-08-13 04:29:43,483 INFO Running git -C /tmpubhyfb3i/tmpggc__srt remote add source [email protected]:federico/Bors-test.git
2018-08-13 04:29:43,492 INFO Running git -C /tmpubhyfb3i/tmpggc__srt fetch --prune source
2018-08-13 04:29:47,240 INFO Running git -C /tmpubhyfb3i/tmpggc__srt checkout -B test-non-working source/test-non-working --
2018-08-13 04:29:47,247 INFO Running git -C /tmpubhyfb3i/tmpggc__srt rebase origin/master
2018-08-13 04:29:47,336 INFO Running git -C /tmpubhyfb3i/tmpggc__srt rev-parse HEAD
2018-08-13 04:29:47,341 INFO Running git -C /tmpubhyfb3i/tmpggc__srt rev-parse origin/master
2018-08-13 04:29:47,345 INFO Running git -C /tmpubhyfb3i/tmpggc__srt checkout test-non-working --
2018-08-13 04:29:47,355 INFO Running git -C /tmpubhyfb3i/tmpggc__srt diff-index --quiet HEAD
2018-08-13 04:29:47,360 INFO Running git -C /tmpubhyfb3i/tmpggc__srt ls-files --others
2018-08-13 04:29:47,365 INFO Running git -C /tmpubhyfb3i/tmpggc__srt config --get remote.source.url
2018-08-13 04:29:47,370 INFO Running git -C /tmpubhyfb3i/tmpggc__srt push --force source test-non-working
2018-08-13 04:29:50,533 INFO Running git -C /tmpubhyfb3i/tmpggc__srt checkout master --
2018-08-13 04:29:50,539 INFO Running git -C /tmpubhyfb3i/tmpggc__srt branch -D test-non-working
2018-08-13 04:29:50,545 INFO Commit id to merge '18a991a77917afc735b088c9ad434e3db355cde9' (into: '79375273a12686d15e230fa39bec69107966c83c')
2018-08-13 04:30:05,322 INFO Successfully merged !4.

Marge should not merge MRs with failed CI unless explicity stated by a config.

So here is the scenario, we setup marge with default config and made a failing MR to test. We assigned marge to the MR but instead of complaining it did go ahead and merge it since we hadn't yet turned on this giltlab flag for the project.

I think Marge should prevent stupid mistakes like this and have it require a flag be set if you really want her to merge failing CI MR.

Fix/investigate corner case of no-op merge request

This can happen when the commit messages of source and target differ, but content is identical; there is an example in our internal marge-test-repo. The weird thing we observed in that case is that rebasing into the target branch did not update the branch reference (i.e. unexpected git behavior which we should try to understand; possibly a bug more likely an UX issue or us missing something).

merge failure (405 method not allowed on merge)

marge got:

Reporter   
I couldn't merge this branch: had some issue with gitlab, check my logs...

i checked the logs and it has:

marge-bot_1  | 2017-08-09 06:29:43,992 ERROR Unanticipated ApiError from Gitlab on merge attempt
marge-bot_1  | Traceback (most recent call last):
marge-bot_1  |   File "/nix/store/9vhc0sbcxii1s05sz755ws8gr46iynqw-python3.6-marge-0.2.0/lib/python3.6/site-packages/marge/job.py", line 136, in rebase_and_accept
marge-bot_1  |     merge_request.accept(remove_branch=True, sha=actual_sha)
marge-bot_1  |   File "/nix/store/9vhc0sbcxii1s05sz755ws8gr46iynqw-python3.6-marge-0.2.0/lib/python3.6/site-packages/marge/merge_request.py", line 104, in accept
marge-bot_1  |     sha=sha or self.sha,  # if provided, ensures what is merged is what we want (or fails)
marge-bot_1  |   File "/nix/store/9vhc0sbcxii1s05sz755ws8gr46iynqw-python3.6-marge-0.2.0/lib/python3.6/site-packages/marge/gitlab.py", line 55, in call
marge-bot_1  |     raise error(response.status_code, err_message)
marge-bot_1  | marge.gitlab.MethodNotAllowed: (405, {'message': '405 Method Not Allowed'})
marge-bot_1  | 2017-08-09 06:29:44,545 WARNING I couldn't merge this branch: had some issue with gitlab, check my logs...

questions:

  1. what could be cause, is it temporary error?
  2. how to make marge retry?

i changed marge user access from reporter to developer, i used reporter before because such privilege worked in earlier project (marge itself is admin), but i don't see how to make marge retry. i even force pushed last commit removing the tested-by lines and restarted the bot docker container.

Marge crashing with an UnicodeEncodeError

  File "/nix/store/q0m1zzzkxhliiyjhvhidisx9ja196v64-python3.6-marge-0.3.2/lib/python3.6/site-packages/marge/job.py", line 55, in execute
    self.rebase_and_accept(approvals)
  File "/nix/store/q0m1zzzkxhliiyjhvhidisx9ja196v64-python3.6-marge-0.3.2/lib/python3.6/site-packages/marge/job.py", line 111, in rebase_and_accept
    tested_by=tested_by,
  File "/nix/store/q0m1zzzkxhliiyjhvhidisx9ja196v64-python3.6-marge-0.3.2/lib/python3.6/site-packages/marge/job.py", line 298, in push_rebased_and_rewritten_version
    start_commit='origin/' + target_branch,
  File "/nix/store/q0m1zzzkxhliiyjhvhidisx9ja196v64-python3.6-marge-0.3.2/lib/python3.6/site-packages/marge/git.py", line 52, in tag_with_trailer
    self.git('filter-branch', '--force', '--msg-filter', filter_script, commit_range)
  File "/nix/store/q0m1zzzkxhliiyjhvhidisx9ja196v64-python3.6-marge-0.3.2/lib/python3.6/site-packages/marge/git.py", line 138, in git
    return _run(*command, env=env, check=True, timeout=TIMEOUT_IN_SECS)
  File "/nix/store/q0m1zzzkxhliiyjhvhidisx9ja196v64-python3.6-marge-0.3.2/lib/python3.6/site-packages/marge/git.py", line 147, in _run
    with subprocess.Popen(args, env=env, stdout=PIPE, stderr=PIPE) as process:
  File "/nix/store/an47r56zf6xn6fp2kyfygdy8xbplzyc2-python3-3.6.1/lib/python3.6/subprocess.py", line 707, in __init__
    restore_signals, start_new_session)
  File "/nix/store/an47r56zf6xn6fp2kyfygdy8xbplzyc2-python3-3.6.1/lib/python3.6/subprocess.py", line 1260, in _execute_child
    restore_signals, start_new_session, preexec_fn)
UnicodeEncodeError: 'ascii' codec can't encode character '\xe3' in position 25: ordinal not in range(128)
Traceback (most recent call last):
  File "/nix/store/q0m1zzzkxhliiyjhvhidisx9ja196v64-python3.6-marge-0.3.2/bin/.marge.app-wrapped", line 4, in <module>
    marge.app.main()
  File "/nix/store/q0m1zzzkxhliiyjhvhidisx9ja196v64-python3.6-marge-0.3.2/lib/python3.6/site-packages/marge/app.py", line 151, in main
    marge_bot.start()
  File "/nix/store/q0m1zzzkxhliiyjhvhidisx9ja196v64-python3.6-marge-0.3.2/lib/python3.6/site-packages/marge/bot.py", line 36, in start
    self._run(repo_manager)
  File "/nix/store/q0m1zzzkxhliiyjhvhidisx9ja196v64-python3.6-marge-0.3.2/lib/python3.6/site-packages/marge/bot.py", line 90, in _run
    merge_job.execute()
  File "/nix/store/q0m1zzzkxhliiyjhvhidisx9ja196v64-python3.6-marge-0.3.2/lib/python3.6/site-packages/marge/job.py", line 55, in execute
    self.rebase_and_accept(approvals)
  File "/nix/store/q0m1zzzkxhliiyjhvhidisx9ja196v64-python3.6-marge-0.3.2/lib/python3.6/site-packages/marge/job.py", line 111, in rebase_and_accept
    tested_by=tested_by,
  File "/nix/store/q0m1zzzkxhliiyjhvhidisx9ja196v64-python3.6-marge-0.3.2/lib/python3.6/site-packages/marge/job.py", line 298, in push_rebased_and_rewritten_version
    start_commit='origin/' + target_branch,
  File "/nix/store/q0m1zzzkxhliiyjhvhidisx9ja196v64-python3.6-marge-0.3.2/lib/python3.6/site-packages/marge/git.py", line 52, in tag_with_trailer
    self.git('filter-branch', '--force', '--msg-filter', filter_script, commit_range)
  File "/nix/store/q0m1zzzkxhliiyjhvhidisx9ja196v64-python3.6-marge-0.3.2/lib/python3.6/site-packages/marge/git.py", line 138, in git
    return _run(*command, env=env, check=True, timeout=TIMEOUT_IN_SECS)
  File "/nix/store/q0m1zzzkxhliiyjhvhidisx9ja196v64-python3.6-marge-0.3.2/lib/python3.6/site-packages/marge/git.py", line 147, in _run
    with subprocess.Popen(args, env=env, stdout=PIPE, stderr=PIPE) as process:
  File "/nix/store/an47r56zf6xn6fp2kyfygdy8xbplzyc2-python3-3.6.1/lib/python3.6/subprocess.py", line 707, in __init__
    restore_signals, start_new_session)
  File "/nix/store/an47r56zf6xn6fp2kyfygdy8xbplzyc2-python3-3.6.1/lib/python3.6/subprocess.py", line 1260, in _execute_child
    restore_signals, start_new_session, preexec_fn)
UnicodeEncodeError: 'ascii' codec can't encode character '\xe3' in position 25: ordinal not in range(128)

There are two bugs here:

  • we should always force utf-8 encoding and decoding, locale be damned (the problem here almost certainly is that the LANG/LC_ALL are not .utf-8)
  • marge-bot should unassign hereself on failure

Handling merge requests from forks

A very significant flaw of the merge request model in GitLab is that it seems the only CI linked to the merge request is in the source project. This may be alright in very simple projects and configurations, but I don't think the CI from an external project should be trusted:

  1. It could have no access to specific runners
  2. Secret variables will not be available
  3. Runner time limits could be different

These could cause CI jobs in a fork to fail, with almost no chance of fixing them. Perhaps more serious, I imagine it could be possible for a malicious user to set up a customized runner that will report success where a test should fail, in which case the CI would appear as passing, but it will be broken when run in the target project's runners.

I don't know if there's any way to run pipelines for merge requests on the target project. Apparently the SHA for the MR commit is created in the target project, and a pipeline can be run if a tag or branch is added to it, but it is not connected to the MR. See for example:

https://gitlab.com/Jellby/test/merge_requests/10 The CI on the source project fails (artificially forced to do so, but it could happen in a real case for legitimate reasons as seen above).

The commit appeared in the target repository: https://gitlab.com/Jellby/test/commit/1ca482baa35df4287afaf5313a2f64fc59b62ed5

I created a tag: https://gitlab.com/Jellby/test/commits/testingMR!10 and ran a pipeline: https://gitlab.com/Jellby/test/pipelines/22898164 on the target project, but the MR does not show its result, so the MR can't be accepted.

If someone can find a good solution, that would be great. Otherwise, I'd suggest at least an option to ignore MRs not originating from the same project (and it should be the default if the guarantee for a green master is important).

Handle protected branches

If a branch has been protected in GitLab, then Marge cannot force push to it (which is necessary if Marge has added trailers, or rebased the MR). However, there's no handling for this case and so Marge simply blows up with the "broken on the inside" message.

One should be notified immediately if a request is not mergeable

At the moment, if one assigns to marge a MR that cannot be merged, e.g., because it is marked as WIP or has unresolved conversations, marge will bail out and re-assign it to the owner but only when the time comes to process this merge request.

At busy periods, it may take a while until this happens. The user then needs to resolve the problem (e.g. remove the WIP tag), reassign and wait for long once again for the branch to be merged.

It would be much better if the feedback were almost immediately. We could do this, e.g. with a separate thread that polls continuously for assigned merge requests (those modified after the last check?) and unassigns marge from those in an unmergeable state.

No `impersonate-approvers` on gitlab.com

Using impersonate-approvers requires admin permission... How do I grant admin permission? I reckon this is something that belongs to the GitLab installation, and therefore is not something mere mortals can do on gitlab.com, even in our own repositories. If it is so, it would be good to say mention it in the documentation, I didn't see that.

iterating over projects takes over 30 seconds

as marge checks each project it is assigned one by one, and having over 50 projects assigned, the whole cycle (with no jobs found) takes ~2 minutes. how to solve this and make marge process assigned jobs sooner?

marge 0.6.1

# docker-compose logs |grep -E 'INFO Sleeping|INFO Finding out my current projects'
marge-bot_1  | 2018-03-26 20:06:22,903 INFO Finding out my current projects...
marge-bot_1  | 2018-03-26 20:08:14,924 INFO Sleeping for 0 seconds...
marge-bot_1  | 2018-03-26 20:08:14,924 INFO Finding out my current projects...
marge-bot_1  | 2018-03-26 20:10:07,329 INFO Sleeping for 0 seconds...
marge-bot_1  | 2018-03-26 20:10:07,330 INFO Finding out my current projects...

# docker-compose logs | sed -ne 's/.*INFO Fetching merge requests assigned to me in //p' | sort -u | wc -l
82

Re-approvals only applied after successful CI run

There is a comment related to this within marge/job.py, including for context:

# Re-approve the merge request, in case us pushing it has removed
# approvals. Note that there is a bit of a race; effectively
# approval can't be withdrawn after we've pushed (resetting
# approvals) and CI runs.

Occasionally CI may fail due to transient network issues that are unrelated to the change made. In this case, Marge will error out and not bother attempting to reapply any approvals. GitLab doesn't remove approvals on CI failure, so it doesn't quite make sense that this happens with Marge.

This also applies to any potential exception that might occur between the force push and applying approvals, we need to restart marge and then manually approve again.

I'm unaware as to whether there is a historical reason for why approvals are reapplied when they are, but could they no be applied immediately after the rebase?

Make git pull timeout configurable

in marge/git.py, you're hardcoding the git clone timeout to 120 seconds. While this may be a sensible default, it absolutely doesn't work for large repositories which take longer to clone.

I'd rather propose this to be configurable by either an environment variable (MARGE_GIT_TIMEOUT?) or a command option (or both?)

unexpected merge state locked

marge-bot_1  | 2018-02-05 12:39:47,026 INFO Commit id to merge 'bb052510c9a6357fe733b793f4c1f5b38a32e89e' (into: 'aa5d3b11e3768d34f74bde8de7095a629d76cba1')
marge-bot_1  | 2018-02-05 12:39:53,476 INFO Giving 10 more secs for !125 to be merged...
marge-bot_1  | 2018-02-05 12:40:03,757 INFO Giving 10 more secs for !125 to be merged...
marge-bot_1  | 2018-02-05 12:40:14,265 INFO Giving 10 more secs for !125 to be merged...
marge-bot_1  | 2018-02-05 12:40:24,748 INFO Giving 10 more secs for !125 to be merged...
marge-bot_1  | 2018-02-05 12:40:35,059 INFO Giving 10 more secs for !125 to be merged...
marge-bot_1  | 2018-02-05 12:40:45,633 INFO Giving 10 more secs for !125 to be merged...
marge-bot_1  | 2018-02-05 12:40:55,966 INFO Giving 10 more secs for !125 to be merged...
marge-bot_1  | 2018-02-05 12:41:06,263 INFO Giving 10 more secs for !125 to be merged...
marge-bot_1  | 2018-02-05 12:41:16,685 INFO Giving 10 more secs for !125 to be merged...
marge-bot_1  | 2018-02-05 12:41:27,039 INFO Giving 10 more secs for !125 to be merged...
marge-bot_1  | 2018-02-05 12:41:37,310 INFO Giving 10 more secs for !125 to be merged...
marge-bot_1  | 2018-02-05 12:41:47,509 INFO Giving 10 more secs for !125 to be merged...
marge-bot_1  | 2018-02-05 12:41:57,879 ERROR Unexpected Exception
marge-bot_1  | Traceback (most recent call last):
marge-bot_1  |   File "/nix/store/v4xzqxg6yvhvdqk6w453pig8v7r69v1c-python3.6-marge-0.5.1/lib/python3.6/site-packages/marge/job.py", line 55, in execute
marge-bot_1  |     self.rebase_and_accept(approvals)
marge-bot_1  |   File "/nix/store/v4xzqxg6yvhvdqk6w453pig8v7r69v1c-python3.6-marge-0.5.1/lib/python3.6/site-packages/marge/job.py", line 198, in rebase_and_accept
marge-bot_1  |     self.wait_for_branch_to_be_merged()
marge-bot_1  |   File "/nix/store/v4xzqxg6yvhvdqk6w453pig8v7r69v1c-python3.6-marge-0.5.1/lib/python3.6/site-packages/marge/job.py", line 238, in wait_for_branch_to_be_merged
marge-bot_1  |     assert merge_request.state in ('opened', 'reopened'), merge_request.state
marge-bot_1  | AssertionError: locked
marge-bot_1  | Traceback (most recent call last):
marge-bot_1  |   File "/nix/store/v4xzqxg6yvhvdqk6w453pig8v7r69v1c-python3.6-marge-0.5.1/bin/.marge.app-wrapped", line 4, in <module>
marge-bot_1  |     marge.app.main()
marge-bot_1  |   File "/nix/store/v4xzqxg6yvhvdqk6w453pig8v7r69v1c-python3.6-marge-0.5.1/lib/python3.6/site-packages/marge/app.py", line 221, in main
marge-bot_1  |     marge_bot.start()
marge-bot_1  |   File "/nix/store/v4xzqxg6yvhvdqk6w453pig8v7r69v1c-python3.6-marge-0.5.1/lib/python3.6/site-packages/marge/bot.py", line 39, in start
marge-bot_1  |     self._run(repo_manager)
marge-bot_1  |   File "/nix/store/v4xzqxg6yvhvdqk6w453pig8v7r69v1c-python3.6-marge-0.5.1/lib/python3.6/site-packages/marge/bot.py", line 108, in _run
marge-bot_1  |     merge_job.execute()
marge-bot_1  |   File "/nix/store/v4xzqxg6yvhvdqk6w453pig8v7r69v1c-python3.6-marge-0.5.1/lib/python3.6/site-packages/marge/job.py", line 55, in execute
marge-bot_1  |     self.rebase_and_accept(approvals)
marge-bot_1  |   File "/nix/store/v4xzqxg6yvhvdqk6w453pig8v7r69v1c-python3.6-marge-0.5.1/lib/python3.6/site-packages/marge/job.py", line 198, in rebase_and_accept
marge-bot_1  |     self.wait_for_branch_to_be_merged()
marge-bot_1  |   File "/nix/store/v4xzqxg6yvhvdqk6w453pig8v7r69v1c-python3.6-marge-0.5.1/lib/python3.6/site-packages/marge/job.py", line 238, in wait_for_branch_to_be_merged
marge-bot_1  |     assert merge_request.state in ('opened', 'reopened'), merge_request.state
marge-bot_1  | AssertionError: locked

here's how it looked at gitlab web:

image

Errors parsing version of current gitlab versions

Got an an error when parsing the version of newer gitlab versions. Looks like the "edition" part of the version is missing but expected.

24.7.2017 23:49:212017-07-24 21:49:21,800 DEBUG RESPONSE CODE: 200
24.7.2017 23:49:212017-07-24 21:49:21,800 DEBUG RESPONSE BODY: {'version': '9.4.0', 'revision': '9bbe2ac'}
24.7.2017 23:49:212017-07-24 21:49:21,800 ERROR Unexpected Exception
24.7.2017 23:49:21Traceback (most recent call last):
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/lib/python3.6/site-packages/marge/job.py", line 56, in execute
24.7.2017 23:49:21    approvals = merge_request.fetch_approvals()
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/lib/python3.6/site-packages/marge/merge_request.py", line 121, in fetch_approvals
24.7.2017 23:49:21    approvals.refetch_info()
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/lib/python3.6/site-packages/marge/approvals.py", line 10, in refetch_info
24.7.2017 23:49:21    if self._api.version().release >= (9, 2, 2):
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/lib/python3.6/site-packages/marge/gitlab.py", line 72, in version
24.7.2017 23:49:21    return Version.parse(response['version'])
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/lib/python3.6/site-packages/marge/gitlab.py", line 207, in parse
24.7.2017 23:49:21    release_string, edition = string.split('-', maxsplit=1)
24.7.2017 23:49:21ValueError: not enough values to unpack (expected 2, got 1)
24.7.2017 23:49:212017-07-24 21:49:21,800 DEBUG REQUEST: GET http://gitlab/api/v4/version {'PRIVATE-TOKEN': 'HW9c_BJgwgoK5cEmwsSr'} {'params': {}}
24.7.2017 23:49:212017-07-24 21:49:21,802 DEBUG Starting new HTTP connection (1): gitlab
24.7.2017 23:49:212017-07-24 21:49:21,810 DEBUG http://gitlab:80 "GET /api/v4/version HTTP/1.1" 200 None
24.7.2017 23:49:212017-07-24 21:49:21,811 DEBUG RESPONSE CODE: 200
24.7.2017 23:49:212017-07-24 21:49:21,811 DEBUG RESPONSE BODY: {'version': '9.4.0', 'revision': '9bbe2ac'}
24.7.2017 23:49:21Traceback (most recent call last):
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/lib/python3.6/site-packages/marge/job.py", line 56, in execute
24.7.2017 23:49:21    approvals = merge_request.fetch_approvals()
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/lib/python3.6/site-packages/marge/merge_request.py", line 121, in fetch_approvals
24.7.2017 23:49:21    approvals.refetch_info()
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/lib/python3.6/site-packages/marge/approvals.py", line 10, in refetch_info
24.7.2017 23:49:21    if self._api.version().release >= (9, 2, 2):
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/lib/python3.6/site-packages/marge/gitlab.py", line 72, in version
24.7.2017 23:49:21    return Version.parse(response['version'])
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/lib/python3.6/site-packages/marge/gitlab.py", line 207, in parse
24.7.2017 23:49:21    release_string, edition = string.split('-', maxsplit=1)
24.7.2017 23:49:21ValueError: not enough values to unpack (expected 2, got 1)
24.7.2017 23:49:21
24.7.2017 23:49:21During handling of the above exception, another exception occurred:
24.7.2017 23:49:21
24.7.2017 23:49:21Traceback (most recent call last):
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/bin/.marge.app-wrapped", line 4, in <module>
24.7.2017 23:49:21    marge.app.main()
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/lib/python3.6/site-packages/marge/app.py", line 114, in main
24.7.2017 23:49:21    marge_bot.start()
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/lib/python3.6/site-packages/marge/bot.py", line 50, in start
24.7.2017 23:49:21    self._run(repo_manager)
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/lib/python3.6/site-packages/marge/bot.py", line 92, in _run
24.7.2017 23:49:21    job.execute()
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/lib/python3.6/site-packages/marge/job.py", line 70, in execute
24.7.2017 23:49:21    merge_request.comment("I'm broken on the inside, please somebody fix me... :cry:")
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/lib/python3.6/site-packages/marge/merge_request.py", line 90, in comment
24.7.2017 23:49:21    if self._api.version().release >= (9, 2, 2):
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/lib/python3.6/site-packages/marge/gitlab.py", line 72, in version
24.7.2017 23:49:21    return Version.parse(response['version'])
24.7.2017 23:49:21  File "/nix/store/0yjvdhpw9cpmahw6ndfgby9n4pz8m79i-python3.6-marge-0.1.1/lib/python3.6/site-packages/marge/gitlab.py", line 207, in parse
24.7.2017 23:49:21    release_string, edition = string.split('-', maxsplit=1)
24.7.2017 23:49:21ValueError: not enough values to unpack (expected 2, got 1)

Versions
GitLab: 9.4.0
GitLab API: v4
marge-bot: 0.1.1

merge failure because base branch not updated

marge-bot_1  | 2017-08-17 11:47:36,764 INFO Processing !39 - 'Add 360 video support, DVID-103'
marge-bot_1  | 2017-08-17 11:47:36,944 INFO Running git -C /tmpa7qybnrd/tmphn_oz1jn fetch origin
marge-bot_1  | 2017-08-17 11:47:37,667 INFO Running git -C /tmpa7qybnrd/tmphn_oz1jn checkout -B DVID-103_add_360_video_support origin/DVID-103_add_360_video_support --
marge-bot_1  | 2017-08-17 11:47:37,687 INFO Running git -C /tmpa7qybnrd/tmphn_oz1jn rebase origin/master
marge-bot_1  | 2017-08-17 11:47:37,777 WARNING git returned 128
marge-bot_1  | 2017-08-17 11:47:37,777 WARNING stdout: b'First, rewinding head to replay your work on top of it...\nApplying: change1\nApplying: change2\nApplying: change3\nUsing index info to reconstruct a base tree...\nM\tfile1.php\nM\tfile2.php\nFalling back to patching base and 3-way merge...\nAuto-merging file2.php\nCONFLICT (content): Merge conflict in file2.php\nAuto-merging file1.php\nCONFLICT (content): Merge conflict in file1.php\nPatch failed at 0003 change1\nThe copy of the patch that failed is found in: .git/rebase-apply/patch\n\nWhen you have resolved this problem, run "git rebase --continue".\nIf you prefer to skip this patch, run "git rebase --skip" instead.\nTo check out the original branch and stop rebasing, run "git rebase --abort".\n\n'
marge-bot_1  | 2017-08-17 11:47:37,777 WARNING stderr: b'error: Failed to merge in the changes.\n'
marge-bot_1  | 2017-08-17 11:47:37,778 WARNING rebase failed, doing an --abort
marge-bot_1  | 2017-08-17 11:47:37,778 INFO Running git -C /tmpa7qybnrd/tmphn_oz1jn rebase --abort
marge-bot_1  | 2017-08-17 11:47:37,823 INFO Running git -C /tmpa7qybnrd/tmphn_oz1jn checkout master --
marge-bot_1  | 2017-08-17 11:47:37,833 INFO Running git -C /tmpa7qybnrd/tmphn_oz1jn branch -D DVID-103_add_360_video_support
marge-bot_1  | 2017-08-17 11:47:37,837 WARNING I couldn't merge this branch: got conflicts while rebasing, your problem now...

when i check workspace of marge bot, it's at 4d81b82, but real origin/master is at 8fba43a
and therefore the merge conflicts because base branch is out of date.

also seems that origin master is fetched and up to date. perhaps merge against origin/master not master?

bash-4.4# GIT_DIR=/tmpa7qybnrd/tmphn_oz1jn/.git /nix/store/m9wmmxajfxpw06sn0wv3gmvda2zlgmv2-git-2.13.3/bin/git show -s HEAD
commit 4d81b823fb7038b90a36bd2a8bd9da378a0e111a (HEAD -> master)


bash-4.4# GIT_DIR=/tmpa7qybnrd/tmphn_oz1jn/.git /nix/store/m9wmmxajfxpw06sn0wv3gmvda2zlgmv2-git-2.13.3/bin/git show -s master
commit 4d81b823fb7038b90a36bd2a8bd9da378a0e111a (HEAD -> master)

bash-4.4# GIT_DIR=/tmpa7qybnrd/tmphn_oz1jn/.git /nix/store/m9wmmxajfxpw06sn0wv3gmvda2zlgmv2-git-2.13.3/bin/git show -s origin/master
commit 8fba43a37831666af74a6b5de71cd6089ccf71c9 (origin/master, origin/HEAD)
Merge: 4e24499 dcb781f
bash-4.4#

Give a better message when can't merge due to unresolved discussions

At the moment If a request is assigned to marge-bot, there are pending discussions, and GitLab is configured so that requests can be merged until discussions are resolved, she will bail out with:

I couldn't merge this branch: Gitlab refused to merge this request and I don't know why!

We should check if this is due to pending discussions and leave a more informative message instead.

stale ssh private key files

the current version (59ace57) leaves temporary ssh key files laying around.

first problem is that the temporary file is created even if --ssh-key-file commandline is used.

and second problem that the temporary files are never removed. thus root filesystem of docker container is filled with ssh private key files (probably system temp dir for non-docker runs).

bash-4.4# ls -l /
-rw-------   1 root root 3243 Aug  7 09:07 ssh-key
-rw-------   1 root root    0 Aug  7 10:36 ssh-key-rgss44m3
-rw-------   1 root root    0 Aug  7 10:35 ssh-key-tmagyr7i

ssh-key is mounted via docker volume and used as commandline --ssh-key-file=/ssh-key, the other two came from processing (two?) merge requests.

Missing support for gitlab-CE

Looks like marge-bot is only compatible with gitlab-EE. It uses the approval feature that is not available in gitlab-CE. The endpoint /api/v4/projects/{id}/merge_requests/{id}/approvals is also not part of the Community Editions API.

25.7.2017 10:23:142017-07-25 08:23:14,400 DEBUG http://gitlab:80 "GET /api/v4/projects/1/merge_requests/1/approvals HTTP/1.1" 404 None
25.7.2017 10:23:142017-07-25 08:23:14,401 DEBUG RESPONSE CODE: 404
25.7.2017 10:23:142017-07-25 08:23:14,401 DEBUG RESPONSE BODY: {'error': '404 Not Found'}
25.7.2017 10:23:142017-07-25 08:23:14,402 ERROR Unexpected Exception
25.7.2017 10:23:14Traceback (most recent call last):
25.7.2017 10:23:14  File "/nix/store/02cbi06m7hk3qccalxrc71c2abiax6nz-python3.6-marge-0.1.2/lib/python3.6/site-packages/marge/job.py", line 56, in execute
25.7.2017 10:23:14    approvals = merge_request.fetch_approvals()
25.7.2017 10:23:14  File "/nix/store/02cbi06m7hk3qccalxrc71c2abiax6nz-python3.6-marge-0.1.2/lib/python3.6/site-packages/marge/merge_request.py", line 121, in fetch_approvals
25.7.2017 10:23:14    approvals.refetch_info()
25.7.2017 10:23:14  File "/nix/store/02cbi06m7hk3qccalxrc71c2abiax6nz-python3.6-marge-0.1.2/lib/python3.6/site-packages/marge/approvals.py", line 15, in refetch_info
25.7.2017 10:23:14    self._info = self._api.call(GET(approver_url))
25.7.2017 10:23:14  File "/nix/store/02cbi06m7hk3qccalxrc71c2abiax6nz-python3.6-marge-0.1.2/lib/python3.6/site-packages/marge/gitlab.py", line 55, in call
25.7.2017 10:23:14    raise error(response.status_code, err_message)
25.7.2017 10:23:14marge.gitlab.NotFound: (404, {'error': '404 Not Found'})

Supporting both versions with suitable workflows would be awesome!

Space suggestion for marge bot username

Your suggestion to include space in bot name, breaks GitLab Jira integration.

[ Marge Bot|https://gitlab.example.net/marge-bot] mentioned this issue in a commit of libraries/imagetools:
'Merge branch 'imagetools-fixes' into 'master''

not sure what to do with this, remove the suggestion, report to gitlab-ce about the problem, or ...

Some issues starting up

Sorry to put some problems in the same issue, I can split it up if it's preferred.

python 3.5.2 complained about the trailing comma in job.py:

def update_from_target_branch_and_push(
        *,
        repo,
        source_branch,
        target_branch,
        source_repo_url=None,
        reviewers=None,
        tested_by=None,
        part_of=None,
        use_merge_strategy=False,
):

removing it worked.

Then there was a problem with (still in job.py) when using use-merge-strategy: true:

        fuse = repo.merge if use_merge_strategy else repo.rebase
        rewritten_sha = updated_sha = fuse(
            branch=source_branch,
            new_base=target_branch,
            source_repo_url=source_repo_url
        )

since repo.merge uses source_branch and target_branch instead of branch and new_base as argument names.

And finally (for now, because I haven't solved it):

2018-05-18 16:00:15,767 INFO Running git clone --origin=origin [email protected]:Jellby/test.git /tmp/tmpmj08l3pw/tmptm1hlsd2
2018-05-18 16:00:18,678 INFO Running git -C /tmp/tmpmj08l3pw/tmptm1hlsd2 config user.email [email protected]
2018-05-18 16:00:18,686 INFO Running git -C /tmp/tmpmj08l3pw/tmptm1hlsd2 config user.name Molcas
2018-05-18 16:00:18,693 INFO Processing !3 - 'dev/* branches and longer job'
2018-05-18 16:00:25,178 INFO Running git -C /tmp/tmpmj08l3pw/tmptm1hlsd2 fetch --prune origin
2018-05-18 16:00:26,163 WARNING git returned 128
2018-05-18 16:00:26,163 WARNING stdout: b''
2018-05-18 16:00:26,165 WARNING stderr: b'Warning: Identity file ssh-key not accessible: No such file or directory.\nPermission denied (publickey).\r\nfatal: Could not read from remote repository.\n\nPlease make sure you have the correct access rights\nand the repository exists.\n'
2018-05-18 16:00:26,165 INFO Running git -C /tmp/tmpmj08l3pw/tmptm1hlsd2 checkout master --
2018-05-18 16:00:26,175 INFO Running git -C /tmp/tmpmj08l3pw/tmptm1hlsd2 branch -D branch
2018-05-18 16:00:26,182 WARNING git returned 1
2018-05-18 16:00:26,183 WARNING stdout: b''
2018-05-18 16:00:26,183 WARNING stderr: b"error: branch 'branch' not found.\n"
2018-05-18 16:00:26,183 ERROR Unexpected Git error
Traceback (most recent call last):
  File "/home/ubuntu/marge-bot/marge/git.py", line 163, in git
    return _run(*command, env=env, check=True, timeout=timeout_seconds)
  File "/home/ubuntu/marge-bot/marge/git.py", line 189, in _run
    retcode, process.args, output=stdout, stderr=stderr,
subprocess.CalledProcessError: Command '[b'git', b'-C', b'/tmp/tmpmj08l3pw/tmptm1hlsd2', b'fetch', b'--prune', b'origin']' returned non-zero exit status 128

I don't know why it complains about the identity file, since it ran the git clone apparently successfully. Then git fails when it tries to remove the local branch branch, which I guess doesn't exist because it hasn't been set to track the remote one yet...

Handle CI status 'skipped'

Marge-bot will currently wait up until the ci-timeout before reporting that the CI is taking too long if the status is 'skipped'. This status will occur if the top commit message of the MR contains the magic [ci skip] tag.

This status should either be treated in the same way as 'success', since the user is explicitly stating that the CI needn't run for the particular change. Or instead reported as an error earlier, with a clearer message. This could perhaps be configurable.

Remove merge-commit-attempts when using the merge strategy

With the experimental support for merge-commits (see #72), spurious merge-commits may be left around. A possible scenario would be:

  1. One assigns to marge
  2. A merge commit is thus pushed to the branch
  3. A flaky test fails
  4. Another branch gets merged in
  5. One reassigns to marge
  6. A new merge commit is pushed, but the previous one is still there

This is a bit ugly, specially since the first commit will be marked as "Tested-by: marge" even though CI failed there. Ideally, the second time around, the failed merge-commit would be identified and removed.

Trigger pipelines for merge requests

Since GitLab does not support pipeline for merge requests yet (see https://gitlab.com/gitlab-org/gitlab-ce/issues/23902), can marge-bot take care of it?

I'd like her to:

  1. Check if a pipeline has been created on the MR (or the branch it comes from)
  2. Check if it is the correct pipeline (if it includes the right jobs, at least)
  3. If either is no, trigger a pipeline for the MR and wait for completion

The reason is that for expensive tests one may not want to run them for every push to every branch, but they must be run on a MR if it's going to go into master. The CI configuration could be set up to run these tests only for, say, triggers and web, but can't enforce them to run on MRs. A possibility is running the test for some specially-named branches by setting a branch regexp for the CI, and require MRs to use these names, but that needs some discipline which is hard to find (although marge-bot could help here too).

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.