Compare commits
	
		
			3 Commits
		
	
	
		
			19ff99e46f
			...
			3a2da3fba8
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 3a2da3fba8 | |||
| 8edb8a6a4a | |||
| b1337d3599 | 
							
								
								
									
										1
									
								
								.dockerignore
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								.dockerignore
									
									
									
									
									
										Symbolic link
									
								
							| @@ -0,0 +1 @@ | ||||
| .gitignore | ||||
							
								
								
									
										14
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| FROM rust:1.72-slim-bullseye AS builder | ||||
|  | ||||
| WORKDIR /bebot-build | ||||
|  | ||||
| COPY . ./ | ||||
| RUN cargo build --release | ||||
|  | ||||
| FROM debian:bookworm-slim | ||||
|  | ||||
| WORKDIR /bebot | ||||
|  | ||||
| COPY --from=builder /bebot-build/target/release/bebot ./ | ||||
|  | ||||
| ENTRYPOINT [ "/bebot/bebot", "/bebot/config/bebot.yaml" ] | ||||
							
								
								
									
										169
									
								
								src/event.rs
									
									
									
									
									
								
							
							
						
						
									
										169
									
								
								src/event.rs
									
									
									
									
									
								
							| @@ -6,23 +6,20 @@ 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<String>, | ||||
|     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, | ||||
|     pub url: String, | ||||
|     pub ssh_url: String, | ||||
|     pub http_url: String, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Deserialize)] | ||||
| @@ -30,10 +27,6 @@ pub struct Repository { | ||||
|     pub name: String, | ||||
|     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 +36,82 @@ pub struct Commit { | ||||
|     pub url: String, | ||||
| } | ||||
|  | ||||
| #[derive(PartialEq, Debug, Deserialize)] | ||||
| pub enum MergeRequestAction { | ||||
|     #[serde(rename = "open")] | ||||
|     Opened, | ||||
|     #[serde(rename = "close")] | ||||
|     Closed, | ||||
|     #[serde(rename = "reopen")] | ||||
|     Reopened, | ||||
|     #[serde(rename = "update")] | ||||
|     Updated, | ||||
|     #[serde(rename = "approved")] | ||||
|     Approved, | ||||
|     #[serde(rename = "unapproved")] | ||||
|     Unapproved, | ||||
|     #[serde(rename = "merge")] | ||||
|     Merged, | ||||
|     #[serde(other)] | ||||
|     Other, | ||||
| } | ||||
|  | ||||
| impl MergeRequestAction { | ||||
|     pub fn as_str(&self) -> &str { | ||||
|         match self { | ||||
|             MergeRequestAction::Opened => "opened", | ||||
|             MergeRequestAction::Closed => "closed", | ||||
|             MergeRequestAction::Reopened => "reopened", | ||||
|             MergeRequestAction::Updated => "updated", | ||||
|             MergeRequestAction::Approved => "approved", | ||||
|             MergeRequestAction::Unapproved => "unapproved", | ||||
|             MergeRequestAction::Merged => "merged", | ||||
|             MergeRequestAction::Other => "other", | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Deserialize)] | ||||
| pub struct MergeRequestObjectAttributes { | ||||
|     pub target_branch: String, | ||||
|     pub source_branch: String, | ||||
|     pub title: String, | ||||
|     pub url: String, | ||||
|     pub source: Project, | ||||
|     pub target: Project, | ||||
|     pub action: MergeRequestAction, | ||||
| } | ||||
|  | ||||
| #[derive(PartialEq, Debug, Deserialize)] | ||||
| pub enum PipelineStatus { | ||||
|     #[serde(rename = "failed")] | ||||
|     Failed, | ||||
|     #[serde(other)] | ||||
|     Other, | ||||
| } | ||||
|  | ||||
| impl PipelineStatus { | ||||
|     pub fn as_str(&self) -> &str { | ||||
|         match self { | ||||
|             PipelineStatus::Failed => "failed", | ||||
|             PipelineStatus::Other => "other", | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Deserialize)] | ||||
| pub struct PipelineObjectAttributes { | ||||
|     pub name: Option<String>, | ||||
|     pub r#ref: String, | ||||
|     pub status: PipelineStatus, | ||||
|     pub url: String, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Deserialize)] | ||||
| pub struct PipelineMergeRequest { | ||||
|     pub title: String, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Deserialize)] | ||||
| #[serde(tag = "object_kind")] | ||||
| pub enum GitlabEvent { | ||||
| @@ -82,6 +151,20 @@ pub enum GitlabEvent { | ||||
|         commits: Vec<Commit>, | ||||
|         total_commits_count: u64, | ||||
|     }, | ||||
|     #[serde(rename = "merge_request")] | ||||
|     MergeRequest { | ||||
|         user: User, | ||||
|         project: Project, | ||||
|         repository: Repository, | ||||
|         object_attributes: MergeRequestObjectAttributes, | ||||
|     }, | ||||
|     #[serde(rename = "pipeline")] | ||||
|     Pipeline { | ||||
|         object_attributes: PipelineObjectAttributes, | ||||
|         merge_request: PipelineMergeRequest, | ||||
|         user: User, | ||||
|         project: Project, | ||||
|     }, | ||||
| } | ||||
|  | ||||
| impl GitlabEventExt for GitlabEvent { | ||||
| @@ -89,6 +172,8 @@ impl GitlabEventExt for GitlabEvent { | ||||
|         match self { | ||||
|             GitlabEvent::Push { project, .. } => &project, | ||||
|             GitlabEvent::TagPush { project, .. } => &project, | ||||
|             GitlabEvent::MergeRequest { project, .. } => &project, | ||||
|             GitlabEvent::Pipeline { project, .. } => &project, | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -96,6 +181,8 @@ 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, | ||||
|             GitlabEvent::Pipeline { object_attributes, .. } => &object_attributes.r#ref, | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -103,6 +190,8 @@ impl GitlabEventExt for GitlabEvent { | ||||
|         match self { | ||||
|             GitlabEvent::Push { user_name, .. } => &user_name, | ||||
|             GitlabEvent::TagPush { user_name, .. } => &user_name, | ||||
|             GitlabEvent::MergeRequest { user, .. } => &user.name, | ||||
|             GitlabEvent::Pipeline { user, .. } => &user.name, | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -118,6 +207,8 @@ 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(), | ||||
|             GitlabEvent::Pipeline { object_attributes, .. } => object_attributes.url.clone(), | ||||
|         }; | ||||
|  | ||||
|         url.replace("http://", "https://").to_string() | ||||
| @@ -137,6 +228,17 @@ 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) | ||||
|             } | ||||
|             GitlabEvent::Pipeline { | ||||
|                 object_attributes, | ||||
|                 merge_request, | ||||
|                 .. | ||||
|             } => { | ||||
|                 let title = object_attributes.name.as_ref().unwrap_or(&merge_request.title); | ||||
|                 format!("Pipeline {}: {}", object_attributes.status.as_str(), title) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -221,4 +323,47 @@ 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(()) | ||||
|     } | ||||
|  | ||||
|     #[test] | ||||
|     pub fn parse_pipeline_event() -> anyhow::Result<()> { | ||||
|         let event = load_test_data("pipeline-event")?; | ||||
|  | ||||
|         match event { | ||||
|             GitlabEvent::Pipeline { | ||||
|                 object_attributes, | ||||
|                 merge_request, | ||||
|                 user, | ||||
|                 .. | ||||
|             } => { | ||||
|                 assert_eq!(object_attributes.name, Some("Pipeline for branch: master".to_string())); | ||||
|                 assert_eq!(object_attributes.r#ref, "master"); | ||||
|                 assert_eq!(object_attributes.status, PipelineStatus::Failed); | ||||
|                 assert_eq!(merge_request.title, "Test"); | ||||
|                 assert_eq!(user.name, "Administrator"); | ||||
|             } | ||||
|             _ => panic!("not a pipeline event"), | ||||
|         }; | ||||
|  | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										14
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/main.rs
									
									
									
									
									
								
							| @@ -22,6 +22,8 @@ use matrix_sdk::{ | ||||
| }; | ||||
| use warp::Filter; | ||||
|  | ||||
| use crate::event::{MergeRequestAction, PipelineStatus}; | ||||
|  | ||||
| async fn build_sync_settings(matrix_client: &Client) -> SyncSettings { | ||||
|     let mut settings = SyncSettings::default().timeout(Duration::from_secs(30)); | ||||
|     if let Some(token) = matrix_client.sync_token().await { | ||||
| @@ -125,6 +127,16 @@ async fn handle_gitlab_event( | ||||
|     room_id: &OwnedRoomOrAliasId, | ||||
|     matrix_client: &Client, | ||||
| ) -> anyhow::Result<()> { | ||||
|     if let GitlabEvent::MergeRequest { object_attributes, .. } = &event { | ||||
|         if object_attributes.action == MergeRequestAction::Other { | ||||
|             return Ok(()); | ||||
|         } | ||||
|     } else if let GitlabEvent::Pipeline { object_attributes, .. } = &event { | ||||
|         if object_attributes.status == PipelineStatus::Other { | ||||
|             return Ok(()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     let room = ensure_matrix_room_joined(matrix_client, room_id).await?; | ||||
|     let msg = build_gitlab_message(&event); | ||||
|     debug!("Sending message to {}: {}", room_id, msg); | ||||
| @@ -160,7 +172,7 @@ async fn run() -> anyhow::Result<()> { | ||||
|  | ||||
|             async move { | ||||
|                 let project = event.project(); | ||||
|                 let config_key = project.homepage.replace("http://", "").replace("https://", ""); | ||||
|                 let config_key = project.web_url.replace("http://", "").replace("https://", ""); | ||||
|                 if let Some(repo_config) = config.repo_configs.get(&config_key) { | ||||
|                     if !constant_time_eq(token.as_bytes(), repo_config.token.as_bytes()) { | ||||
|                         warn!("Invalid token for repo '{}'", config_key); | ||||
|   | ||||
							
								
								
									
										200
									
								
								test-data/merge-request-event.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								test-data/merge-request-event.json
									
									
									
									
									
										Normal file
									
								
							| @@ -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" | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										262
									
								
								test-data/pipeline-event.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										262
									
								
								test-data/pipeline-event.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,262 @@ | ||||
| { | ||||
|    "object_kind": "pipeline", | ||||
|    "object_attributes":{ | ||||
|       "id": 31, | ||||
|       "iid": 3, | ||||
|       "name": "Pipeline for branch: master", | ||||
|       "ref": "master", | ||||
|       "tag": false, | ||||
|       "sha": "bcbb5ec396a2c0f828686f14fac9b80b780504f2", | ||||
|       "before_sha": "bcbb5ec396a2c0f828686f14fac9b80b780504f2", | ||||
|       "source": "merge_request_event", | ||||
|       "status": "failed", | ||||
|       "stages":[ | ||||
|          "build", | ||||
|          "test", | ||||
|          "deploy" | ||||
|       ], | ||||
|       "created_at": "2016-08-12 15:23:28 UTC", | ||||
|       "finished_at": "2016-08-12 15:26:29 UTC", | ||||
|       "duration": 63, | ||||
|       "variables": [ | ||||
|         { | ||||
|           "key": "NESTOR_PROD_ENVIRONMENT", | ||||
|           "value": "us-west-1" | ||||
|         } | ||||
|       ], | ||||
|       "url": "http://example.com/gitlab-org/gitlab-test/-/pipelines/31" | ||||
|    }, | ||||
|     "merge_request": { | ||||
|       "id": 1, | ||||
|       "iid": 1, | ||||
|       "title": "Test", | ||||
|       "source_branch": "test", | ||||
|       "source_project_id": 1, | ||||
|       "target_branch": "master", | ||||
|       "target_project_id": 1, | ||||
|       "state": "opened", | ||||
|       "merge_status": "can_be_merged", | ||||
|       "detailed_merge_status": "mergeable", | ||||
|       "url": "http://192.168.64.1:3005/gitlab-org/gitlab-test/merge_requests/1" | ||||
|    }, | ||||
|    "user":{ | ||||
|       "id": 1, | ||||
|       "name": "Administrator", | ||||
|       "username": "root", | ||||
|       "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon", | ||||
|       "email": "user_email@gitlab.com" | ||||
|    }, | ||||
|    "project":{ | ||||
|       "id": 1, | ||||
|       "name": "Gitlab Test", | ||||
|       "description": "Atque in sunt eos similique dolores voluptatem.", | ||||
|       "web_url": "http://192.168.64.1:3005/gitlab-org/gitlab-test", | ||||
|       "avatar_url": null, | ||||
|       "git_ssh_url": "git@192.168.64.1:gitlab-org/gitlab-test.git", | ||||
|       "git_http_url": "http://192.168.64.1:3005/gitlab-org/gitlab-test.git", | ||||
|       "namespace": "Gitlab Org", | ||||
|       "visibility_level": 20, | ||||
|       "path_with_namespace": "gitlab-org/gitlab-test", | ||||
|       "default_branch": "master" | ||||
|    }, | ||||
|    "commit":{ | ||||
|       "id": "bcbb5ec396a2c0f828686f14fac9b80b780504f2", | ||||
|       "message": "test\n", | ||||
|       "timestamp": "2016-08-12T17:23:21+02:00", | ||||
|       "url": "http://example.com/gitlab-org/gitlab-test/commit/bcbb5ec396a2c0f828686f14fac9b80b780504f2", | ||||
|       "author":{ | ||||
|          "name": "User", | ||||
|          "email": "user@gitlab.com" | ||||
|       } | ||||
|    }, | ||||
|    "source_pipeline":{ | ||||
|       "project":{ | ||||
|         "id": 41, | ||||
|         "web_url": "https://gitlab.example.com/gitlab-org/upstream-project", | ||||
|         "path_with_namespace": "gitlab-org/upstream-project" | ||||
|       }, | ||||
|       "pipeline_id": 30, | ||||
|       "job_id": 3401 | ||||
|    }, | ||||
|    "builds":[ | ||||
|       { | ||||
|          "id": 380, | ||||
|          "stage": "deploy", | ||||
|          "name": "production", | ||||
|          "status": "skipped", | ||||
|          "created_at": "2016-08-12 15:23:28 UTC", | ||||
|          "started_at": null, | ||||
|          "finished_at": null, | ||||
|          "duration": null, | ||||
|          "queued_duration": null, | ||||
|          "failure_reason": null, | ||||
|          "when": "manual", | ||||
|          "manual": true, | ||||
|          "allow_failure": false, | ||||
|          "user":{ | ||||
|             "id": 1, | ||||
|             "name": "Administrator", | ||||
|             "username": "root", | ||||
|             "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon", | ||||
|             "email": "admin@example.com" | ||||
|          }, | ||||
|          "runner": null, | ||||
|          "artifacts_file":{ | ||||
|             "filename": null, | ||||
|             "size": null | ||||
|          }, | ||||
|          "environment": { | ||||
|            "name": "production", | ||||
|            "action": "start", | ||||
|            "deployment_tier": "production" | ||||
|          } | ||||
|       }, | ||||
|       { | ||||
|          "id": 377, | ||||
|          "stage": "test", | ||||
|          "name": "test-image", | ||||
|          "status": "success", | ||||
|          "created_at": "2016-08-12 15:23:28 UTC", | ||||
|          "started_at": "2016-08-12 15:26:12 UTC", | ||||
|          "finished_at": "2016-08-12 15:26:29 UTC", | ||||
|          "duration": 17.0, | ||||
|          "queued_duration": 196.0, | ||||
|          "failure_reason": null, | ||||
|          "when": "on_success", | ||||
|          "manual": false, | ||||
|          "allow_failure": false, | ||||
|          "user":{ | ||||
|             "id": 1, | ||||
|             "name": "Administrator", | ||||
|             "username": "root", | ||||
|             "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon", | ||||
|             "email": "admin@example.com" | ||||
|          }, | ||||
|          "runner": { | ||||
|             "id": 380987, | ||||
|             "description": "shared-runners-manager-6.gitlab.com", | ||||
|             "active": true, | ||||
|             "runner_type": "instance_type", | ||||
|             "is_shared": true, | ||||
|             "tags": [ | ||||
|               "linux", | ||||
|               "docker", | ||||
|               "shared-runner" | ||||
|             ] | ||||
|          }, | ||||
|          "artifacts_file":{ | ||||
|             "filename": null, | ||||
|             "size": null | ||||
|          }, | ||||
|          "environment": null | ||||
|       }, | ||||
|       { | ||||
|          "id": 378, | ||||
|          "stage": "test", | ||||
|          "name": "test-build", | ||||
|          "status": "failed", | ||||
|          "created_at": "2016-08-12 15:23:28 UTC", | ||||
|          "started_at": "2016-08-12 15:26:12 UTC", | ||||
|          "finished_at": "2016-08-12 15:26:29 UTC", | ||||
|          "duration": 17.0, | ||||
|          "queued_duration": 196.0, | ||||
|          "failure_reason": "script_failure", | ||||
|          "when": "on_success", | ||||
|          "manual": false, | ||||
|          "allow_failure": false, | ||||
|          "user":{ | ||||
|             "id": 1, | ||||
|             "name": "Administrator", | ||||
|             "username": "root", | ||||
|             "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon", | ||||
|             "email": "admin@example.com" | ||||
|          }, | ||||
|          "runner": { | ||||
|             "id":380987, | ||||
|             "description":"shared-runners-manager-6.gitlab.com", | ||||
|             "active":true, | ||||
|             "runner_type": "instance_type", | ||||
|             "is_shared": true, | ||||
|             "tags": [ | ||||
|               "linux", | ||||
|               "docker" | ||||
|             ] | ||||
|          }, | ||||
|          "artifacts_file":{ | ||||
|             "filename": null, | ||||
|             "size": null | ||||
|          }, | ||||
|          "environment": null | ||||
|       }, | ||||
|       { | ||||
|          "id": 376, | ||||
|          "stage": "build", | ||||
|          "name": "build-image", | ||||
|          "status": "success", | ||||
|          "created_at": "2016-08-12 15:23:28 UTC", | ||||
|          "started_at": "2016-08-12 15:24:56 UTC", | ||||
|          "finished_at": "2016-08-12 15:25:26 UTC", | ||||
|          "duration": 17.0, | ||||
|          "queued_duration": 196.0, | ||||
|          "failure_reason": null, | ||||
|          "when": "on_success", | ||||
|          "manual": false, | ||||
|          "allow_failure": false, | ||||
|          "user":{ | ||||
|             "id": 1, | ||||
|             "name": "Administrator", | ||||
|             "username": "root", | ||||
|             "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon", | ||||
|             "email": "admin@example.com" | ||||
|          }, | ||||
|          "runner": { | ||||
|             "id": 380987, | ||||
|             "description": "shared-runners-manager-6.gitlab.com", | ||||
|             "active": true, | ||||
|             "runner_type": "instance_type", | ||||
|             "is_shared": true, | ||||
|             "tags": [ | ||||
|               "linux", | ||||
|               "docker" | ||||
|             ] | ||||
|          }, | ||||
|          "artifacts_file":{ | ||||
|             "filename": null, | ||||
|             "size": null | ||||
|          }, | ||||
|          "environment": null | ||||
|       }, | ||||
|       { | ||||
|          "id": 379, | ||||
|          "stage": "deploy", | ||||
|          "name": "staging", | ||||
|          "status": "created", | ||||
|          "created_at": "2016-08-12 15:23:28 UTC", | ||||
|          "started_at": null, | ||||
|          "finished_at": null, | ||||
|          "duration": null, | ||||
|          "queued_duration": null, | ||||
|          "failure_reason": null, | ||||
|          "when": "on_success", | ||||
|          "manual": false, | ||||
|          "allow_failure": false, | ||||
|          "user":{ | ||||
|             "id": 1, | ||||
|             "name": "Administrator", | ||||
|             "username": "root", | ||||
|             "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon", | ||||
|             "email": "admin@example.com" | ||||
|          }, | ||||
|          "runner": null, | ||||
|          "artifacts_file":{ | ||||
|             "filename": null, | ||||
|             "size": null | ||||
|          }, | ||||
|          "environment": { | ||||
|            "name": "staging", | ||||
|            "action": "start", | ||||
|            "deployment_tier": "staging" | ||||
|          } | ||||
|       } | ||||
|    ] | ||||
| } | ||||
		Reference in New Issue
	
	Block a user