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 +30/−30
- gitlab-haskell.cabal +2/−1
- src/GitLab.hs +2/−0
- src/GitLab/SystemHooks/GitLabSystemHooks.hs +16/−0
- src/GitLab/SystemHooks/Rules.hs +81/−0
- src/GitLab/SystemHooks/Types.hs +231/−6
- tests/SystemHookTests.hs +125/−36
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} }