// Copyright (C) 2023-2099 The crate authors. // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published by the // Free Software Foundation, either version 3 of the License, or (at your // option) any later version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License // for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . pub use forgejo_hooks::Hook as ForgejoHook; pub use gitlab::webhooks::{ IssueAction, MergeRequestAction, WebHook as GitlabHook, WikiPageAction, }; use log::debug; #[derive(Debug)] pub enum Hook { Forgejo(ForgejoHook), Gitlab(GitlabHook), } impl From for Hook { fn from(hook: GitlabHook) -> Hook { Hook::Gitlab(hook) } } pub fn format_hook(glh: &GitlabHook) -> Option { Some(match glh { GitlabHook::Push(push) if push.object_kind == "tag_push" => { format!( "[{}] {} pushed tag {}.", push.project.name, push.user_name, push.ref_.strip_prefix("refs/tags/").unwrap_or("?!"), ) } GitlabHook::Push(push) => { if push.ref_ != "refs/heads/main" { // Ignore: Action not on 'main' branch return None; } // Unlikely to be reached as 'main' is probably never going to be deleted if push.commits.len() == 0 { // Ignore: Branch got deleted return None; } let mut text = format!( "[{}] {} pushed {} commits to main", push.project.name, push.user_name, push.commits.len(), ); // Display max 3 commits for commit in push.commits.clone().into_iter().take(3) { match commit.message.lines().nth(0) { Some(subject) => { text = format!("{}\n• {} <{}>", text, subject, commit.url); } None => {} } } text } GitlabHook::Issue(issue) => { let action = match issue.object_attributes.action { Some(IssueAction::Update) => return None, Some(IssueAction::Open) => "opened", Some(IssueAction::Close) => "closed", Some(IssueAction::Reopen) => "reopened", None => return None, }; format!( "[{}] {} {} issue {}: {}{}", issue.project.name, issue.user.name, action, issue.object_attributes.iid, issue.object_attributes.title, issue .object_attributes .url .as_ref() .map(|url| format!(" <{}>", url)) .unwrap_or("".to_owned()) ) } GitlabHook::MergeRequest(merge_req) => { let action = match merge_req.object_attributes.action { Some(MergeRequestAction::Update) => return None, Some(MergeRequestAction::Open) => "opened", Some(MergeRequestAction::Close) => "closed", Some(MergeRequestAction::Reopen) => "reopened", Some(MergeRequestAction::Merge) => "merged", None => return None, _ => { log::warn!( "Unsupported merge request action: {:?}", merge_req.object_attributes.action ); return None; } }; format!( "[{}] {} {} merge request {}: {}{}", merge_req.project.name, merge_req.user.name, action, merge_req.object_attributes.iid, merge_req.object_attributes.title, merge_req .object_attributes .url .as_ref() .map(|url| format!(" <{}>", url)) .unwrap_or("".to_owned()) ) } GitlabHook::Note(note) => { if let Some(_) = note.snippet { return None; } if let Some(commit) = ¬e.commit { format!( "[{}] {} commented on commit {:?} <{}>", note.project.name, note.user.name, commit.id, commit.url, ) } else if let Some(issue) = ¬e.issue { format!( "[{}] {} commented on issue {}: {} <{}>", note.project.name, note.user.name, issue.iid, issue.title, note.object_attributes.url, ) } else if let Some(mr) = ¬e.merge_request { format!( "[{}] {} commented on merge request {}: {} <{}>", note.project.name, note.user.name, mr.iid, mr.title, note.object_attributes.url, ) } else { unreachable!() } } GitlabHook::Build(build) => { println!("Build: {:?}", build); return None; } GitlabHook::WikiPage(page) => { let action = match page.object_attributes.action { WikiPageAction::Update => "updated", WikiPageAction::Create => "created", }; format!( "[{}] {} {} wiki page {} <{}>", page.project.name, page.user.name, action, page.object_attributes.title, page.object_attributes.url, ) } _glh => { debug!("Hook not supported"); return None; } }) }