packages feed

gitlab-haskell 0.2.2 → 0.2.3

raw patch · 7 files changed

+487/−73 lines, 7 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ GitLab.SystemHooks.Rules: ruleAddMembers :: String -> [Text] -> [Text] -> Rule
+ GitLab.SystemHooks.Rules: ruleAddNewUserToGroups :: String -> [Text] -> [Text] -> Rule
+ GitLab.SystemHooks.Types: MergeParams :: Text -> MergeParams
+ GitLab.SystemHooks.Types: MergeRequestEvent :: Text -> UserEvent -> ProjectEvent -> ObjectAttributes -> Maybe Text -> RepositoryEvent -> MergeRequestEvent
+ GitLab.SystemHooks.Types: ObjectAttributes :: Int -> Text -> Text -> Int -> Int -> Int -> Text -> Text -> Text -> Maybe Int -> Text -> Text -> Int -> Int -> Text -> Maybe Int -> Maybe Text -> MergeParams -> Bool -> Maybe Int -> Maybe Text -> Maybe Text -> Maybe Text -> Maybe Int -> Int -> Text -> Int -> Int -> Bool -> Maybe Int -> ProjectEvent -> ProjectEvent -> CommitEvent -> Bool -> Int -> Maybe Int -> Maybe Int -> ObjectAttributes
+ GitLab.SystemHooks.Types: ProjectChanges :: Text -> Text -> Text -> ProjectChanges
+ GitLab.SystemHooks.Types: RepositoryUpdate :: Text -> Int -> Text -> Text -> Text -> Int -> ProjectEvent -> [ProjectChanges] -> [Text] -> RepositoryUpdate
+ GitLab.SystemHooks.Types: UserEvent :: Text -> Text -> Text -> UserEvent
+ GitLab.SystemHooks.Types: [$sel:mergeParams_force_remove_source_branch:MergeParams] :: MergeParams -> Text
+ GitLab.SystemHooks.Types: [$sel:mergeRequest_labels:MergeRequestEvent] :: MergeRequestEvent -> Maybe Text
+ GitLab.SystemHooks.Types: [$sel:mergeRequest_object_attributes:MergeRequestEvent] :: MergeRequestEvent -> ObjectAttributes
+ GitLab.SystemHooks.Types: [$sel:mergeRequest_object_kind:MergeRequestEvent] :: MergeRequestEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:mergeRequest_project:MergeRequestEvent] :: MergeRequestEvent -> ProjectEvent
+ GitLab.SystemHooks.Types: [$sel:mergeRequest_repository:MergeRequestEvent] :: MergeRequestEvent -> RepositoryEvent
+ GitLab.SystemHooks.Types: [$sel:mergeRequest_user:MergeRequestEvent] :: MergeRequestEvent -> UserEvent
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_assignee_id:ObjectAttributes] :: ObjectAttributes -> Int
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_author_id:ObjectAttributes] :: ObjectAttributes -> Int
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_created_at:ObjectAttributes] :: ObjectAttributes -> Text
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_deleted_at:ObjectAttributes] :: ObjectAttributes -> Maybe Text
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_description:ObjectAttributes] :: ObjectAttributes -> Text
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_head_pipeline_id:ObjectAttributes] :: ObjectAttributes -> Int
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_human_time_estimate:ObjectAttributes] :: ObjectAttributes -> Maybe Int
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_human_total_time_spent:ObjectAttributes] :: ObjectAttributes -> Maybe Int
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_id:ObjectAttributes] :: ObjectAttributes -> Int
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_iid:ObjectAttributes] :: ObjectAttributes -> Int
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_in_progress_merge_commit_sha:ObjectAttributes] :: ObjectAttributes -> Maybe Text
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_last_commit:ObjectAttributes] :: ObjectAttributes -> CommitEvent
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_last_edited_at:ObjectAttributes] :: ObjectAttributes -> Text
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_last_edited_by_id:ObjectAttributes] :: ObjectAttributes -> Int
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_lock_version:ObjectAttributes] :: ObjectAttributes -> Maybe Int
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_merge_commit_sha:ObjectAttributes] :: ObjectAttributes -> Maybe Text
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_merge_error:ObjectAttributes] :: ObjectAttributes -> Maybe Text
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_merge_jid:ObjectAttributes] :: ObjectAttributes -> Maybe Int
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_merge_params:ObjectAttributes] :: ObjectAttributes -> MergeParams
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_merge_status:ObjectAttributes] :: ObjectAttributes -> Text
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_merge_user_id:ObjectAttributes] :: ObjectAttributes -> Maybe Int
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_merge_when_pipeline_succeeds:ObjectAttributes] :: ObjectAttributes -> Bool
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_milestone_id:ObjectAttributes] :: ObjectAttributes -> Maybe Int
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_ref_fetched:ObjectAttributes] :: ObjectAttributes -> Bool
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_source:ObjectAttributes] :: ObjectAttributes -> ProjectEvent
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_source_branch:ObjectAttributes] :: ObjectAttributes -> Text
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_source_project_id:ObjectAttributes] :: ObjectAttributes -> Int
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_state:ObjectAttributes] :: ObjectAttributes -> Text
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_target:ObjectAttributes] :: ObjectAttributes -> ProjectEvent
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_target_branch:ObjectAttributes] :: ObjectAttributes -> Text
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_target_project_id:ObjectAttributes] :: ObjectAttributes -> Int
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_time_estimate:ObjectAttributes] :: ObjectAttributes -> Int
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_title:ObjectAttributes] :: ObjectAttributes -> Text
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_total_time_spent:ObjectAttributes] :: ObjectAttributes -> Int
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_updated_at:ObjectAttributes] :: ObjectAttributes -> Text
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_updated_by_id:ObjectAttributes] :: ObjectAttributes -> Maybe Int
+ GitLab.SystemHooks.Types: [$sel:objectAttributes_work_in_progress:ObjectAttributes] :: ObjectAttributes -> Bool
+ GitLab.SystemHooks.Types: [$sel:projectChanges_after:ProjectChanges] :: ProjectChanges -> Text
+ GitLab.SystemHooks.Types: [$sel:projectChanges_before:ProjectChanges] :: ProjectChanges -> Text
+ GitLab.SystemHooks.Types: [$sel:projectChanges_ref:ProjectChanges] :: ProjectChanges -> Text
+ GitLab.SystemHooks.Types: [$sel:repositoryUpdate_changes:RepositoryUpdate] :: RepositoryUpdate -> [ProjectChanges]
+ GitLab.SystemHooks.Types: [$sel:repositoryUpdate_event_name:RepositoryUpdate] :: RepositoryUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:repositoryUpdate_project:RepositoryUpdate] :: RepositoryUpdate -> ProjectEvent
+ GitLab.SystemHooks.Types: [$sel:repositoryUpdate_project_id:RepositoryUpdate] :: RepositoryUpdate -> Int
+ GitLab.SystemHooks.Types: [$sel:repositoryUpdate_refs:RepositoryUpdate] :: RepositoryUpdate -> [Text]
+ GitLab.SystemHooks.Types: [$sel:repositoryUpdate_user_avatar:RepositoryUpdate] :: RepositoryUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:repositoryUpdate_user_email:RepositoryUpdate] :: RepositoryUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:repositoryUpdate_user_id:RepositoryUpdate] :: RepositoryUpdate -> Int
+ GitLab.SystemHooks.Types: [$sel:repositoryUpdate_user_name:RepositoryUpdate] :: RepositoryUpdate -> Text
+ GitLab.SystemHooks.Types: [$sel:userEvent_avatar_url:UserEvent] :: UserEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:userEvent_name:UserEvent] :: UserEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:userEvent_username:UserEvent] :: UserEvent -> Text
+ GitLab.SystemHooks.Types: data MergeParams
+ GitLab.SystemHooks.Types: data MergeRequestEvent
+ GitLab.SystemHooks.Types: data ObjectAttributes
+ GitLab.SystemHooks.Types: data ProjectChanges
+ GitLab.SystemHooks.Types: data RepositoryUpdate
+ GitLab.SystemHooks.Types: data UserEvent
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.MergeParams
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.MergeRequestEvent
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.ObjectAttributes
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.ProjectChanges
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.RepositoryUpdate
+ GitLab.SystemHooks.Types: instance Data.Aeson.Types.FromJSON.FromJSON GitLab.SystemHooks.Types.UserEvent
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.MergeParams
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.MergeRequestEvent
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.ObjectAttributes
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.ProjectChanges
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.RepositoryUpdate
+ GitLab.SystemHooks.Types: instance GHC.Classes.Eq GitLab.SystemHooks.Types.UserEvent
+ GitLab.SystemHooks.Types: instance GHC.Generics.Generic GitLab.SystemHooks.Types.MergeParams
+ GitLab.SystemHooks.Types: instance GHC.Generics.Generic GitLab.SystemHooks.Types.MergeRequestEvent
+ GitLab.SystemHooks.Types: instance GHC.Generics.Generic GitLab.SystemHooks.Types.ObjectAttributes
+ GitLab.SystemHooks.Types: instance GHC.Generics.Generic GitLab.SystemHooks.Types.ProjectChanges
+ GitLab.SystemHooks.Types: instance GHC.Generics.Generic GitLab.SystemHooks.Types.UserEvent
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.MergeParams
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.MergeRequestEvent
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.ObjectAttributes
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.ProjectChanges
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.RepositoryUpdate
+ GitLab.SystemHooks.Types: instance GHC.Show.Show GitLab.SystemHooks.Types.UserEvent
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.MergeRequestEvent
+ GitLab.SystemHooks.Types: instance GitLab.SystemHooks.Types.SystemHook GitLab.SystemHooks.Types.RepositoryUpdate
- GitLab.SystemHooks.Types: RepositoryEvent :: Text -> Text -> Text -> Maybe Text -> Text -> Text -> Visibility -> RepositoryEvent
+ GitLab.SystemHooks.Types: RepositoryEvent :: Text -> Text -> Text -> Maybe Text -> Maybe Text -> Maybe Text -> Maybe Visibility -> RepositoryEvent
- GitLab.SystemHooks.Types: [$sel:repositoryEvent_git_http_url:RepositoryEvent] :: RepositoryEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:repositoryEvent_git_http_url:RepositoryEvent] :: RepositoryEvent -> Maybe Text
- GitLab.SystemHooks.Types: [$sel:repositoryEvent_git_ssh_url:RepositoryEvent] :: RepositoryEvent -> Text
+ GitLab.SystemHooks.Types: [$sel:repositoryEvent_git_ssh_url:RepositoryEvent] :: RepositoryEvent -> Maybe Text
- GitLab.SystemHooks.Types: [$sel:repositoryEvent_visibility_level:RepositoryEvent] :: RepositoryEvent -> Visibility
+ GitLab.SystemHooks.Types: [$sel:repositoryEvent_visibility_level:RepositoryEvent] :: RepositoryEvent -> Maybe Visibility

Files

data/system-hooks/repository-update.json view
@@ -1,32 +1,32 @@ {-  "event_name": "repository_update",-  "user_id": 1,-  "user_name": "John Smith",-  "user_email": "admin@example.com",-  "user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80",-  "project_id": 1,-  "project": {-    "name":"Example",-    "description":"",-    "web_url":"http://example.com/jsmith/example",-    "avatar_url":null,-    "git_ssh_url":"git@example.com:jsmith/example.git",-    "git_http_url":"http://example.com/jsmith/example.git",-    "namespace":"Jsmith",-    "visibility_level":0,-    "path_with_namespace":"jsmith/example",-    "default_branch":"master",-    "homepage":"http://example.com/jsmith/example",-    "url":"git@example.com:jsmith/example.git",-    "ssh_url":"git@example.com:jsmith/example.git",-    "http_url":"http://example.com/jsmith/example.git",-  },-  "changes": [-    {-      "before":"8205ea8d81ce0c6b90fbe8280d118cc9fdad6130",-      "after":"4045ea7a3df38697b3730a20fb73c8bed8a3e69e",-      "ref":"refs/heads/master"-    }-  ],-  "refs":["refs/heads/master"]+    "event_name": "repository_update",+    "user_id": 1,+    "user_name": "John Smith",+    "user_email": "admin@example.com",+    "user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80",+    "project_id": 1,+    "project": {+        "name":"Example",+        "description":"",+        "web_url":"http://example.com/jsmith/example",+        "avatar_url":null,+        "git_ssh_url":"git@example.com:jsmith/example.git",+        "git_http_url":"http://example.com/jsmith/example.git",+        "namespace":"Jsmith",+        "visibility_level":0,+        "path_with_namespace":"jsmith/example",+        "default_branch":"master",+        "homepage":"http://example.com/jsmith/example",+        "url":"git@example.com:jsmith/example.git",+        "ssh_url":"git@example.com:jsmith/example.git",+        "http_url":"http://example.com/jsmith/example.git"+    },+    "changes": [+        {+            "before":"8205ea8d81ce0c6b90fbe8280d118cc9fdad6130",+            "after":"4045ea7a3df38697b3730a20fb73c8bed8a3e69e",+            "ref":"refs/heads/master"+        }+    ],+    "refs":["refs/heads/master"] }
gitlab-haskell.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4 name:           gitlab-haskell category:       Git-version:        0.2.2+version:        0.2.3 synopsis:       A Haskell library for the GitLab web API description:             This Haskell library queries and updates the database of a GitLab instance using the GitLab web API: <https://docs.gitlab.com/ee/api/>@@ -77,6 +77,7 @@                 , GitLab.API.Version                 , GitLab.SystemHooks.Types                 , GitLab.SystemHooks.GitLabSystemHooks+                , GitLab.SystemHooks.Rules   other-modules:                   GitLab.WebRequests.GitLabWebCalls   hs-source-dirs:
src/GitLab.hs view
@@ -28,6 +28,7 @@     module GitLab.API.Version,     module GitLab.SystemHooks.GitLabSystemHooks,     module GitLab.SystemHooks.Types,+    module GitLab.SystemHooks.Rules,   ) where @@ -48,6 +49,7 @@ import GitLab.API.Users import GitLab.API.Version import GitLab.SystemHooks.GitLabSystemHooks+import GitLab.SystemHooks.Rules import GitLab.SystemHooks.Types import GitLab.Types import Network.Connection (TLSSettings (..))
src/GitLab/SystemHooks/GitLabSystemHooks.hs view
@@ -149,6 +149,14 @@       (Just (\_ -> return True))       (cast f :: Maybe (TagPush -> GitLab ()))       (parseEvent contents :: Maybe TagPush)+    `orElse` fireIf'+      (Just (\_ -> return True))+      (cast f :: Maybe (RepositoryUpdate -> GitLab ()))+      (parseEvent contents :: Maybe RepositoryUpdate)+    `orElse` fireIf'+      (Just (\_ -> return True))+      (cast f :: Maybe (MergeRequestEvent -> GitLab ()))+      (parseEvent contents :: Maybe MergeRequestEvent) tryFire contents (MatchIf _ predF f) = do   fireIf'     (cast predF :: Maybe (ProjectCreate -> GitLab Bool))@@ -242,6 +250,14 @@       (cast predF :: Maybe (TagPush -> GitLab Bool))       (cast f :: Maybe (TagPush -> GitLab ()))       (parseEvent contents :: Maybe TagPush)+    `orElse` fireIf'+      (cast predF :: Maybe (RepositoryUpdate -> GitLab Bool))+      (cast f :: Maybe (RepositoryUpdate -> GitLab ()))+      (parseEvent contents :: Maybe RepositoryUpdate)+    `orElse` fireIf'+      (cast predF :: Maybe (MergeRequestEvent -> GitLab Bool))+      (cast f :: Maybe (MergeRequestEvent -> GitLab ()))+      (parseEvent contents :: Maybe MergeRequestEvent)  fireIf' :: (Typeable a, Show a) => Maybe (a -> GitLab Bool) -> Maybe (a -> GitLab ()) -> Maybe a -> GitLab Bool fireIf' castPred castF parsed = do
+ src/GitLab/SystemHooks/Rules.hs view
@@ -0,0 +1,81 @@+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module      : GitLab.SystemHooks.Rules+-- Description : Common GitLab system hook rules+-- Copyright   : (c) Rob Stewart, Heriot-Watt University, 2020+-- License     : BSD3+-- Maintainer  : robstewart57@gmail.com+-- Stability   : stable+module GitLab.SystemHooks.Rules (ruleAddMembers, ruleAddNewUserToGroups) where++import Control.Monad+import Data.Text+import GitLab.API.Groups+import GitLab.API.Members+import GitLab.API.Projects+import GitLab.API.Users+import GitLab.SystemHooks.Types+import GitLab.Types++ruleAddNewUserToGroups ::+  -- | rule label+  String ->+  -- | list of (non registered) usernames+  [Text] ->+  -- | list of groups to add new user to+  [Text] ->+  Rule+ruleAddNewUserToGroups lbl nonRegisteredUsernames groupNames =+  matchIf+    lbl+    ( \event@UserCreate {} -> do+        return (userCreate_username event `elem` nonRegisteredUsernames)+    )+    ( \event@UserCreate {} -> do+        mapM_+          ( \groupName ->+              -- will return value of type `Left Status` if user already+              -- member of the group, `void` silently ignores any outcome.+              addUserToGroup' groupName Reporter (userCreate_user_id event)+          )+          groupNames+    )++ruleAddMembers ::+  -- | rule label+  String ->+  -- | project names to match on+  [Text] ->+  -- | user names to add as member of matched project+  [Text] ->+  Rule+ruleAddMembers label projectNames userNames =+  matchIf+    label+    ( \event@ProjectCreate {} -> do+        request <- searchProjectId (projectCreate_project_id event)+        case request of+          Left _ -> return False+          Right Nothing -> return False+          Right (Just prj) ->+            return+              ( project_path prj+                  `elem` projectNames+              )+    )+    ( \event@ProjectCreate {} -> do+        mapM_+          ( \userName -> do+              request <- searchUser userName+              case request of+                Nothing -> return ()+                Just foundUser ->+                  void $+                    addMemberToProject'+                      (projectCreate_project_id event)+                      Reporter+                      (user_id foundUser)+          )+          userNames+    )
src/GitLab/SystemHooks/Types.hs view
@@ -21,6 +21,7 @@     ProjectRename (..),     ProjectTransfer (..),     ProjectUpdate (..),+    ProjectChanges (..),     UserAddToTeam (..),     UserUpdateForTeam (..),     UserRemoveFromTeam (..),@@ -40,9 +41,14 @@     TagPush (..),     ProjectEvent (..),     RepositoryEvent (..),+    RepositoryUpdate (..),     CommitEvent (..),     CommitAuthorEvent (..),     Visibility (..),+    MergeRequestEvent (..),+    ObjectAttributes (..),+    MergeParams (..),+    UserEvent (..),     parseEvent,   ) where@@ -490,6 +496,24 @@   }   deriving (Typeable, Show, Eq) +instance SystemHook RepositoryUpdate where+  match = Match+  matchIf = MatchIf++-- | Tags have been pushed to the server.+data RepositoryUpdate = RepositoryUpdate+  { repositoryUpdate_event_name :: Text,+    repositoryUpdate_user_id :: Int,+    repositoryUpdate_user_name :: Text,+    repositoryUpdate_user_email :: Text,+    repositoryUpdate_user_avatar :: Text,+    repositoryUpdate_project_id :: Int,+    repositoryUpdate_project :: ProjectEvent,+    repositoryUpdate_changes :: [ProjectChanges],+    repositoryUpdate_refs :: [Text]+  }+  deriving (Typeable, Show, Eq)+ -- | A project event. data ProjectEvent = ProjectEvent   { projectEvent_name :: Text,@@ -510,15 +534,26 @@   }   deriving (Typeable, Show, Eq, Generic) +-- | A project event.+data ProjectChanges = ProjectChanges+  { projectChanges_before :: Text,+    projectChanges_after :: Text,+    projectChanges_ref :: Text+  }+  deriving (Typeable, Show, Eq, Generic)+ -- | A repository event. data RepositoryEvent = RepositoryEvent   { repositoryEvent_name :: Text,     repositoryEvent_url :: Text,     repositoryEvent_description :: Text,     repositoryEvent_homepage :: Maybe Text,-    repositoryEvent_git_http_url :: Text,-    repositoryEvent_git_ssh_url :: Text,-    repositoryEvent_visibility_level :: Visibility+    -- these three not in the merge_request event example+    -- in the GitLab documentation. Is the merge_request documentation+    -- out dated?+    repositoryEvent_git_http_url :: Maybe Text,+    repositoryEvent_git_ssh_url :: Maybe Text,+    repositoryEvent_visibility_level :: Maybe Visibility   }   deriving (Typeable, Show, Eq, Generic) @@ -539,6 +574,75 @@   }   deriving (Typeable, Show, Eq, Generic) +instance SystemHook MergeRequestEvent where+  match = Match+  matchIf = MatchIf++-- | Merge request (named so, since 'MergeRequest' type already used+-- in GitLab.Types.+data MergeRequestEvent = MergeRequestEvent+  { mergeRequest_object_kind :: Text,+    mergeRequest_user :: UserEvent,+    mergeRequest_project :: ProjectEvent,+    mergeRequest_object_attributes :: ObjectAttributes,+    mergeRequest_labels :: Maybe Text,+    mergeRequest_repository :: RepositoryEvent+  }+  deriving (Typeable, Show, Eq, Generic)++data ObjectAttributes = ObjectAttributes+  { objectAttributes_id :: Int,+    objectAttributes_target_branch :: Text,+    objectAttributes_source_branch :: Text,+    objectAttributes_source_project_id :: Int,+    objectAttributes_author_id :: Int,+    objectAttributes_assignee_id :: Int,+    objectAttributes_title :: Text,+    objectAttributes_created_at :: Text,+    objectAttributes_updated_at :: Text,+    objectAttributes_milestone_id :: Maybe Int,+    objectAttributes_state :: Text,+    objectAttributes_merge_status :: Text,+    objectAttributes_target_project_id :: Int,+    objectAttributes_iid :: Int,+    objectAttributes_description :: Text,+    objectAttributes_updated_by_id :: Maybe Int,+    objectAttributes_merge_error :: Maybe Text,+    objectAttributes_merge_params :: MergeParams,+    objectAttributes_merge_when_pipeline_succeeds :: Bool,+    objectAttributes_merge_user_id :: Maybe Int,+    objectAttributes_merge_commit_sha :: Maybe Text,+    objectAttributes_deleted_at :: Maybe Text,+    objectAttributes_in_progress_merge_commit_sha :: Maybe Text,+    objectAttributes_lock_version :: Maybe Int,+    objectAttributes_time_estimate :: Int,+    objectAttributes_last_edited_at :: Text,+    objectAttributes_last_edited_by_id :: Int,+    objectAttributes_head_pipeline_id :: Int,+    objectAttributes_ref_fetched :: Bool,+    objectAttributes_merge_jid :: Maybe Int,+    objectAttributes_source :: ProjectEvent,+    objectAttributes_target :: ProjectEvent,+    objectAttributes_last_commit :: CommitEvent,+    objectAttributes_work_in_progress :: Bool,+    objectAttributes_total_time_spent :: Int,+    objectAttributes_human_total_time_spent :: Maybe Int,+    objectAttributes_human_time_estimate :: Maybe Int+  }+  deriving (Typeable, Show, Eq, Generic)++data MergeParams = MergeParams+  { mergeParams_force_remove_source_branch :: Text+  }+  deriving (Typeable, Show, Eq, Generic)++data UserEvent = UserEvent+  { userEvent_name :: Text,+    userEvent_username :: Text,+    userEvent_avatar_url :: Text+  }+  deriving (Typeable, Show, Eq, Generic)+ data ProjectAction   = ProjectCreated   | ProjectDestroyed@@ -562,6 +666,8 @@   | GroupMemberUpdated   | Pushed   | TagPushed+  | RepositoryUpdated+  | MergeRequested   deriving (Show, Eq)  -- |  Project visibility.@@ -1032,7 +1138,7 @@  instance FromJSON TagPush where   parseJSON =-    withObject "Push" $ \v -> do+    withObject "TagPush" $ \v -> do       isProjectEvent <- v .:? "event_name"       case isProjectEvent of         Just theEvent ->@@ -1055,6 +1161,47 @@             _unexpected -> fail "tag_push parsing failed"         _unexpected -> fail "tag_push parsing failed" +instance FromJSON RepositoryUpdate where+  parseJSON =+    withObject "RepositoryUpdate" $ \v -> do+      isProjectEvent <- v .:? "event_name"+      case isProjectEvent of+        Just theEvent ->+          case theEvent of+            RepositoryUpdated ->+              RepositoryUpdate+                <$> v .: "event_name"+                <*> v .: "user_id"+                <*> v .: "user_name"+                <*> v .: "user_email"+                <*> v .: "user_avatar"+                <*> v .: "project_id"+                <*> v .: "project"+                <*> v .: "changes"+                <*> v .: "refs"+            _unexpected -> fail "repository_update parsing failed"+        _unexpected -> fail "repository_update parsing failed"++instance FromJSON MergeRequestEvent where+  parseJSON =+    withObject "MergeRequestEvent" $ \v -> do+      -- Note: it's `event_name` in all other examples.+      -- Bug in GitLab system hooks documentation?+      isProjectEvent <- v .:? "object_kind"+      case isProjectEvent of+        Just theEvent ->+          case theEvent of+            MergeRequested ->+              MergeRequestEvent+                <$> v .: "object_kind"+                <*> v .: "user"+                <*> v .: "project"+                <*> v .: "object_attributes"+                <*> v .: "labels"+                <*> v .: "repository"+            _unexpected -> fail "merge_request parsing failed"+        _unexpected -> fail "merge_request parsing failed"+ bodyNoPrefix :: String -> String bodyNoPrefix "projectEvent_name" = "name" bodyNoPrefix "projectEvent_description" = "description"@@ -1071,6 +1218,9 @@ bodyNoPrefix "projectEvent_url" = "url" bodyNoPrefix "projectEvent_ssh_url" = "ssh_url" bodyNoPrefix "projectEvent_http_url" = "http_url"+bodyNoPrefix "projectChanges_before" = "before"+bodyNoPrefix "projectChanges_after" = "after"+bodyNoPrefix "projectChanges_ref" = "ref" bodyNoPrefix "repositoryEvent_name" = "name" bodyNoPrefix "repositoryEvent_url" = "url" bodyNoPrefix "repositoryEvent_description" = "description"@@ -1085,7 +1235,48 @@ bodyNoPrefix "commitEvent_author" = "author" bodyNoPrefix "commitAuthorEvent_name" = "name" bodyNoPrefix "commitAuthorEvent_email" = "email"-bodyNoPrefix s = error s+bodyNoPrefix "mergeParams_force_remove_source_branch" = "force_remove_source_branch"+bodyNoPrefix "userEvent_name" = "name"+bodyNoPrefix "userEvent_username" = "username"+bodyNoPrefix "userEvent_avatar_url" = "avatar_url"+bodyNoPrefix "objectAttributes_id" = "id"+bodyNoPrefix "objectAttributes_target_branch" = "target_branch"+bodyNoPrefix "objectAttributes_source_branch" = "source_branch"+bodyNoPrefix "objectAttributes_source_project_id" = "source_project_id"+bodyNoPrefix "objectAttributes_author_id" = "author_id"+bodyNoPrefix "objectAttributes_assignee_id" = "assignee_id"+bodyNoPrefix "objectAttributes_title" = "title"+bodyNoPrefix "objectAttributes_created_at" = "created_at"+bodyNoPrefix "objectAttributes_updated_at" = "updated_at"+bodyNoPrefix "objectAttributes_milestone_id" = "milestone_id"+bodyNoPrefix "objectAttributes_state" = "state"+bodyNoPrefix "objectAttributes_merge_status" = "merge_status"+bodyNoPrefix "objectAttributes_target_project_id" = "target_project_id"+bodyNoPrefix "objectAttributes_iid" = "iid"+bodyNoPrefix "objectAttributes_description" = "description"+bodyNoPrefix "objectAttributes_updated_by_id" = "updated_by_id"+bodyNoPrefix "objectAttributes_merge_error" = "merge_error"+bodyNoPrefix "objectAttributes_merge_params" = "merge_params"+bodyNoPrefix "objectAttributes_merge_when_pipeline_succeeds" = "merge_when_pipeline_succeeds"+bodyNoPrefix "objectAttributes_merge_user_id" = "merge_user_id"+bodyNoPrefix "objectAttributes_merge_commit_sha" = "merge_commit_sha"+bodyNoPrefix "objectAttributes_deleted_at" = "deleted_at"+bodyNoPrefix "objectAttributes_in_progress_merge_commit_sha" = "in_progress_merge_commit_sha"+bodyNoPrefix "objectAttributes_lock_version" = "lock_version"+bodyNoPrefix "objectAttributes_time_estimate" = "time_estimate"+bodyNoPrefix "objectAttributes_last_edited_at" = "last_edited_at"+bodyNoPrefix "objectAttributes_last_edited_by_id" = "last_edited_by_id"+bodyNoPrefix "objectAttributes_head_pipeline_id" = "head_pipeline_id"+bodyNoPrefix "objectAttributes_ref_fetched" = "ref_fetched"+bodyNoPrefix "objectAttributes_merge_jid" = "merge_jid"+bodyNoPrefix "objectAttributes_source" = "source"+bodyNoPrefix "objectAttributes_target" = "target"+bodyNoPrefix "objectAttributes_last_commit" = "last_commit"+bodyNoPrefix "objectAttributes_work_in_progress" = "work_in_progress"+bodyNoPrefix "objectAttributes_total_time_spent" = "total_time_spent"+bodyNoPrefix "objectAttributes_human_total_time_spent" = "human_total_time_spent"+bodyNoPrefix "objectAttributes_human_time_estimate" = "human_time_estimate"+bodyNoPrefix s = error ("uexpected JSON field prefix: " <> s)  instance FromJSON ProjectEvent where   parseJSON =@@ -1095,6 +1286,14 @@           }       ) +instance FromJSON ProjectChanges where+  parseJSON =+    genericParseJSON+      ( defaultOptions+          { fieldLabelModifier = bodyNoPrefix+          }+      )+ instance FromJSON CommitEvent where   parseJSON =     genericParseJSON@@ -1119,6 +1318,30 @@           }       ) +instance FromJSON ObjectAttributes where+  parseJSON =+    genericParseJSON+      ( defaultOptions+          { fieldLabelModifier = bodyNoPrefix+          }+      )++instance FromJSON MergeParams where+  parseJSON =+    genericParseJSON+      ( defaultOptions+          { fieldLabelModifier = bodyNoPrefix+          }+      )++instance FromJSON UserEvent where+  parseJSON =+    genericParseJSON+      ( defaultOptions+          { fieldLabelModifier = bodyNoPrefix+          }+      )+ instance FromJSON ProjectAction where   parseJSON (String "project_create") = return ProjectCreated   parseJSON (String "project_destroy") = return ProjectDestroyed@@ -1142,7 +1365,9 @@   parseJSON (String "user_update_for_group") = return GroupMemberUpdated   parseJSON (String "push") = return Pushed   parseJSON (String "tag_push") = return TagPushed-  parseJSON s = error (show s)+  parseJSON (String "repository_update") = return RepositoryUpdated+  parseJSON (String "merge_request") = return MergeRequested+  parseJSON s = error ("unexpected system hook event: " <> show s)  instance FromJSON Visibility where   parseJSON (String "public") = return Public
tests/SystemHookTests.hs view
@@ -129,17 +129,17 @@         "tag-push-event"         ( readFile "data/system-hooks/tag-push.json"             >>= \eventJson -> parseEvent eventJson @?= Just tagPushHaskell+        ),+      testCase+        "merge-request-event"+        ( readFile "data/system-hooks/merge-request.json"+            >>= \eventJson -> parseEvent eventJson @?= Just mergeRequestHaskell+        ),+      testCase+        "repository-update-event"+        ( readFile "data/system-hooks/repository-update.json"+            >>= \eventJson -> parseEvent eventJson @?= Just repositoryUpdateHaskell         )-      -- testCase-      --   "merge-request-event"-      --   ( readFile "data/system-hooks/merge-request.json"-      --       >>= \eventJson -> parseEvent eventJson @?= Just mergeRequestHaskell-      --   ),-      -- testCase-      --   "repository-update-event"-      --   ( readFile "data/system-hooks/repository-update.json"-      --       >>= \eventJson -> parseEvent eventJson @?= Just repositoryUpdateHaskell-      -- )     ]  matchTest :: String -> String -> Rule -> String -> Rule -> [TestTree]@@ -173,14 +173,14 @@         ( liftIO (readFile ("data/system-hooks/" <> jsonFilename))             >>= \eventJson -> tryFire eventJson yesFire         )-        @? "project-create-fireIf-yes failed",+        @? (lbl <> "-fireIf-yes failed"),     testCase (lbl <> "-no") $       not         <$> runGitLabDbg           ( liftIO (readFile ("data/system-hooks/" <> jsonFilename))               >>= \eventJson -> tryFire eventJson noFire           )-        @? "project-create-fireIf-no failed"+        @? (lbl <> "-fireIf-no failed")   ]  -- [ testCase lbl $@@ -230,6 +230,8 @@       <> matchTest "group-member-update" "group-member-updated.json" groupMemberUpdateRule "project-created.json" projectCreateRule       <> matchTest "push" "push.json" pushRule "project-created.json" projectCreateRule       <> matchTest "tag-push" "tag-push.json" tagPushRule "project-created.json" projectCreateRule+      <> matchTest "repository-update" "repository-update.json" repositoryUpdateRule "project-created.json" projectCreateRule+      <> matchTest "merge-request" "merge-request.json" mergeRequestRule "project-created.json" projectCreateRule  matchIfTests :: TestTree matchIfTests =@@ -256,35 +258,37 @@       <> matchIfTest "group-member-update" "group-member-updated.json" groupMemberUpdateIfRuleYes groupMemberUpdateIfRuleNo       <> matchIfTest "push" "push.json" pushIfRuleYes pushIfRuleNo       <> matchIfTest "tag-push" "tag-push.json" tagPushIfRuleYes tagPushIfRuleNo+      <> matchIfTest "repository-update" "repository-update.json" repositoryUpdateIfRuleYes repositoryUpdateIfRuleNo+      <> matchIfTest "merge-request" "merge-request.json" mergeRequestIfRuleYes mergeRequestIfRuleNo  receiveTests :: TestTree receiveTests =   testGroup     "GitLab system hooks receive"-    [ testCase "1-rule-match"-        $ runGitLabDbg-        $ liftIO (readFile "data/system-hooks/project-created.json")-          >>= \eventJson ->-            receiveString-              eventJson-              [projectCreateRule],-      testCase "1-rule-no-match"-        $ runGitLabDbg-        $ liftIO (readFile "data/system-hooks/project-created.json")-          >>= \eventJson ->-            receiveString-              eventJson-              [projectRenameRule],+    [ testCase "1-rule-match" $+        runGitLabDbg $+          liftIO (readFile "data/system-hooks/project-created.json")+            >>= \eventJson ->+              receiveString+                eventJson+                [projectCreateRule],+      testCase "1-rule-no-match" $+        runGitLabDbg $+          liftIO (readFile "data/system-hooks/project-created.json")+            >>= \eventJson ->+              receiveString+                eventJson+                [projectRenameRule],       testCase         "2-rules"-        $ runGitLabDbg-        $ liftIO (readFile "data/system-hooks/project-created.json")-          >>= \eventJson ->-            receiveString-              eventJson-              [ projectCreateRule,-                projectDestroyRule-              ]+        $ runGitLabDbg $+          liftIO (readFile "data/system-hooks/project-created.json")+            >>= \eventJson ->+              receiveString+                eventJson+                [ projectCreateRule,+                  projectDestroyRule+                ]     ]  projectCreateRule :: Rule@@ -1061,6 +1065,66 @@         return ()     ) +repositoryUpdateRule :: Rule+repositoryUpdateRule =+  match+    "repositoryUpdate rule"+    ( \RepositoryUpdate {} -> do+        return ()+    )++repositoryUpdateIfRuleYes :: Rule+repositoryUpdateIfRuleYes =+  matchIf+    "repositoryUpdate rule-if yes"+    ( \event@RepositoryUpdate {} -> do+        return (repositoryUpdate_refs event == ["refs/heads/master"])+    )+    ( \RepositoryUpdate {} -> do+        return ()+    )++repositoryUpdateIfRuleNo :: Rule+repositoryUpdateIfRuleNo =+  matchIf+    "repositoryUpdate rule-if no"+    ( \event@RepositoryUpdate {} -> do+        return (repositoryUpdate_refs event == ["refs/heads/branch-1"])+    )+    ( \RepositoryUpdate {} -> do+        return ()+    )++mergeRequestRule :: Rule+mergeRequestRule =+  match+    "mergeRequest rule"+    ( \MergeRequestEvent {} -> do+        return ()+    )++mergeRequestIfRuleYes :: Rule+mergeRequestIfRuleYes =+  matchIf+    "mergeRequest rule-if yes"+    ( \event@MergeRequestEvent {} -> do+        return (userEvent_name (mergeRequest_user event) == "Administrator")+    )+    ( \MergeRequestEvent {} -> do+        return ()+    )++mergeRequestIfRuleNo :: Rule+mergeRequestIfRuleNo =+  matchIf+    "mergeRequest rule-if no"+    ( \event@MergeRequestEvent {} -> do+        return (userEvent_name (mergeRequest_user event) == "joe")+    )+    ( \MergeRequestEvent {} -> do+        return ()+    )+ projectCreatedHaskell :: ProjectCreate projectCreatedHaskell =   ProjectCreate@@ -1368,7 +1432,7 @@       push_user_avatar = "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80",       push_project_id = 15,       push_project = ProjectEvent {projectEvent_name = "Diaspora", projectEvent_description = "", projectEvent_web_url = "http://example.com/mike/diaspora", projectEvent_avatar_url = Nothing, projectEvent_git_ssh_url = "git@example.com:mike/diaspora.git", projectEvent_git_http_url = "http://example.com/mike/diaspora.git", projectEvent_namespace = "Mike", projectEvent_visibility_level = Private, projectEvent_path_with_namespace = "mike/diaspora", projectEvent_default_branch = "master", projectEvent_homepage = Just "http://example.com/mike/diaspora", projectEvent_url = "git@example.com:mike/diaspora.git", projectEvent_ssh_url = "git@example.com:mike/diaspora.git", projectEvent_http_url = "http://example.com/mike/diaspora.git"},-      push_repository = RepositoryEvent {repositoryEvent_name = "Diaspora", repositoryEvent_url = "git@example.com:mike/diaspora.git", repositoryEvent_description = "", repositoryEvent_homepage = Just "http://example.com/mike/diaspora", repositoryEvent_git_http_url = "http://example.com/mike/diaspora.git", repositoryEvent_git_ssh_url = "git@example.com:mike/diaspora.git", repositoryEvent_visibility_level = Private},+      push_repository = RepositoryEvent {repositoryEvent_name = "Diaspora", repositoryEvent_url = "git@example.com:mike/diaspora.git", repositoryEvent_description = "", repositoryEvent_homepage = Just "http://example.com/mike/diaspora", repositoryEvent_git_http_url = Just "http://example.com/mike/diaspora.git", repositoryEvent_git_ssh_url = Just "git@example.com:mike/diaspora.git", repositoryEvent_visibility_level = Just Private},       push_commits = [CommitEvent {commitEvent_id = "c5feabde2d8cd023215af4d2ceeb7a64839fc428", commitEvent_message = "Add simple search to projects in public area", commitEvent_timestamp = "2013-05-13T18:18:08+00:00", commitEvent_url = "https://dev.gitlab.org/gitlab/gitlabhq/commit/c5feabde2d8cd023215af4d2ceeb7a64839fc428", commitEvent_author = CommitAuthorEvent {commitAuthorEvent_name = "Example User", commitAuthorEvent_email = "user@example.com"}}],       push_total_commits_count = 1     }@@ -1386,7 +1450,32 @@       tagPush_user_avatar = "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80",       tagPush_project_id = 1,       tagPush_project = ProjectEvent {projectEvent_name = "Example", projectEvent_description = "", projectEvent_web_url = "http://example.com/jsmith/example", projectEvent_avatar_url = Nothing, projectEvent_git_ssh_url = "git@example.com:jsmith/example.git", projectEvent_git_http_url = "http://example.com/jsmith/example.git", projectEvent_namespace = "Jsmith", projectEvent_visibility_level = Private, projectEvent_path_with_namespace = "jsmith/example", projectEvent_default_branch = "master", projectEvent_homepage = Just "http://example.com/jsmith/example", projectEvent_url = "git@example.com:jsmith/example.git", projectEvent_ssh_url = "git@example.com:jsmith/example.git", projectEvent_http_url = "http://example.com/jsmith/example.git"},-      tagPush_repository = RepositoryEvent {repositoryEvent_name = "Example", repositoryEvent_url = "ssh://git@example.com/jsmith/example.git", repositoryEvent_description = "", repositoryEvent_homepage = Just "http://example.com/jsmith/example", repositoryEvent_git_http_url = "http://example.com/jsmith/example.git", repositoryEvent_git_ssh_url = "git@example.com:jsmith/example.git", repositoryEvent_visibility_level = Private},+      tagPush_repository = RepositoryEvent {repositoryEvent_name = "Example", repositoryEvent_url = "ssh://git@example.com/jsmith/example.git", repositoryEvent_description = "", repositoryEvent_homepage = Just "http://example.com/jsmith/example", repositoryEvent_git_http_url = Just "http://example.com/jsmith/example.git", repositoryEvent_git_ssh_url = Just "git@example.com:jsmith/example.git", repositoryEvent_visibility_level = Just Private},       tagPush_commits = [],       tagPush_total_commits_count = 0+    }++repositoryUpdateHaskell :: RepositoryUpdate+repositoryUpdateHaskell =+  RepositoryUpdate+    { repositoryUpdate_event_name = "repository_update",+      repositoryUpdate_user_id = 1,+      repositoryUpdate_user_name = "John Smith",+      repositoryUpdate_user_email = "admin@example.com",+      repositoryUpdate_user_avatar = "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80",+      repositoryUpdate_project_id = 1,+      repositoryUpdate_project = ProjectEvent {projectEvent_name = "Example", projectEvent_description = "", projectEvent_web_url = "http://example.com/jsmith/example", projectEvent_avatar_url = Nothing, projectEvent_git_ssh_url = "git@example.com:jsmith/example.git", projectEvent_git_http_url = "http://example.com/jsmith/example.git", projectEvent_namespace = "Jsmith", projectEvent_visibility_level = Private, projectEvent_path_with_namespace = "jsmith/example", projectEvent_default_branch = "master", projectEvent_homepage = Just "http://example.com/jsmith/example", projectEvent_url = "git@example.com:jsmith/example.git", projectEvent_ssh_url = "git@example.com:jsmith/example.git", projectEvent_http_url = "http://example.com/jsmith/example.git"},+      repositoryUpdate_changes = [ProjectChanges {projectChanges_before = "8205ea8d81ce0c6b90fbe8280d118cc9fdad6130", projectChanges_after = "4045ea7a3df38697b3730a20fb73c8bed8a3e69e", projectChanges_ref = "refs/heads/master"}],+      repositoryUpdate_refs = ["refs/heads/master"]+    }++mergeRequestHaskell :: MergeRequestEvent+mergeRequestHaskell =+  MergeRequestEvent+    { mergeRequest_object_kind = "merge_request",+      mergeRequest_user = UserEvent {userEvent_name = "Administrator", userEvent_username = "root", userEvent_avatar_url = "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"},+      mergeRequest_project = ProjectEvent {projectEvent_name = "Example", projectEvent_description = "", projectEvent_web_url = "http://example.com/jsmith/example", projectEvent_avatar_url = Nothing, projectEvent_git_ssh_url = "git@example.com:jsmith/example.git", projectEvent_git_http_url = "http://example.com/jsmith/example.git", projectEvent_namespace = "Jsmith", projectEvent_visibility_level = Private, projectEvent_path_with_namespace = "jsmith/example", projectEvent_default_branch = "master", projectEvent_homepage = Just "http://example.com/jsmith/example", projectEvent_url = "git@example.com:jsmith/example.git", projectEvent_ssh_url = "git@example.com:jsmith/example.git", projectEvent_http_url = "http://example.com/jsmith/example.git"},+      mergeRequest_object_attributes = ObjectAttributes {objectAttributes_id = 90, objectAttributes_target_branch = "master", objectAttributes_source_branch = "ms-viewport", objectAttributes_source_project_id = 14, objectAttributes_author_id = 51, objectAttributes_assignee_id = 6, objectAttributes_title = "MS-Viewport", objectAttributes_created_at = "2017-09-20T08:31:45.944Z", objectAttributes_updated_at = "2017-09-28T12:23:42.365Z", objectAttributes_milestone_id = Nothing, objectAttributes_state = "opened", objectAttributes_merge_status = "unchecked", objectAttributes_target_project_id = 14, objectAttributes_iid = 1, objectAttributes_description = "", objectAttributes_updated_by_id = Just 1, objectAttributes_merge_error = Nothing, objectAttributes_merge_params = MergeParams {mergeParams_force_remove_source_branch = "0"}, objectAttributes_merge_when_pipeline_succeeds = False, objectAttributes_merge_user_id = Nothing, objectAttributes_merge_commit_sha = Nothing, objectAttributes_deleted_at = Nothing, objectAttributes_in_progress_merge_commit_sha = Nothing, objectAttributes_lock_version = Just 5, objectAttributes_time_estimate = 0, objectAttributes_last_edited_at = "2017-09-27T12:43:37.558Z", objectAttributes_last_edited_by_id = 1, objectAttributes_head_pipeline_id = 61, objectAttributes_ref_fetched = True, objectAttributes_merge_jid = Nothing, objectAttributes_source = ProjectEvent {projectEvent_name = "Awesome Project", projectEvent_description = "", projectEvent_web_url = "http://example.com/awesome_space/awesome_project", projectEvent_avatar_url = Nothing, projectEvent_git_ssh_url = "git@example.com:awesome_space/awesome_project.git", projectEvent_git_http_url = "http://example.com/awesome_space/awesome_project.git", projectEvent_namespace = "root", projectEvent_visibility_level = Private, projectEvent_path_with_namespace = "awesome_space/awesome_project", projectEvent_default_branch = "master", projectEvent_homepage = Just "http://example.com/awesome_space/awesome_project", projectEvent_url = "http://example.com/awesome_space/awesome_project.git", projectEvent_ssh_url = "git@example.com:awesome_space/awesome_project.git", projectEvent_http_url = "http://example.com/awesome_space/awesome_project.git"}, objectAttributes_target = ProjectEvent {projectEvent_name = "Awesome Project", projectEvent_description = "Aut reprehenderit ut est.", projectEvent_web_url = "http://example.com/awesome_space/awesome_project", projectEvent_avatar_url = Nothing, projectEvent_git_ssh_url = "git@example.com:awesome_space/awesome_project.git", projectEvent_git_http_url = "http://example.com/awesome_space/awesome_project.git", projectEvent_namespace = "Awesome Space", projectEvent_visibility_level = Private, projectEvent_path_with_namespace = "awesome_space/awesome_project", projectEvent_default_branch = "master", projectEvent_homepage = Just "http://example.com/awesome_space/awesome_project", projectEvent_url = "http://example.com/awesome_space/awesome_project.git", projectEvent_ssh_url = "git@example.com:awesome_space/awesome_project.git", projectEvent_http_url = "http://example.com/awesome_space/awesome_project.git"}, objectAttributes_last_commit = CommitEvent {commitEvent_id = "ba3e0d8ff79c80d5b0bbb4f3e2e343e0aaa662b7", commitEvent_message = "fixed readme", commitEvent_timestamp = "2017-09-26T16:12:57Z", commitEvent_url = "http://example.com/awesome_space/awesome_project/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7", commitEvent_author = CommitAuthorEvent {commitAuthorEvent_name = "GitLab dev user", commitAuthorEvent_email = "gitlabdev@dv6700.(none)"}}, objectAttributes_work_in_progress = False, objectAttributes_total_time_spent = 0, objectAttributes_human_total_time_spent = Nothing, objectAttributes_human_time_estimate = Nothing},+      mergeRequest_labels = Nothing,+      mergeRequest_repository = RepositoryEvent {repositoryEvent_name = "git-gpg-test", repositoryEvent_url = "git@example.com:awesome_space/awesome_project.git", repositoryEvent_description = "", repositoryEvent_homepage = Just "http://example.com/awesome_space/awesome_project", repositoryEvent_git_http_url = Nothing, repositoryEvent_git_ssh_url = Nothing, repositoryEvent_visibility_level = Nothing}     }