Add configurable event publishing
This commit is contained in:
parent
4c00f45b1c
commit
e3fffe1814
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -160,8 +160,10 @@ dependencies = [
|
||||
"http",
|
||||
"log",
|
||||
"matrix-sdk",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_regex",
|
||||
"serde_yaml",
|
||||
"tokio",
|
||||
"warp",
|
||||
@ -1453,6 +1455,16 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_regex"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf"
|
||||
dependencies = [
|
||||
"regex",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.1"
|
||||
|
@ -12,8 +12,10 @@ env_logger = "0.10"
|
||||
http = "0.2"
|
||||
log = { version = "0.4", features = ["std"] }
|
||||
matrix-sdk = { version = "0.6", features = ["anyhow", "markdown", "rustls-tls"], default-features = false }
|
||||
regex = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
serde_regex = "1"
|
||||
serde_yaml = "0.9"
|
||||
tokio = { version = "1", default-features = false, features = ["rt-multi-thread", "macros"] }
|
||||
warp = "0.3"
|
||||
|
19
README.md
19
README.md
@ -23,23 +23,8 @@ running `cargo install bebot`.
|
||||
## Setup
|
||||
|
||||
Bebot requires a configuration file in YAML format. See
|
||||
`sample-config.yaml` for all existing configuration options. They
|
||||
should hopefully be fairly self-explanatory, but a few clarifications:
|
||||
|
||||
1. `bind_address` and `bind_port` determine what IP/interface and port
|
||||
the webhook handler will listen on.
|
||||
2. Bebot's webhook will be served from `/hooks/gitlab`. You can use
|
||||
`url_prefix` to prepend further path segments in front of that.
|
||||
3. `user_id` and `password` are for the Matrix user that the bot will
|
||||
sign into Matrix as. Ensure that `user_id` is the full username,
|
||||
including the homeserver.
|
||||
4. `default_room` is the room that Bebot will publish to if not
|
||||
specified in the per-repo configuration.
|
||||
5. `repo_configs` is a map where the key is of the form
|
||||
`$GITLAB_INSTANCE/$NAMESPACE/$REPO`. It is recommended that you use
|
||||
a unique, randomly-generated `token` for each repository. You can
|
||||
specify `room` here as well if you don't want messages to go to
|
||||
`default_room`.
|
||||
`sample-config.yaml` for all existing configuration options, as well as
|
||||
documentation on what each option does.
|
||||
|
||||
When setting up the webhook in Gitlab, use the same `token` from the
|
||||
configuration file in the webhook's "Secret token" field. You should
|
||||
|
@ -1,12 +1,58 @@
|
||||
# Address/interface the webhook listener should bind to (default is 127.0.0.1).
|
||||
bind_address: 127.0.0.1
|
||||
# Port the webhook listener should bind to (default is 3000).
|
||||
bind_port: 3000
|
||||
# Optional prefix to serve the webhook path under (default is empty string).
|
||||
url_prefix: "/bebot"
|
||||
# Matrix user to sign in as.
|
||||
user_id: "@mybebot:example.com"
|
||||
# Password for Matrix user.
|
||||
password: "secret-matrix-account-password"
|
||||
# Default Matrix room to publish events to.
|
||||
default_room: "#my-project-commits:example.com"
|
||||
# Default set of events to publish. If left out, all events will be published.
|
||||
default_publish_events:
|
||||
- name: push
|
||||
# Regexes of branch names. Leave out entirely for "all branches".
|
||||
branches:
|
||||
- '^main$'
|
||||
- '^xfce-.+'
|
||||
- name: tag_push
|
||||
- name: issues
|
||||
# See the Gitlab docs for a full list of actions. If left out, all actions
|
||||
# will be published.
|
||||
actions:
|
||||
- open
|
||||
- close
|
||||
- name: merge_request
|
||||
# See the Gitlab docs for a full list of actions. If left out, all actions
|
||||
# will be published.
|
||||
actions:
|
||||
- open
|
||||
- merge
|
||||
- name: pipeline
|
||||
# See the Gitlab docs for a full list of statuses. If left out, all
|
||||
# actions will be published.
|
||||
statuses:
|
||||
- failed
|
||||
# Key-value configuration for repositories.
|
||||
repo_configs:
|
||||
# Keys are the instance name / namespace / repository name
|
||||
"gitlab.example.com/myorg/my-cool-app":
|
||||
# Each repository should use a unique, randomly-generated token. Enter
|
||||
# this token in the webhook configuration's "Secret token" on Gitlab.
|
||||
token: "abcdefg12345"
|
||||
# You can override the default_room above. Leave out to use the default.
|
||||
room: "#my-cool-app-events:example.com"
|
||||
# You can override default_events above. Leave out this section to
|
||||
# use the defaults.
|
||||
publish_events:
|
||||
- name: push
|
||||
branches:
|
||||
- main
|
||||
- name: pipeline
|
||||
statuses:
|
||||
- failed
|
||||
"gitlab.example.com/myuser/some-other-less-cool-app":
|
||||
room: "#my-other-room:example.com"
|
||||
token: "kljaslkdjaklsdjalksd"
|
||||
# This repo uses the default events and room.
|
||||
|
@ -18,14 +18,38 @@ use std::{collections::HashMap, fmt, fs::File, io::BufReader};
|
||||
|
||||
use anyhow::Context;
|
||||
use matrix_sdk::ruma::{OwnedRoomOrAliasId, OwnedUserId, RoomOrAliasId, UserId};
|
||||
use regex::Regex;
|
||||
use serde::de;
|
||||
|
||||
use crate::event::{IssueAction, MergeRequestAction, PipelineStatus};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(tag = "name", rename_all = "snake_case")]
|
||||
pub enum PublishEvent {
|
||||
Push {
|
||||
#[serde(default)]
|
||||
#[serde(with = "serde_regex")]
|
||||
branches: Option<Vec<Regex>>,
|
||||
},
|
||||
TagPush,
|
||||
Issues {
|
||||
actions: Option<Vec<IssueAction>>,
|
||||
},
|
||||
MergeRequest {
|
||||
actions: Option<Vec<MergeRequestAction>>,
|
||||
},
|
||||
Pipeline {
|
||||
statuses: Option<Vec<PipelineStatus>>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct RepoConfig {
|
||||
pub token: String,
|
||||
#[serde(default)]
|
||||
#[serde(deserialize_with = "deser_optional_room_or_alias_id")]
|
||||
pub room: Option<OwnedRoomOrAliasId>,
|
||||
pub publish_events: Option<Vec<PublishEvent>>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@ -39,6 +63,7 @@ pub struct Config {
|
||||
#[serde(default)]
|
||||
#[serde(deserialize_with = "deser_optional_room_or_alias_id")]
|
||||
pub default_room: Option<OwnedRoomOrAliasId>,
|
||||
pub default_publish_events: Option<Vec<PublishEvent>>,
|
||||
pub repo_configs: HashMap<String, RepoConfig>, // key is repo url without scheme; e.g.
|
||||
// gitlab.xfce.org/xfce/xfdesktop
|
||||
}
|
||||
|
316
src/event.rs
316
src/event.rs
@ -14,7 +14,12 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use core::fmt;
|
||||
|
||||
use crate::config::PublishEvent;
|
||||
|
||||
pub trait GitlabEventExt {
|
||||
fn should_publish(&self, publish_events: &Vec<PublishEvent>) -> bool;
|
||||
fn project(&self) -> &Project;
|
||||
fn r#ref(&self) -> Option<&str>;
|
||||
fn user(&self) -> &str;
|
||||
@ -49,37 +54,39 @@ pub struct Commit {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
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")]
|
||||
Open,
|
||||
Close,
|
||||
Reopen,
|
||||
Update,
|
||||
Approve,
|
||||
Unapprove,
|
||||
Merged,
|
||||
Approval,
|
||||
Unapproval,
|
||||
#[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",
|
||||
}
|
||||
impl fmt::Display for MergeRequestAction {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
MergeRequestAction::Open => "opened",
|
||||
MergeRequestAction::Close => "closed",
|
||||
MergeRequestAction::Reopen => "reopened",
|
||||
MergeRequestAction::Update => "updated",
|
||||
MergeRequestAction::Approve => "approved",
|
||||
MergeRequestAction::Unapprove => "unapproved",
|
||||
MergeRequestAction::Approval => "approval",
|
||||
MergeRequestAction::Unapproval => "unapproval",
|
||||
MergeRequestAction::Merged => "merged",
|
||||
MergeRequestAction::Other => "other",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,19 +103,43 @@ pub struct MergeRequestObjectAttributes {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum PipelineStatus {
|
||||
#[serde(rename = "failed")]
|
||||
Created,
|
||||
WaitingForResource,
|
||||
Preparing,
|
||||
Pending,
|
||||
Running,
|
||||
Success,
|
||||
Failed,
|
||||
Canceled,
|
||||
Skipped,
|
||||
Manual,
|
||||
Scheduled,
|
||||
#[serde(other)]
|
||||
Other,
|
||||
}
|
||||
|
||||
impl PipelineStatus {
|
||||
pub fn as_str(&self) -> &str {
|
||||
match self {
|
||||
PipelineStatus::Failed => "failed",
|
||||
PipelineStatus::Other => "other",
|
||||
}
|
||||
impl fmt::Display for PipelineStatus {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
PipelineStatus::Created => "created",
|
||||
PipelineStatus::WaitingForResource => "waiting for resource",
|
||||
PipelineStatus::Preparing => "preparing",
|
||||
PipelineStatus::Pending => "pending",
|
||||
PipelineStatus::Running => "running",
|
||||
PipelineStatus::Success => "succeeded",
|
||||
PipelineStatus::Failed => "failed",
|
||||
PipelineStatus::Canceled => "canceled",
|
||||
PipelineStatus::Skipped => "skipped",
|
||||
PipelineStatus::Manual => "manual",
|
||||
PipelineStatus::Scheduled => "scheduled",
|
||||
PipelineStatus::Other => "other",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,37 +157,38 @@ pub struct PipelineMergeRequest {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum IssueAction {
|
||||
#[serde(rename = "open")]
|
||||
Opened,
|
||||
#[serde(rename = "close")]
|
||||
Closed,
|
||||
#[serde(rename = "reopen")]
|
||||
Reopened,
|
||||
#[serde(rename = "update")]
|
||||
Updated,
|
||||
Open,
|
||||
Close,
|
||||
Reopen,
|
||||
Update,
|
||||
#[serde(other)]
|
||||
Other,
|
||||
}
|
||||
|
||||
impl IssueAction {
|
||||
pub fn as_str(&self) -> &str {
|
||||
match self {
|
||||
IssueAction::Opened => "opened",
|
||||
IssueAction::Closed => "closed",
|
||||
IssueAction::Reopened => "reopened",
|
||||
IssueAction::Updated => "updated",
|
||||
IssueAction::Other => "other",
|
||||
}
|
||||
impl fmt::Display for IssueAction {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
IssueAction::Open => "opened",
|
||||
IssueAction::Close => "closed",
|
||||
IssueAction::Reopen => "reopened",
|
||||
IssueAction::Update => "updated",
|
||||
IssueAction::Other => "other",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct IssueObjectAttributes {
|
||||
id: u32,
|
||||
title: String,
|
||||
action: IssueAction,
|
||||
url: String,
|
||||
pub id: u32,
|
||||
pub title: String,
|
||||
pub action: IssueAction,
|
||||
pub url: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
@ -222,7 +254,74 @@ pub enum GitlabEvent {
|
||||
Other,
|
||||
}
|
||||
|
||||
macro_rules! find_publish_event {
|
||||
($cfgs:expr, $case:pat) => {
|
||||
$cfgs.iter().find(|cfg| match cfg {
|
||||
$case => true,
|
||||
_ => false,
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
impl GitlabEventExt for GitlabEvent {
|
||||
fn should_publish(&self, publish_events: &Vec<PublishEvent>) -> bool {
|
||||
match self {
|
||||
GitlabEvent::Push { r#ref, .. } => {
|
||||
if let Some(PublishEvent::Push { branches }) =
|
||||
find_publish_event!(publish_events, PublishEvent::Push { .. })
|
||||
{
|
||||
match branches {
|
||||
None => true,
|
||||
Some(branches) => {
|
||||
let refname = parse_ref(r#ref);
|
||||
branches.iter().find(|branch| branch.find(&refname).is_some()).is_some()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
GitlabEvent::TagPush { .. } => find_publish_event!(publish_events, PublishEvent::TagPush { .. }).is_some(),
|
||||
GitlabEvent::Issue { object_attributes, .. } => {
|
||||
if let Some(PublishEvent::Issues { actions }) =
|
||||
find_publish_event!(publish_events, PublishEvent::Issues { .. })
|
||||
{
|
||||
match actions {
|
||||
None => true,
|
||||
Some(actions) => actions.contains(&object_attributes.action),
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
GitlabEvent::MergeRequest { object_attributes, .. } => {
|
||||
if let Some(PublishEvent::MergeRequest { actions }) =
|
||||
find_publish_event!(publish_events, PublishEvent::MergeRequest { .. })
|
||||
{
|
||||
match actions {
|
||||
None => true,
|
||||
Some(actions) => actions.contains(&object_attributes.action),
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
GitlabEvent::Pipeline { object_attributes, .. } => {
|
||||
if let Some(PublishEvent::Pipeline { statuses }) =
|
||||
find_publish_event!(publish_events, PublishEvent::Pipeline { .. })
|
||||
{
|
||||
match statuses {
|
||||
None => true,
|
||||
Some(statuses) => statuses.contains(&object_attributes.status),
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
GitlabEvent::Other => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn project(&self) -> &Project {
|
||||
match self {
|
||||
GitlabEvent::Push { project, .. } => &project,
|
||||
@ -307,9 +406,7 @@ impl GitlabEventExt for GitlabEvent {
|
||||
if object_attributes.action != IssueAction::Other {
|
||||
let title = format!(
|
||||
"Issue #{} **{}**: {}",
|
||||
object_attributes.id,
|
||||
object_attributes.action.as_str(),
|
||||
object_attributes.title
|
||||
object_attributes.id, object_attributes.action, object_attributes.title
|
||||
);
|
||||
vec![markdown_link(&title, &object_attributes.url)]
|
||||
} else {
|
||||
@ -320,9 +417,7 @@ impl GitlabEventExt for GitlabEvent {
|
||||
if object_attributes.action != MergeRequestAction::Other {
|
||||
let title = format!(
|
||||
"MR !{} **{}**: {}",
|
||||
object_attributes.iid,
|
||||
object_attributes.action.as_str(),
|
||||
object_attributes.title
|
||||
object_attributes.iid, object_attributes.action, object_attributes.title
|
||||
);
|
||||
vec![markdown_link(&title, &object_attributes.url)]
|
||||
} else {
|
||||
@ -341,10 +436,9 @@ impl GitlabEventExt for GitlabEvent {
|
||||
.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),
|
||||
);
|
||||
.fold(format!("Pipeline **{}**", object_attributes.status), |accum, title| {
|
||||
format!("{}: {}", accum, title)
|
||||
});
|
||||
vec![markdown_link(&title, &object_attributes.url)]
|
||||
} else {
|
||||
vec![]
|
||||
@ -376,6 +470,7 @@ pub fn parse_ref(r#ref: &str) -> String {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use regex::Regex;
|
||||
use std::{fs::File, io::BufReader};
|
||||
|
||||
fn load_test_data(name: &str) -> anyhow::Result<GitlabEvent> {
|
||||
@ -389,7 +484,7 @@ mod test {
|
||||
pub fn parse_push_event() -> anyhow::Result<()> {
|
||||
let event = load_test_data("push-event")?;
|
||||
|
||||
match event {
|
||||
match &event {
|
||||
GitlabEvent::Push {
|
||||
event_name,
|
||||
before,
|
||||
@ -412,11 +507,32 @@ mod test {
|
||||
assert_eq!(project.namespace, "Mike");
|
||||
assert_eq!(repository.name, "Diaspora");
|
||||
assert_eq!(repository.url, "git@example.com:mike/diaspora.git");
|
||||
assert_eq!(total_commits_count, 4);
|
||||
assert_eq!(*total_commits_count, 4);
|
||||
}
|
||||
_ => panic!("not a push event"),
|
||||
};
|
||||
|
||||
let publish_events = vec![PublishEvent::Push { branches: None }];
|
||||
assert!(event.should_publish(&publish_events));
|
||||
|
||||
let publish_events = vec![PublishEvent::Push {
|
||||
branches: Some(vec![Regex::new(r"^master$").unwrap()]),
|
||||
}];
|
||||
assert!(event.should_publish(&publish_events));
|
||||
|
||||
let publish_events = vec![PublishEvent::Push {
|
||||
branches: Some(vec![Regex::new(r"^mas").unwrap()]),
|
||||
}];
|
||||
assert!(event.should_publish(&publish_events));
|
||||
|
||||
let publish_events = vec![PublishEvent::Push {
|
||||
branches: Some(vec![Regex::new(r"^foobar$").unwrap()]),
|
||||
}];
|
||||
assert!(!event.should_publish(&publish_events));
|
||||
|
||||
let publish_events = vec![PublishEvent::Pipeline { statuses: None }];
|
||||
assert!(!event.should_publish(&publish_events));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -424,7 +540,7 @@ mod test {
|
||||
pub fn parse_tag_push_event() -> anyhow::Result<()> {
|
||||
let event = load_test_data("tag-push-event")?;
|
||||
|
||||
match event {
|
||||
match &event {
|
||||
GitlabEvent::TagPush {
|
||||
event_name,
|
||||
before,
|
||||
@ -446,11 +562,17 @@ mod test {
|
||||
assert_eq!(project.name, "Example");
|
||||
assert_eq!(project.namespace, "Jsmith");
|
||||
assert_eq!(repository.name, "Example");
|
||||
assert_eq!(total_commits_count, 0);
|
||||
assert_eq!(*total_commits_count, 0);
|
||||
}
|
||||
_ => panic!("not a tag push event"),
|
||||
};
|
||||
|
||||
let publish_events = vec![PublishEvent::TagPush];
|
||||
assert!(event.should_publish(&publish_events));
|
||||
|
||||
let publish_events = vec![PublishEvent::Push { branches: None }];
|
||||
assert!(!event.should_publish(&publish_events));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -458,7 +580,7 @@ mod test {
|
||||
pub fn parse_issue_event() -> anyhow::Result<()> {
|
||||
let event = load_test_data("issue-event")?;
|
||||
|
||||
match event {
|
||||
match &event {
|
||||
GitlabEvent::Issue {
|
||||
user,
|
||||
object_attributes,
|
||||
@ -466,11 +588,27 @@ mod test {
|
||||
} => {
|
||||
assert_eq!(user.name, "Administrator");
|
||||
assert_eq!(object_attributes.id, 301);
|
||||
assert_eq!(object_attributes.action, IssueAction::Opened);
|
||||
assert_eq!(object_attributes.action, IssueAction::Open);
|
||||
}
|
||||
_ => panic!("not an issue event"),
|
||||
}
|
||||
|
||||
let publish_events = vec![PublishEvent::Issues { actions: None }];
|
||||
assert!(event.should_publish(&publish_events));
|
||||
|
||||
let publish_events = vec![PublishEvent::Issues {
|
||||
actions: Some(vec![IssueAction::Open]),
|
||||
}];
|
||||
assert!(event.should_publish(&publish_events));
|
||||
|
||||
let publish_events = vec![PublishEvent::Issues {
|
||||
actions: Some(vec![IssueAction::Close]),
|
||||
}];
|
||||
assert!(!event.should_publish(&publish_events));
|
||||
|
||||
let publish_events = vec![PublishEvent::Push { branches: None }];
|
||||
assert!(!event.should_publish(&publish_events));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -478,19 +616,35 @@ mod test {
|
||||
pub fn parse_merge_request_event() -> anyhow::Result<()> {
|
||||
let event = load_test_data("merge-request-event")?;
|
||||
|
||||
match event {
|
||||
match &event {
|
||||
GitlabEvent::MergeRequest {
|
||||
user,
|
||||
object_attributes,
|
||||
..
|
||||
} => {
|
||||
assert_eq!(user.name, "Administrator");
|
||||
assert_eq!(object_attributes.action, MergeRequestAction::Opened);
|
||||
assert_eq!(object_attributes.action, MergeRequestAction::Open);
|
||||
assert_eq!(object_attributes.title, "MS-Viewport");
|
||||
}
|
||||
_ => panic!("not a merge request event"),
|
||||
};
|
||||
|
||||
let publish_events = vec![PublishEvent::MergeRequest { actions: None }];
|
||||
assert!(event.should_publish(&publish_events));
|
||||
|
||||
let publish_events = vec![PublishEvent::MergeRequest {
|
||||
actions: Some(vec![MergeRequestAction::Open]),
|
||||
}];
|
||||
assert!(event.should_publish(&publish_events));
|
||||
|
||||
let publish_events = vec![PublishEvent::MergeRequest {
|
||||
actions: Some(vec![MergeRequestAction::Close]),
|
||||
}];
|
||||
assert!(!event.should_publish(&publish_events));
|
||||
|
||||
let publish_events = vec![PublishEvent::Push { branches: None }];
|
||||
assert!(!event.should_publish(&publish_events));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -498,7 +652,7 @@ mod test {
|
||||
pub fn parse_pipeline_event() -> anyhow::Result<()> {
|
||||
let event = load_test_data("pipeline-event")?;
|
||||
|
||||
match event {
|
||||
match &event {
|
||||
GitlabEvent::Pipeline {
|
||||
object_attributes,
|
||||
merge_request,
|
||||
@ -508,12 +662,28 @@ mod test {
|
||||
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.unwrap().title, "Test");
|
||||
assert_eq!(merge_request.as_ref().unwrap().title, "Test");
|
||||
assert_eq!(user.name, "Administrator");
|
||||
}
|
||||
_ => panic!("not a pipeline event"),
|
||||
};
|
||||
|
||||
let publish_events = vec![PublishEvent::Pipeline { statuses: None }];
|
||||
assert!(event.should_publish(&publish_events));
|
||||
|
||||
let publish_events = vec![PublishEvent::Pipeline {
|
||||
statuses: Some(vec![PipelineStatus::Failed]),
|
||||
}];
|
||||
assert!(event.should_publish(&publish_events));
|
||||
|
||||
let publish_events = vec![PublishEvent::Pipeline {
|
||||
statuses: Some(vec![PipelineStatus::Success]),
|
||||
}];
|
||||
assert!(!event.should_publish(&publish_events));
|
||||
|
||||
let publish_events = vec![PublishEvent::Push { branches: None }];
|
||||
assert!(!event.should_publish(&publish_events));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
10
src/main.rs
10
src/main.rs
@ -215,8 +215,14 @@ async fn run() -> anyhow::Result<()> {
|
||||
} else {
|
||||
debug!("payload: {:?}", event);
|
||||
if let Some(room) = repo_config.room.as_ref().or(config.default_room.as_ref()) {
|
||||
if let Err(err) = event_tx.send((event, room.clone())).await {
|
||||
warn!("Failed to enqueue payload: {}", err);
|
||||
let publish_events = repo_config
|
||||
.publish_events
|
||||
.as_ref()
|
||||
.or(config.default_publish_events.as_ref());
|
||||
if publish_events.map(|ecs| event.should_publish(ecs)).unwrap_or(true) {
|
||||
if let Err(err) = event_tx.send((event, room.clone())).await {
|
||||
warn!("Failed to enqueue payload: {}", err);
|
||||
}
|
||||
}
|
||||
warp::reply::with_status("OK", StatusCode::OK)
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user