docs: notification flows, their API and the notifications page
This commit is contained in:
parent
0512862b3d
commit
7795da44f8
9 changed files with 140 additions and 59 deletions
|
|
@ -42,7 +42,12 @@ pub const MAX_TEXT: usize = 500;
|
|||
|
||||
/// The forge event types a source node can start from: the ones
|
||||
/// swarm-controller's hooks deliver to the events stream.
|
||||
pub const SOURCE_EVENTS: &[&str] = &["issues", "issue_assign", "pull_request", "pull_request_assign"];
|
||||
pub const SOURCE_EVENTS: &[&str] = &[
|
||||
"issues",
|
||||
"issue_assign",
|
||||
"pull_request",
|
||||
"pull_request_assign",
|
||||
];
|
||||
|
||||
/// The fields of an event a condition or a recipient can name.
|
||||
pub const FIELDS: &[&str] = &[
|
||||
|
|
@ -204,8 +209,8 @@ impl Document {
|
|||
/// Not the expected shape, or a [`Document::version`] this build does not
|
||||
/// know. The reader keeps what it had.
|
||||
pub fn decode(bytes: &[u8]) -> Result<Self, DecodeError> {
|
||||
let value: serde_json::Value =
|
||||
serde_json::from_slice(bytes).map_err(|e| DecodeError::Malformed(format!("not JSON: {e}")))?;
|
||||
let value: serde_json::Value = serde_json::from_slice(bytes)
|
||||
.map_err(|e| DecodeError::Malformed(format!("not JSON: {e}")))?;
|
||||
if let Some(found) = value.get("version")
|
||||
&& found != VERSION
|
||||
{
|
||||
|
|
@ -225,15 +230,14 @@ impl Document {
|
|||
return Err(format!("version {} is not {VERSION}", self.version));
|
||||
}
|
||||
if self.flows.len() > MAX_FLOWS {
|
||||
return Err(format!(
|
||||
"{} flows, more than {MAX_FLOWS}",
|
||||
self.flows.len()
|
||||
));
|
||||
return Err(format!("{} flows, more than {MAX_FLOWS}", self.flows.len()));
|
||||
}
|
||||
let builtin = builtins();
|
||||
for id in &self.disabled_builtins {
|
||||
if !builtin.iter().any(|b| b.id == *id) {
|
||||
return Err(format!("disabled_builtins names {id}, which is no built-in flow"));
|
||||
return Err(format!(
|
||||
"disabled_builtins names {id}, which is no built-in flow"
|
||||
));
|
||||
}
|
||||
}
|
||||
let mut ids: BTreeSet<&str> = builtin.iter().map(|b| b.id.as_str()).collect();
|
||||
|
|
@ -244,7 +248,8 @@ impl Document {
|
|||
flow.id
|
||||
));
|
||||
}
|
||||
flow.validate().map_err(|why| format!("flow {}: {why}", flow.id))?;
|
||||
flow.validate()
|
||||
.map_err(|why| format!("flow {}: {why}", flow.id))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -401,7 +406,10 @@ impl NodeKind {
|
|||
}
|
||||
Self::Match { when } => {
|
||||
if let Some(bad) = when.iter().find(|c| !is_field(&c.field)) {
|
||||
return Err(format!("condition on {:?}, which is no event field", bad.field));
|
||||
return Err(format!(
|
||||
"condition on {:?}, which is no event field",
|
||||
bad.field
|
||||
));
|
||||
}
|
||||
}
|
||||
Self::Todo(sink) => sink.validate()?,
|
||||
|
|
@ -534,7 +542,10 @@ mod tests {
|
|||
}
|
||||
|
||||
fn builtin(id: &str) -> Flow {
|
||||
builtins().into_iter().find(|f| f.id == id).expect("a built-in")
|
||||
builtins()
|
||||
.into_iter()
|
||||
.find(|f| f.id == id)
|
||||
.expect("a built-in")
|
||||
}
|
||||
|
||||
/// A custom flow: opened issue or PR → a todo for `triage`.
|
||||
|
|
@ -704,7 +715,12 @@ mod tests {
|
|||
);
|
||||
let mut bad = custom("bad");
|
||||
bad.edges.pop();
|
||||
assert!(doc(&[], vec![bad]).check().unwrap_err().starts_with("flow bad:"));
|
||||
assert!(
|
||||
doc(&[], vec![bad])
|
||||
.check()
|
||||
.unwrap_err()
|
||||
.starts_with("flow bad:")
|
||||
);
|
||||
let many = (0..=MAX_FLOWS).map(|i| custom(&format!("f{i}"))).collect();
|
||||
assert!(doc(&[], many).check().is_err(), "flow count");
|
||||
let mut old = doc(&[], vec![]);
|
||||
|
|
|
|||
Loading…
Reference in a new issue