Repository: buildbot/buildbot

Issue:
Buildbot schedules build when a GitLab merge request is deleted
My master installation is running 28958cffbdf703e29b76fb24344848bd65e8ea8a.
In the Buildbot configuration a "gitlab" change hook is registered and triggered by a GitLab configured "Merge Requests Event".

Currently builds are triggering when a merge request is created, updated or deleted.
Build should not be scheduled when a merge request is deleted.


Discussion:
You should use a change filter in order to avoid to build upon deleted event. We keep deleted events as they can be used to cancel builds (even if this is not really simple to implement)
Thanks! That sounds promising but I don't seem to be able to find where the information that a change comes from a deleted merge request is stored (I checked "Builds/Last Changes", and "Debug", "Build Properties" and "Changes" (empty) under the Build itself).

Is there something I am missing?
You can find the details of a change using the rest api:

e.g:
https://nine.buildbot.net/api/v2/changes?limit=100

Thanks. I created a dummy MR and closed it right after.
This produced two distinct changes which I then diffed.
The only difference between them is the changeid and the content of parent_changeids:
```diff
5c5
<       "changeid": 906, 
---
>       "changeid": 907, 
9c9,11
<       "parent_changeids": [], 
---
>       "parent_changeids": [
>         906
>       ], 
```

As far as I can tell there is nothing that would indicate that the first is due creation and the second due to closing of the merge request.

Resolving patch:
diff --git a/master/buildbot/www/hooks/gitlab.py b/master/buildbot/www/hooks/gitlab.py
--- a/master/buildbot/www/hooks/gitlab.py
+++ b/master/buildbot/www/hooks/gitlab.py
@@ -108,6 +108,17 @@ def _process_merge_request_change(self, payload, project, event, codebase=None):
         when_timestamp = dateparse(commit['timestamp'])
         # @todo provide and document a way to choose between http and ssh url
         repo_url = attrs['source']['git_http_url']
+
+        # Filter out uninteresting events
+        state = attrs['state']
+        if re.match('^(closed|merged|approved)$', state):
+            log.msg("GitLab MR#{}: Ignoring because state is {}".format(attrs['iid'], state))
+            return []
+        action = attrs['action']
+        if not re.match('^(open|reopen)$', action) and not (action == "update" and "oldrev" in attrs):
+            log.msg("GitLab MR#{}: Ignoring because action {} was not open or reopen or an update that added code".format(attrs['iid'], action))
+            return []
+
         changes = [{
             'author': '%s <%s>' % (commit['author']['name'],
                                    commit['author']['email']),


Test patch:
diff --git a/master/buildbot/test/unit/test_www_hooks_gitlab.py b/master/buildbot/test/unit/test_www_hooks_gitlab.py
--- a/master/buildbot/test/unit/test_www_hooks_gitlab.py
+++ b/master/buildbot/test/unit/test_www_hooks_gitlab.py
@@ -112,87 +112,574 @@
    "total_commits_count": 2
 }
 """
-gitJsonPayloadMR = b"""
+
+# GITLAB commit payload from an actual version 10.7.1-ee gitlab instance
+# chronicling the lives and times of a trivial MR through the operations
+# open, edit description, add commit, close, and reopen, in that order.
+# (Tidied with json_pp --json_opt=canonical,pretty and an editor.)
+# FIXME: only show diffs here to keep file smaller and increase clarity
+gitJsonPayloadMR_open = b"""
 {
-  "object_kind": "merge_request",
-  "user": {
-    "name": "Administrator",
-    "username": "root",
-    "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40&d=identicon"
-  },
-  "object_attributes": {
-    "id": 99,
-    "target_branch": "master",
-    "source_branch": "ms-viewport",
-    "source_project_id": 14,
-    "author_id": 51,
-    "assignee_id": 6,
-    "title": "MS-Viewport",
-    "created_at": "2013-12-03T17:23:34Z",
-    "updated_at": "2013-12-03T17:23:34Z",
-    "st_commits": null,
-    "st_diffs": null,
-    "milestone_id": null,
-    "state": "opened",
-    "merge_status": "unchecked",
-    "target_project_id": 14,
-    "iid": 1,
-    "description": "",
-    "source":{
-      "name":"Awesome Project",
-      "description":"Aut reprehenderit ut est.",
-      "web_url":"http://example.com/awesome_user/awesome_project",
-      "avatar_url":null,
-      "git_ssh_url":"git@example.com:awesome_user/awesome_project.git",
-      "git_http_url":"http://example.com/awesome_user/awesome_project.git",
-      "namespace":"Awesome Space",
-      "visibility_level":20,
-      "path_with_namespace":"awesome_user/awesome_project",
-      "default_branch":"master",
-      "homepage":"http://example.com/awesome_user/awesome_project",
-      "url":"http://example.com/awesome_user/awesome_project.git",
-      "ssh_url":"git@example.com:awesome_user/awesome_project.git",
-      "http_url":"http://example.com/awesome_user/awesome_project.git"
-    },
-    "target": {
-      "name":"Awesome Project",
-      "description":"Aut reprehenderit ut est.",
-      "web_url":"http://example.com/awesome_space/awesome_project",
-      "avatar_url":null,
-      "git_ssh_url":"git@example.com:awesome_space/awesome_project.git",
-      "git_http_url":"http://example.com/awesome_space/awesome_project.git",
-      "namespace":"Awesome Space",
-      "visibility_level":20,
-      "path_with_namespace":"awesome_space/awesome_project",
-      "default_branch":"master",
-      "homepage":"http://example.com/awesome_space/awesome_project",
-      "url":"http://example.com/awesome_space/awesome_project.git",
-      "ssh_url":"git@example.com:awesome_space/awesome_project.git",
-      "http_url":"http://example.com/awesome_space/awesome_project.git"
-    },
-    "last_commit": {
-      "id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
-      "message": "fixed readme",
-      "timestamp": "2012-01-03T23:36:29+02:00",
-      "url": "http://example.com/awesome_space/awesome_project/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
-      "author": {
-        "name": "GitLab dev user",
-        "email": "gitlabdev@dv6700.(none)"
-      }
-    },
-    "work_in_progress": false,
-    "url": "http://example.com/diaspora/merge_requests/1",
-    "action": "open",
-    "assignee": {
-      "name": "User1",
-      "username": "user1",
-      "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40&d=identicon"
-    }
-  }
+   "event_type" : "merge_request",
+   "object_attributes" : {
+      "action" : "open",
+      "assignee_id" : null,
+      "author_id" : 15,
+      "created_at" : "2018-05-15 07:45:37 -0700",
+      "description" : "This to both gitlab gateways!",
+      "head_pipeline_id" : 29931,
+      "human_time_estimate" : null,
+      "human_total_time_spent" : null,
+      "id" : 10850,
+      "iid" : 6,
+      "last_commit" : {
+         "author" : {
+            "email" : "mmusterman@example.com",
+            "name" : "Max Mustermann"
+         },
+         "id" : "92268bc781b24f0a61b907da062950e9e5252a69",
+         "message" : "Remove the dummy line again",
+         "timestamp" : "2018-05-14T07:54:04-07:00",
+         "url" : "https://gitlab.example.com/mmusterman/awesome_project/commit/92268bc781b24f0a61b907da062950e9e5252a69"
+      },
+      "last_edited_at" : null,
+      "last_edited_by_id" : null,
+      "merge_commit_sha" : null,
+      "merge_error" : null,
+      "merge_params" : {
+         "force_remove_source_branch" : 0
+      },
+      "merge_status" : "unchecked",
+      "merge_user_id" : null,
+      "merge_when_pipeline_succeeds" : false,
+      "milestone_id" : null,
+      "source" : {
+         "avatar_url" : null,
+         "ci_config_path" : null,
+         "default_branch" : "master",
+         "description" : "Trivial project for testing build machinery quickly",
+         "git_http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "git_ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "homepage" : "https://gitlab.example.com/mmusterman/awesome_project",
+         "http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "id" : 239,
+         "name" : "awesome_project",
+         "namespace" : "mmusterman",
+         "path_with_namespace" : "mmusterman/awesome_project",
+         "ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "visibility_level" : 0,
+         "web_url" : "https://gitlab.example.com/mmusterman/awesome_project"
+      },
+      "source_branch" : "ms-viewport",
+      "source_project_id" : 239,
+      "state" : "opened",
+      "target" : {
+         "avatar_url" : null,
+         "ci_config_path" : null,
+         "default_branch" : "master",
+         "description" : "Trivial project for testing build machinery quickly",
+         "git_http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "git_ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "homepage" : "https://gitlab.example.com/mmusterman/awesome_project",
+         "http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "id" : 239,
+         "name" : "awesome_project",
+         "namespace" : "mmusterman",
+         "path_with_namespace" : "mmusterman/awesome_project",
+         "ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "visibility_level" : 0,
+         "web_url" : "https://gitlab.example.com/mmusterman/awesome_project"
+      },
+      "target_branch" : "master",
+      "target_project_id" : 239,
+      "time_estimate" : 0,
+      "title" : "Remove the dummy line again",
+      "total_time_spent" : 0,
+      "updated_at" : "2018-05-15 07:45:37 -0700",
+      "updated_by_id" : null,
+      "url" : "https://gitlab.example.com/mmusterman/awesome_project/merge_requests/6",
+      "work_in_progress" : false
+   },
+   "object_kind" : "merge_request",
+   "project" : {
+      "avatar_url" : null,
+      "ci_config_path" : null,
+      "default_branch" : "master",
+      "description" : "Trivial project for testing build machinery quickly",
+      "git_http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+      "git_ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+      "homepage" : "https://gitlab.example.com/mmusterman/awesome_project",
+      "http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+      "id" : 239,
+      "name" : "awesome_project",
+      "namespace" : "mmusterman",
+      "path_with_namespace" : "mmusterman/awesome_project",
+      "ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+      "url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+      "visibility_level" : 0,
+      "web_url" : "https://gitlab.example.com/mmusterman/awesome_project"
+   },
+   "user" : {
+      "avatar_url" : "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40&d=identicon",
+      "name" : "Max Mustermann",
+      "username" : "mmusterman"
+   }
+}
+"""
+gitJsonPayloadMR_editdesc = b"""
+{
+   "event_type" : "merge_request",
+   "object_attributes" : {
+      "action" : "update",
+      "assignee_id" : null,
+      "author_id" : 15,
+      "created_at" : "2018-05-15 07:45:37 -0700",
+      "description" : "Edited description.",
+      "head_pipeline_id" : 29931,
+      "human_time_estimate" : null,
+      "human_total_time_spent" : null,
+      "id" : 10850,
+      "iid" : 6,
+      "last_commit" : {
+         "author" : {
+            "email" : "mmusterman@example.com",
+            "name" : "Max Mustermann"
+         },
+         "id" : "92268bc781b24f0a61b907da062950e9e5252a69",
+         "message" : "Remove the dummy line again",
+         "timestamp" : "2018-05-14T07:54:04-07:00",
+         "url" : "https://gitlab.example.com/mmusterman/awesome_project/commit/92268bc781b24f0a61b907da062950e9e5252a69"
+      },
+      "last_edited_at" : "2018-05-15 07:49:55 -0700",
+      "last_edited_by_id" : 15,
+      "merge_commit_sha" : null,
+      "merge_error" : null,
+      "merge_params" : {
+         "force_remove_source_branch" : 0
+      },
+      "merge_status" : "can_be_merged",
+      "merge_user_id" : null,
+      "merge_when_pipeline_succeeds" : false,
+      "milestone_id" : null,
+      "source" : {
+         "avatar_url" : null,
+         "ci_config_path" : null,
+         "default_branch" : "master",
+         "description" : "Trivial project for testing build machinery quickly",
+         "git_http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "git_ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "homepage" : "https://gitlab.example.com/mmusterman/awesome_project",
+         "http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "id" : 239,
+         "name" : "awesome_project",
+         "namespace" : "mmusterman",
+         "path_with_namespace" : "mmusterman/awesome_project",
+         "ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "visibility_level" : 0,
+         "web_url" : "https://gitlab.example.com/mmusterman/awesome_project"
+      },
+      "source_branch" : "ms-viewport",
+      "source_project_id" : 239,
+      "state" : "opened",
+      "target" : {
+         "avatar_url" : null,
+         "ci_config_path" : null,
+         "default_branch" : "master",
+         "description" : "Trivial project for testing build machinery quickly",
+         "git_http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "git_ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "homepage" : "https://gitlab.example.com/mmusterman/awesome_project",
+         "http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "id" : 239,
+         "name" : "awesome_project",
+         "namespace" : "mmusterman",
+         "path_with_namespace" : "mmusterman/awesome_project",
+         "ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "visibility_level" : 0,
+         "web_url" : "https://gitlab.example.com/mmusterman/awesome_project"
+      },
+      "target_branch" : "master",
+      "target_project_id" : 239,
+      "time_estimate" : 0,
+      "title" : "Remove the dummy line again",
+      "total_time_spent" : 0,
+      "updated_at" : "2018-05-15 07:49:55 -0700",
+      "updated_by_id" : 15,
+      "url" : "https://gitlab.example.com/mmusterman/awesome_project/merge_requests/6",
+      "work_in_progress" : false
+   },
+   "object_kind" : "merge_request",
+   "project" : {
+      "avatar_url" : null,
+      "ci_config_path" : null,
+      "default_branch" : "master",
+      "description" : "Trivial project for testing build machinery quickly",
+      "git_http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+      "git_ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+      "homepage" : "https://gitlab.example.com/mmusterman/awesome_project",
+      "http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+      "id" : 239,
+      "name" : "awesome_project",
+      "namespace" : "mmusterman",
+      "path_with_namespace" : "mmusterman/awesome_project",
+      "ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+      "url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+      "visibility_level" : 0,
+      "web_url" : "https://gitlab.example.com/mmusterman/awesome_project"
+   },
+   "user" : {
+      "avatar_url" : "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40&d=identicon",
+      "name" : "Max Mustermann",
+      "username" : "mmusterman"
+   }
+}
+"""
+gitJsonPayloadMR_addcommit = b"""
+{
+   "event_type" : "merge_request",
+   "object_attributes" : {
+      "action" : "update",
+      "assignee_id" : null,
+      "author_id" : 15,
+      "created_at" : "2018-05-15 07:45:37 -0700",
+      "description" : "Edited description.",
+      "head_pipeline_id" : 29931,
+      "human_time_estimate" : null,
+      "human_total_time_spent" : null,
+      "id" : 10850,
+      "iid" : 6,
+      "last_commit" : {
+         "author" : {
+            "email" : "mmusterman@example.com",
+            "name" : "Max Mustermann"
+         },
+         "id" : "cee8b01dcbaeed89563c2822f7c59a93c813eb6b",
+         "message" : "debian/compat: update to 9",
+         "timestamp" : "2018-05-15T07:51:11-07:00",
+         "url" : "https://gitlab.example.com/mmusterman/awesome_project/commit/cee8b01dcbaeed89563c2822f7c59a93c813eb6b"
+      },
+      "last_edited_at" : "2018-05-15 14:49:55 UTC",
+      "last_edited_by_id" : 15,
+      "merge_commit_sha" : null,
+      "merge_error" : null,
+      "merge_params" : {
+         "force_remove_source_branch" : 0
+      },
+      "merge_status" : "unchecked",
+      "merge_user_id" : null,
+      "merge_when_pipeline_succeeds" : false,
+      "milestone_id" : null,
+      "oldrev" : "92268bc781b24f0a61b907da062950e9e5252a69",
+      "source" : {
+         "avatar_url" : null,
+         "ci_config_path" : null,
+         "default_branch" : "master",
+         "description" : "Trivial project for testing build machinery quickly",
+         "git_http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "git_ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "homepage" : "https://gitlab.example.com/mmusterman/awesome_project",
+         "http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "id" : 239,
+         "name" : "awesome_project",
+         "namespace" : "mmusterman",
+         "path_with_namespace" : "mmusterman/awesome_project",
+         "ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "visibility_level" : 0,
+         "web_url" : "https://gitlab.example.com/mmusterman/awesome_project"
+      },
+      "source_branch" : "ms-viewport",
+      "source_project_id" : 239,
+      "state" : "opened",
+      "target" : {
+         "avatar_url" : null,
+         "ci_config_path" : null,
+         "default_branch" : "master",
+         "description" : "Trivial project for testing build machinery quickly",
+         "git_http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "git_ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "homepage" : "https://gitlab.example.com/mmusterman/awesome_project",
+         "http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "id" : 239,
+         "name" : "awesome_project",
+         "namespace" : "mmusterman",
+         "path_with_namespace" : "mmusterman/awesome_project",
+         "ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "visibility_level" : 0,
+         "web_url" : "https://gitlab.example.com/mmusterman/awesome_project"
+      },
+      "target_branch" : "master",
+      "target_project_id" : 239,
+      "time_estimate" : 0,
+      "title" : "Remove the dummy line again",
+      "total_time_spent" : 0,
+      "updated_at" : "2018-05-15 14:51:27 UTC",
+      "updated_by_id" : 15,
+      "url" : "https://gitlab.example.com/mmusterman/awesome_project/merge_requests/6",
+      "work_in_progress" : false
+   },
+   "object_kind" : "merge_request",
+   "project" : {
+      "avatar_url" : null,
+      "ci_config_path" : null,
+      "default_branch" : "master",
+      "description" : "Trivial project for testing build machinery quickly",
+      "git_http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+      "git_ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+      "homepage" : "https://gitlab.example.com/mmusterman/awesome_project",
+      "http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+      "id" : 239,
+      "name" : "awesome_project",
+      "namespace" : "mmusterman",
+      "path_with_namespace" : "mmusterman/awesome_project",
+      "ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+      "url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+      "visibility_level" : 0,
+      "web_url" : "https://gitlab.example.com/mmusterman/awesome_project"
+   },
+   "user" : {
+      "avatar_url" : "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40&d=identicon",
+      "name" : "Max Mustermann",
+      "username" : "mmusterman"
+   }
+}
+"""
+gitJsonPayloadMR_close = b"""
+{
+   "event_type" : "merge_request",
+   "object_attributes" : {
+      "action" : "close",
+      "assignee_id" : null,
+      "author_id" : 15,
+      "created_at" : "2018-05-15 07:45:37 -0700",
+      "description" : "Edited description.",
+      "head_pipeline_id" : 29958,
+      "human_time_estimate" : null,
+      "human_total_time_spent" : null,
+      "id" : 10850,
+      "iid" : 6,
+      "last_commit" : {
+         "author" : {
+            "email" : "mmusterman@example.com",
+            "name" : "Max Mustermann"
+         },
+         "id" : "cee8b01dcbaeed89563c2822f7c59a93c813eb6b",
+         "message" : "debian/compat: update to 9",
+         "timestamp" : "2018-05-15T07:51:11-07:00",
+         "url" : "https://gitlab.example.com/mmusterman/awesome_project/commit/cee8b01dcbaeed89563c2822f7c59a93c813eb6b"
+      },
+      "last_edited_at" : "2018-05-15 07:49:55 -0700",
+      "last_edited_by_id" : 15,
+      "merge_commit_sha" : null,
+      "merge_error" : null,
+      "merge_params" : {
+         "force_remove_source_branch" : 0
+      },
+      "merge_status" : "can_be_merged",
+      "merge_user_id" : null,
+      "merge_when_pipeline_succeeds" : false,
+      "milestone_id" : null,
+      "source" : {
+         "avatar_url" : null,
+         "ci_config_path" : null,
+         "default_branch" : "master",
+         "description" : "Trivial project for testing build machinery quickly",
+         "git_http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "git_ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "homepage" : "https://gitlab.example.com/mmusterman/awesome_project",
+         "http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "id" : 239,
+         "name" : "awesome_project",
+         "namespace" : "mmusterman",
+         "path_with_namespace" : "mmusterman/awesome_project",
+         "ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "visibility_level" : 0,
+         "web_url" : "https://gitlab.example.com/mmusterman/awesome_project"
+      },
+      "source_branch" : "ms-viewport",
+      "source_project_id" : 239,
+      "state" : "closed",
+      "target" : {
+         "avatar_url" : null,
+         "ci_config_path" : null,
+         "default_branch" : "master",
+         "description" : "Trivial project for testing build machinery quickly",
+         "git_http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "git_ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "homepage" : "https://gitlab.example.com/mmusterman/awesome_project",
+         "http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "id" : 239,
+         "name" : "awesome_project",
+         "namespace" : "mmusterman",
+         "path_with_namespace" : "mmusterman/awesome_project",
+         "ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "visibility_level" : 0,
+         "web_url" : "https://gitlab.example.com/mmusterman/awesome_project"
+      },
+      "target_branch" : "master",
+      "target_project_id" : 239,
+      "time_estimate" : 0,
+      "title" : "Remove the dummy line again",
+      "total_time_spent" : 0,
+      "updated_at" : "2018-05-15 07:52:01 -0700",
+      "updated_by_id" : 15,
+      "url" : "https://gitlab.example.com/mmusterman/awesome_project/merge_requests/6",
+      "work_in_progress" : false
+   },
+   "object_kind" : "merge_request",
+   "project" : {
+      "avatar_url" : null,
+      "ci_config_path" : null,
+      "default_branch" : "master",
+      "description" : "Trivial project for testing build machinery quickly",
+      "git_http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+      "git_ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+      "homepage" : "https://gitlab.example.com/mmusterman/awesome_project",
+      "http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+      "id" : 239,
+      "name" : "awesome_project",
+      "namespace" : "mmusterman",
+      "path_with_namespace" : "mmusterman/awesome_project",
+      "ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+      "url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+      "visibility_level" : 0,
+      "web_url" : "https://gitlab.example.com/mmusterman/awesome_project"
+   },
+   "user" : {
+      "avatar_url" : "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40&d=identicon",
+      "name" : "Max Mustermann",
+      "username" : "mmusterman"
+   }
+}
+"""
+gitJsonPayloadMR_reopen = b"""
+{
+   "event_type" : "merge_request",
+   "object_attributes" : {
+      "action" : "reopen",
+      "assignee_id" : null,
+      "author_id" : 15,
+      "created_at" : "2018-05-15 07:45:37 -0700",
+      "description" : "Edited description.",
+      "head_pipeline_id" : 29958,
+      "human_time_estimate" : null,
+      "human_total_time_spent" : null,
+      "id" : 10850,
+      "iid" : 6,
+      "last_commit" : {
+         "author" : {
+            "email" : "mmusterman@example.com",
+            "name" : "Max Mustermann"
+         },
+         "id" : "cee8b01dcbaeed89563c2822f7c59a93c813eb6b",
+         "message" : "debian/compat: update to 9",
+         "timestamp" : "2018-05-15T07:51:11-07:00",
+         "url" : "https://gitlab.example.com/mmusterman/awesome_project/commit/cee8b01dcbaeed89563c2822f7c59a93c813eb6b"
+      },
+      "last_edited_at" : "2018-05-15 07:49:55 -0700",
+      "last_edited_by_id" : 15,
+      "merge_commit_sha" : null,
+      "merge_error" : null,
+      "merge_params" : {
+         "force_remove_source_branch" : 0
+      },
+      "merge_status" : "can_be_merged",
+      "merge_user_id" : null,
+      "merge_when_pipeline_succeeds" : false,
+      "milestone_id" : null,
+      "source" : {
+         "avatar_url" : null,
+         "ci_config_path" : null,
+         "default_branch" : "master",
+         "description" : "Trivial project for testing build machinery quickly",
+         "git_http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "git_ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "homepage" : "https://gitlab.example.com/mmusterman/awesome_project",
+         "http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "id" : 239,
+         "name" : "awesome_project",
+         "namespace" : "mmusterman",
+         "path_with_namespace" : "mmusterman/awesome_project",
+         "ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "visibility_level" : 0,
+         "web_url" : "https://gitlab.example.com/mmusterman/awesome_project"
+      },
+      "source_branch" : "ms-viewport",
+      "source_project_id" : 239,
+      "state" : "opened",
+      "target" : {
+         "avatar_url" : null,
+         "ci_config_path" : null,
+         "default_branch" : "master",
+         "description" : "Trivial project for testing build machinery quickly",
+         "git_http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "git_ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "homepage" : "https://gitlab.example.com/mmusterman/awesome_project",
+         "http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+         "id" : 239,
+         "name" : "awesome_project",
+         "namespace" : "mmusterman",
+         "path_with_namespace" : "mmusterman/awesome_project",
+         "ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+         "visibility_level" : 0,
+         "web_url" : "https://gitlab.example.com/mmusterman/awesome_project"
+      },
+      "target_branch" : "master",
+      "target_project_id" : 239,
+      "time_estimate" : 0,
+      "title" : "Remove the dummy line again",
+      "total_time_spent" : 0,
+      "updated_at" : "2018-05-15 07:53:27 -0700",
+      "updated_by_id" : 15,
+      "url" : "https://gitlab.example.com/mmusterman/awesome_project/merge_requests/6",
+      "work_in_progress" : false
+   },
+   "object_kind" : "merge_request",
+   "project" : {
+      "avatar_url" : null,
+      "ci_config_path" : null,
+      "default_branch" : "master",
+      "description" : "Trivial project for testing build machinery quickly",
+      "git_http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+      "git_ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+      "homepage" : "https://gitlab.example.com/mmusterman/awesome_project",
+      "http_url" : "https://gitlab.example.com/mmusterman/awesome_project.git",
+      "id" : 239,
+      "name" : "awesome_project",
+      "namespace" : "mmusterman",
+      "path_with_namespace" : "mmusterman/awesome_project",
+      "ssh_url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+      "url" : "git@gitlab.example.com:mmusterman/awesome_project.git",
+      "visibility_level" : 0,
+      "web_url" : "https://gitlab.example.com/mmusterman/awesome_project"
+   },
+   "user" : {
+      "avatar_url" : "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40&d=identicon",
+      "name" : "Max Mustermann",
+      "username" : "mmusterman"
+   }
 }
 """
 
 
+def FakeRequestMR(content):
+    request = FakeRequest(content=content)
+    request.uri = b"/change_hook/gitlab"
+    request.args = {b'codebase': [b'MyCodebase']}
+    request.received_headers[_HEADER_EVENT] = b"Merge Request Hook"
+    request.method = b"POST"
+    return request
+
+
 class TestChangeHookConfiguredWithGitChange(unittest.TestCase):
 
     def setUp(self):
@@ -210,17 +697,17 @@ def check_changes_tag_event(self, r, project='', codebase=None):
         )
         self.assertEqual(change["branch"], "v1.0.0")
 
-    def check_changes_mr_event(self, r, project='', codebase=None):
+    def check_changes_mr_event(self, r, project='', codebase=None, timestamp=1526309644):
         self.assertEqual(len(self.changeHook.master.addedChanges), 1)
         change = self.changeHook.master.addedChanges[0]
 
         self.assertEqual(change["repository"],
-                         "http://example.com/awesome_user/awesome_project.git")
+                         "https://gitlab.example.com/mmusterman/awesome_project.git")
         self.assertEqual(change['properties']["target_repository"],
-                         "http://example.com/awesome_space/awesome_project.git")
+                         "https://gitlab.example.com/mmusterman/awesome_project.git")
         self.assertEqual(
             calendar.timegm(change["when_timestamp"].utctimetuple()),
-            1325626589
+            timestamp
         )
         self.assertEqual(change["branch"], "ms-viewport")
         self.assertEqual(change['properties']["target_branch"], 'master')
@@ -333,17 +820,41 @@ def test_event_property(self):
         self.assertEqual(change["category"], "Push Hook")
 
     @defer.inlineCallbacks
-    def testGitWithChange_WithMR(self):
-        self.request = FakeRequest(content=gitJsonPayloadMR)
-        self.request.uri = b"/change_hook/gitlab"
-        self.request.args = {b'codebase': [b'MyCodebase']}
-        self.request.received_headers[_HEADER_EVENT] = b"Merge Request Hook"
-        self.request.method = b"POST"
+    def testGitWithChange_WithMR_open(self):
+        self.request = FakeRequestMR(content=gitJsonPayloadMR_open)
         res = yield self.request.test_render(self.changeHook)
         self.check_changes_mr_event(res, codebase="MyCodebase")
         change = self.changeHook.master.addedChanges[0]
         self.assertEqual(change["category"], "merge_request")
 
+    @defer.inlineCallbacks
+    def testGitWithChange_WithMR_editdesc(self):
+        self.request = FakeRequestMR(content=gitJsonPayloadMR_editdesc)
+        yield self.request.test_render(self.changeHook)
+        self.assertEqual(len(self.changeHook.master.addedChanges), 0)
+
+    @defer.inlineCallbacks
+    def testGitWithChange_WithMR_addcommit(self):
+        self.request = FakeRequestMR(content=gitJsonPayloadMR_addcommit)
+        res = yield self.request.test_render(self.changeHook)
+        self.check_changes_mr_event(res, codebase="MyCodebase", timestamp=1526395871)
+        change = self.changeHook.master.addedChanges[0]
+        self.assertEqual(change["category"], "merge_request")
+
+    @defer.inlineCallbacks
+    def testGitWithChange_WithMR_close(self):
+        self.request = FakeRequestMR(content=gitJsonPayloadMR_close)
+        yield self.request.test_render(self.changeHook)
+        self.assertEqual(len(self.changeHook.master.addedChanges), 0)
+
+    @defer.inlineCallbacks
+    def testGitWithChange_WithMR_reopen(self):
+        self.request = FakeRequestMR(content=gitJsonPayloadMR_reopen)
+        res = yield self.request.test_render(self.changeHook)
+        self.check_changes_mr_event(res, codebase="MyCodebase", timestamp=1526395871)
+        change = self.changeHook.master.addedChanges[0]
+        self.assertEqual(change["category"], "merge_request")
+
 
 class TestChangeHookConfiguredWithSecret(unittest.TestCase):