Make messages look better and publish multiple for push events
For push events, publish one message per commit pushed, up to a limit of 15.
This commit is contained in:
parent
33d3313927
commit
fcdb10a7ff
115
src/event.rs
115
src/event.rs
@ -2,8 +2,7 @@ pub trait GitlabEventExt {
|
|||||||
fn project(&self) -> &Project;
|
fn project(&self) -> &Project;
|
||||||
fn r#ref(&self) -> &str;
|
fn r#ref(&self) -> &str;
|
||||||
fn user(&self) -> &str;
|
fn user(&self) -> &str;
|
||||||
fn url(&self) -> String;
|
fn titles(&self) -> Vec<String>;
|
||||||
fn title(&self) -> String;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
@ -70,6 +69,7 @@ impl MergeRequestAction {
|
|||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct MergeRequestObjectAttributes {
|
pub struct MergeRequestObjectAttributes {
|
||||||
|
pub iid: u64,
|
||||||
pub target_branch: String,
|
pub target_branch: String,
|
||||||
pub source_branch: String,
|
pub source_branch: String,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
@ -158,7 +158,7 @@ pub enum GitlabEvent {
|
|||||||
#[serde(rename = "pipeline")]
|
#[serde(rename = "pipeline")]
|
||||||
Pipeline {
|
Pipeline {
|
||||||
object_attributes: PipelineObjectAttributes,
|
object_attributes: PipelineObjectAttributes,
|
||||||
merge_request: PipelineMergeRequest,
|
merge_request: Option<PipelineMergeRequest>,
|
||||||
user: User,
|
user: User,
|
||||||
project: Project,
|
project: Project,
|
||||||
},
|
},
|
||||||
@ -192,56 +192,101 @@ impl GitlabEventExt for GitlabEvent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn url(&self) -> String {
|
fn titles(&self) -> Vec<String> {
|
||||||
let url = match self {
|
|
||||||
GitlabEvent::Push { after, project, .. } => format!("{}/-/commits/{}", project.web_url, after),
|
|
||||||
GitlabEvent::TagPush {
|
|
||||||
r#ref,
|
|
||||||
checkout_sha,
|
|
||||||
project,
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn title(&self) -> String {
|
|
||||||
fn find_commit<'a>(commits: &'a Vec<Commit>, sha: &str) -> Option<&'a Commit> {
|
fn find_commit<'a>(commits: &'a Vec<Commit>, sha: &str) -> Option<&'a Commit> {
|
||||||
commits.iter().find(|commit| commit.id == sha)
|
commits.iter().find(|commit| commit.id == sha)
|
||||||
}
|
}
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
GitlabEvent::Push { after, commits, .. } => find_commit(commits, &after)
|
GitlabEvent::Push {
|
||||||
.map(|commit| commit.title.clone())
|
after,
|
||||||
.unwrap_or_else(|| "New commit(s) pushed".to_string()),
|
project,
|
||||||
|
commits,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
const MAX_COMMITS: usize = 15; // TODO: make configurable
|
||||||
|
commits.iter().fold(Vec::new(), |mut titles, commit| {
|
||||||
|
if titles.len() < MAX_COMMITS {
|
||||||
|
titles.push(format!("[**pushed** {}]({})", commit.title, commit.url));
|
||||||
|
|
||||||
|
if titles.len() == MAX_COMMITS {
|
||||||
|
titles.push(format!(
|
||||||
|
"[**pushed** {} more commits]({}/-/compare/{}...{})",
|
||||||
|
commits.len() - MAX_COMMITS,
|
||||||
|
project.web_url,
|
||||||
|
commit.id,
|
||||||
|
after
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
titles
|
||||||
|
})
|
||||||
|
}
|
||||||
GitlabEvent::TagPush {
|
GitlabEvent::TagPush {
|
||||||
checkout_sha, commits, ..
|
r#ref,
|
||||||
} => find_commit(commits, &checkout_sha)
|
checkout_sha,
|
||||||
.iter()
|
project,
|
||||||
.fold("New tag pushed".to_string(), |accum, commit| {
|
commits,
|
||||||
format!("{} ({})", accum, commit.title)
|
..
|
||||||
}),
|
} => {
|
||||||
|
let title = format!(
|
||||||
|
"**tagged** {}",
|
||||||
|
find_commit(commits, &checkout_sha)
|
||||||
|
.map(|commit| &commit.title)
|
||||||
|
.unwrap_or(checkout_sha)
|
||||||
|
);
|
||||||
|
let url = format!("{}/-/tags/{}", project.web_url, parse_ref(r#ref));
|
||||||
|
vec![markdown_link(&title, &url)]
|
||||||
|
}
|
||||||
GitlabEvent::MergeRequest { object_attributes, .. } => {
|
GitlabEvent::MergeRequest { object_attributes, .. } => {
|
||||||
format!("MR {}: {}", object_attributes.action.as_str(), object_attributes.title)
|
let title = format!(
|
||||||
|
"MR !{} **{}**: {}",
|
||||||
|
object_attributes.iid,
|
||||||
|
object_attributes.action.as_str(),
|
||||||
|
object_attributes.title
|
||||||
|
);
|
||||||
|
vec![markdown_link(&title, &object_attributes.url)]
|
||||||
}
|
}
|
||||||
GitlabEvent::Pipeline {
|
GitlabEvent::Pipeline {
|
||||||
object_attributes,
|
object_attributes,
|
||||||
merge_request,
|
merge_request,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let title = object_attributes.name.as_ref().unwrap_or(&merge_request.title);
|
let title = object_attributes
|
||||||
format!("Pipeline {}: {}", object_attributes.status.as_str(), title)
|
.name
|
||||||
|
.as_ref()
|
||||||
|
.map(|n| n.clone())
|
||||||
|
.or(merge_request.as_ref().map(|mr| mr.title.clone()))
|
||||||
|
.iter()
|
||||||
|
.fold(
|
||||||
|
format!("Pipeline **{}**", object_attributes.status.as_str()),
|
||||||
|
|accum, title| format!("{}: {}", accum, title),
|
||||||
|
);
|
||||||
|
vec![markdown_link(&title, &object_attributes.url)]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn markdown_link(title: &String, url: &String) -> String {
|
||||||
|
format!("[{}]({})", title, url)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_ref(r#ref: &str) -> String {
|
||||||
|
if r#ref.starts_with("refs/") {
|
||||||
|
let parts = r#ref.split('/').collect::<Vec<_>>();
|
||||||
|
if parts.len() > 2 {
|
||||||
|
parts.into_iter().skip(2).collect::<Vec<_>>().join("/").to_string()
|
||||||
|
} else {
|
||||||
|
r#ref.to_string()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
r#ref.to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
45
src/main.rs
45
src/main.rs
@ -105,28 +105,22 @@ async fn ensure_matrix_room_joined(matrix_client: &Client, room_id: &OwnedRoomOr
|
|||||||
room.ok_or_else(|| anyhow!("Unable to join room {}", room_id))
|
room.ok_or_else(|| anyhow!("Unable to join room {}", room_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_gitlab_message(event: &GitlabEvent) -> String {
|
fn build_gitlab_messages(event: &GitlabEvent) -> Vec<String> {
|
||||||
let project = event.project();
|
let project = event.project();
|
||||||
let r = event.r#ref();
|
let refname = event::parse_ref(event.r#ref());
|
||||||
let refname = if r.starts_with("refs/") {
|
event
|
||||||
let parts = r.split('/').collect::<Vec<_>>();
|
.titles()
|
||||||
if parts.len() > 2 {
|
.iter()
|
||||||
parts.into_iter().skip(2).collect::<Vec<_>>().join("/").to_string()
|
.map(|title| {
|
||||||
} else {
|
format!(
|
||||||
drop(parts);
|
"\\[{}\\] `{}` *{}* {}",
|
||||||
r.to_string()
|
project.path_with_namespace,
|
||||||
}
|
refname,
|
||||||
} else {
|
event.user(),
|
||||||
r.to_string()
|
title,
|
||||||
};
|
)
|
||||||
format!(
|
})
|
||||||
"*{}* {} **{}** [{}]({})",
|
.collect()
|
||||||
project.path_with_namespace,
|
|
||||||
refname,
|
|
||||||
event.user(),
|
|
||||||
event.title(),
|
|
||||||
event.url()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_gitlab_event(
|
async fn handle_gitlab_event(
|
||||||
@ -145,10 +139,11 @@ async fn handle_gitlab_event(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let room = ensure_matrix_room_joined(matrix_client, room_id).await?;
|
let room = ensure_matrix_room_joined(matrix_client, room_id).await?;
|
||||||
let msg = build_gitlab_message(&event);
|
for msg in build_gitlab_messages(&event) {
|
||||||
debug!("Sending message to {}: {}", room_id, msg);
|
debug!("Sending message to {}: {}", room_id, msg);
|
||||||
let msg_content = RoomMessageEventContent::text_markdown(&msg);
|
let msg_content = RoomMessageEventContent::text_markdown(&msg);
|
||||||
room.send(msg_content, None).await?;
|
room.send(msg_content, None).await?;
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user