diff --git a/src/event.rs b/src/event.rs index 058aaf1..5917b28 100644 --- a/src/event.rs +++ b/src/event.rs @@ -6,17 +6,18 @@ pub trait GitlabEventExt { fn title(&self) -> String; } +#[derive(Debug, Deserialize)] +pub struct User { + name: String, +} + #[derive(Debug, Deserialize)] pub struct Project { - pub id: u64, pub name: String, pub description: String, pub web_url: String, pub avatar_url: Option, - pub git_ssh_url: String, - pub git_http_url: String, pub namespace: String, - pub visibility_level: u32, pub path_with_namespace: String, pub default_branch: String, pub homepage: String, @@ -31,9 +32,6 @@ pub struct Repository { pub url: String, pub description: String, pub homepage: String, - pub git_http_url: String, - pub git_ssh_url: String, - pub visibility_level: u32, } #[derive(Debug, Deserialize)] @@ -43,6 +41,40 @@ pub struct Commit { pub url: String, } +#[derive(PartialEq, Debug, Deserialize)] +pub enum MergeRequestAction { + #[serde(rename = "open")] + Opened, + #[serde(rename = "close")] + Closed, + #[serde(rename = "merge")] + Merged, + #[serde(other)] + Other, +} + +impl MergeRequestAction { + pub fn as_str(&self) -> &str { + match self { + MergeRequestAction::Opened => "opened", + MergeRequestAction::Closed => "closed", + MergeRequestAction::Merged => "merged", + MergeRequestAction::Other => "other", + } + } +} + +#[derive(Debug, Deserialize)] +pub struct ObjectAttributes { + pub target_branch: String, + pub source_branch: String, + pub title: String, + pub url: String, + pub source: Project, + pub target: Project, + pub action: MergeRequestAction, +} + #[derive(Debug, Deserialize)] #[serde(tag = "object_kind")] pub enum GitlabEvent { @@ -82,6 +114,13 @@ pub enum GitlabEvent { commits: Vec, total_commits_count: u64, }, + #[serde(rename = "merge_request")] + MergeRequest { + user: User, + project: Project, + repository: Repository, + object_attributes: ObjectAttributes, + }, } impl GitlabEventExt for GitlabEvent { @@ -89,6 +128,7 @@ impl GitlabEventExt for GitlabEvent { match self { GitlabEvent::Push { project, .. } => &project, GitlabEvent::TagPush { project, .. } => &project, + GitlabEvent::MergeRequest { project, .. } => &project, } } @@ -96,6 +136,7 @@ impl GitlabEventExt for GitlabEvent { match self { GitlabEvent::Push { r#ref, .. } => &r#ref, GitlabEvent::TagPush { r#ref, .. } => &r#ref, + GitlabEvent::MergeRequest { object_attributes, .. } => &object_attributes.target_branch, } } @@ -103,6 +144,7 @@ impl GitlabEventExt for GitlabEvent { match self { GitlabEvent::Push { user_name, .. } => &user_name, GitlabEvent::TagPush { user_name, .. } => &user_name, + GitlabEvent::MergeRequest { user, .. } => &user.name, } } @@ -118,6 +160,7 @@ impl GitlabEventExt for GitlabEvent { let refname = r#ref.split('/').into_iter().last().unwrap_or(checkout_sha); format!("{}/-/tags/{}", project.web_url, refname) } + GitlabEvent::MergeRequest { object_attributes, .. } => object_attributes.url.clone(), }; url.replace("http://", "https://").to_string() @@ -137,6 +180,9 @@ impl GitlabEventExt for GitlabEvent { } => find_commit(commits, &checkout_sha) .map(|commit| commit.title.clone()) .unwrap_or_else(|| "New tag pushed".to_string()), + GitlabEvent::MergeRequest { object_attributes, .. } => { + format!("MR {}: {}", object_attributes.action.as_str(), object_attributes.title) + } } } } @@ -221,4 +267,24 @@ mod test { Ok(()) } + + #[test] + pub fn parse_merge_request_event() -> anyhow::Result<()> { + let event = load_test_data("merge-request-event")?; + + match event { + GitlabEvent::MergeRequest { + user, + object_attributes, + .. + } => { + assert_eq!(user.name, "Administrator"); + assert_eq!(object_attributes.action, MergeRequestAction::Opened); + assert_eq!(object_attributes.title, "MS-Viewport"); + } + _ => panic!("not a merge request event"), + }; + + Ok(()) + } } diff --git a/test-data/merge-request-event.json b/test-data/merge-request-event.json new file mode 100644 index 0000000..68f6ad4 --- /dev/null +++ b/test-data/merge-request-event.json @@ -0,0 +1,200 @@ +{ + "object_kind": "merge_request", + "event_type": "merge_request", + "user": { + "id": 1, + "name": "Administrator", + "username": "root", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon", + "email": "admin@example.com" + }, + "project": { + "id": 1, + "name":"Gitlab Test", + "description":"Aut reprehenderit ut est.", + "web_url":"http://example.com/gitlabhq/gitlab-test", + "avatar_url":null, + "git_ssh_url":"git@example.com:gitlabhq/gitlab-test.git", + "git_http_url":"http://example.com/gitlabhq/gitlab-test.git", + "namespace":"GitlabHQ", + "visibility_level":20, + "path_with_namespace":"gitlabhq/gitlab-test", + "default_branch":"master", + "ci_config_path":"", + "homepage":"http://example.com/gitlabhq/gitlab-test", + "url":"http://example.com/gitlabhq/gitlab-test.git", + "ssh_url":"git@example.com:gitlabhq/gitlab-test.git", + "http_url":"http://example.com/gitlabhq/gitlab-test.git" + }, + "repository": { + "name": "Gitlab Test", + "url": "http://example.com/gitlabhq/gitlab-test.git", + "description": "Aut reprehenderit ut est.", + "homepage": "http://example.com/gitlabhq/gitlab-test" + }, + "object_attributes": { + "id": 99, + "iid": 1, + "target_branch": "master", + "source_branch": "ms-viewport", + "source_project_id": 14, + "author_id": 51, + "assignee_ids": [6], + "assignee_id": 6, + "reviewer_ids": [6], + "title": "MS-Viewport", + "created_at": "2013-12-03T17:23:34Z", + "updated_at": "2013-12-03T17:23:34Z", + "last_edited_at": "2013-12-03T17:23:34Z", + "last_edited_by_id": 1, + "milestone_id": null, + "state_id": 1, + "state": "opened", + "blocking_discussions_resolved": true, + "work_in_progress": false, + "draft": false, + "first_contribution": true, + "merge_status": "unchecked", + "target_project_id": 14, + "description": "", + "total_time_spent": 1800, + "time_change": 30, + "human_total_time_spent": "30m", + "human_time_change": "30s", + "human_time_estimate": "30m", + "url": "http://example.com/diaspora/merge_requests/1", + "source": { + "name":"Awesome Project", + "description":"Aut reprehenderit ut est.", + "web_url":"http://example.com/awesome_space/awesome_project", + "avatar_url":null, + "git_ssh_url":"git@example.com:awesome_space/awesome_project.git", + "git_http_url":"http://example.com/awesome_space/awesome_project.git", + "namespace":"Awesome Space", + "visibility_level":20, + "path_with_namespace":"awesome_space/awesome_project", + "default_branch":"master", + "homepage":"http://example.com/awesome_space/awesome_project", + "url":"http://example.com/awesome_space/awesome_project.git", + "ssh_url":"git@example.com:awesome_space/awesome_project.git", + "http_url":"http://example.com/awesome_space/awesome_project.git" + }, + "target": { + "name":"Awesome Project", + "description":"Aut reprehenderit ut est.", + "web_url":"http://example.com/awesome_space/awesome_project", + "avatar_url":null, + "git_ssh_url":"git@example.com:awesome_space/awesome_project.git", + "git_http_url":"http://example.com/awesome_space/awesome_project.git", + "namespace":"Awesome Space", + "visibility_level":20, + "path_with_namespace":"awesome_space/awesome_project", + "default_branch":"master", + "homepage":"http://example.com/awesome_space/awesome_project", + "url":"http://example.com/awesome_space/awesome_project.git", + "ssh_url":"git@example.com:awesome_space/awesome_project.git", + "http_url":"http://example.com/awesome_space/awesome_project.git" + }, + "last_commit": { + "id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7", + "message": "fixed readme", + "title": "Update file README.md", + "timestamp": "2012-01-03T23:36:29+02:00", + "url": "http://example.com/awesome_space/awesome_project/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7", + "author": { + "name": "GitLab dev user", + "email": "gitlabdev@dv6700.(none)" + } + }, + "labels": [{ + "id": 206, + "title": "API", + "color": "#ffffff", + "project_id": 14, + "created_at": "2013-12-03T17:15:43Z", + "updated_at": "2013-12-03T17:15:43Z", + "template": false, + "description": "API related issues", + "type": "ProjectLabel", + "group_id": 41 + }], + "action": "open", + "detailed_merge_status": "mergeable" + }, + "labels": [{ + "id": 206, + "title": "API", + "color": "#ffffff", + "project_id": 14, + "created_at": "2013-12-03T17:15:43Z", + "updated_at": "2013-12-03T17:15:43Z", + "template": false, + "description": "API related issues", + "type": "ProjectLabel", + "group_id": 41 + }], + "changes": { + "updated_by_id": { + "previous": null, + "current": 1 + }, + "draft": { + "previous": true, + "current": false + }, + "updated_at": { + "previous": "2017-09-15 16:50:55 UTC", + "current":"2017-09-15 16:52:00 UTC" + }, + "labels": { + "previous": [{ + "id": 206, + "title": "API", + "color": "#ffffff", + "project_id": 14, + "created_at": "2013-12-03T17:15:43Z", + "updated_at": "2013-12-03T17:15:43Z", + "template": false, + "description": "API related issues", + "type": "ProjectLabel", + "group_id": 41 + }], + "current": [{ + "id": 205, + "title": "Platform", + "color": "#123123", + "project_id": 14, + "created_at": "2013-12-03T17:15:43Z", + "updated_at": "2013-12-03T17:15:43Z", + "template": false, + "description": "Platform related issues", + "type": "ProjectLabel", + "group_id": 41 + }] + }, + "last_edited_at": { + "previous": null, + "current": "2023-03-15 00:00:10 UTC" + }, + "last_edited_by_id": { + "previous": null, + "current": 3278533 + } + }, + "assignees": [ + { + "id": 6, + "name": "User1", + "username": "user1", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" + } + ], + "reviewers": [ + { + "id": 6, + "name": "User1", + "username": "user1", + "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon" + } + ] +}