Radish alpha
r
rad:zwTxygwuz5LDGBq255RA2CbNGrz8
Radicle CI broker
Radicle
Git
feat: make CI events versioned
Merged liw opened 1 year ago

This will help us avoid breaking changes in the future, when CI events need to be modified, and CI broker instances need to cope with the event queues in their databases.

Previously we had

enum CiEvent {
    BranchCreated { ... },
    BranchUpdatee { ... },
    ....
}

Change that to:

enum CiEvent {
    V1(CiEventV1),
}

enum CiEventV1 {
    BranchCreated { ... },
    BranchUpdatee { ... },
    ....
}

This will allow us to add new version variants to CiEvent, without losing access to the already enqueued V1 events.

Signed-off-by: Lars Wirzenius liw@liw.fi

8 files changed +108 -96 5e813f73 145e061a
modified src/bin/cibtool.rs
@@ -30,7 +30,7 @@ use radicle_git_ext::Oid;

use radicle_ci_broker::{
    broker::BrokerError,
-
    ci_event::{CiEvent, CiEventError},
+
    ci_event::{CiEvent, CiEventError, CiEventV1},
    db::{Db, DbError, QueueId, QueuedCiEvent},
    logger,
    msg::{RunId, RunResult},
modified src/bin/cibtoolcmd/event.rs
@@ -291,7 +291,7 @@ pub struct Shutdown {
impl Leaf for Shutdown {
    fn run(&self, args: &Args) -> Result<(), CibToolError> {
        let db = args.open_db()?;
-
        let id = db.push_queued_ci_event(CiEvent::Shutdown)?;
+
        let id = db.push_queued_ci_event(CiEvent::V1(CiEventV1::Shutdown))?;

        if let Some(filename) = &self.id_file {
            write(filename, id.to_string().as_bytes())
modified src/ci_event.rs
@@ -15,6 +15,11 @@ use radicle::{

#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]
pub enum CiEvent {
+
    V1(CiEventV1),
+
}
+

+
#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize)]
+
pub enum CiEventV1 {
    Shutdown,
    BranchCreated {
        from_node: NodeId,
@@ -55,13 +60,13 @@ impl CiEvent {
        branch: &str,
        tip: Oid,
    ) -> Result<Self, CiEventError> {
-
        Ok(Self::BranchCreated {
+
        Ok(Self::V1(CiEventV1::BranchCreated {
            from_node: node,
            repo,
            branch: RefString::try_from(branch)
                .map_err(|e| CiEventError::RefString(branch.into(), e))?,
            tip,
-
        })
+
        }))
    }

    pub fn branch_updated(
@@ -73,14 +78,14 @@ impl CiEvent {
    ) -> Result<Self, CiEventError> {
        let branch =
            namespaced_branch(branch).map_err(|_| CiEventError::without_namespace2(branch))?;
-
        Ok(Self::BranchUpdated {
+
        Ok(Self::V1(CiEventV1::BranchUpdated {
            from_node: node,
            repo,
            branch: RefString::try_from(branch.clone())
                .map_err(|e| CiEventError::RefString(branch.clone(), e))?,
            tip,
            old_tip,
-
        })
+
        }))
    }

    pub fn from_node_event(event: &Event) -> Result<Vec<Self>, CiEventError> {
@@ -107,14 +112,14 @@ impl CiEvent {
                        RefUpdate::Created { name, oid } => {
                            eprintln!("created: {name:?}");
                            if let Ok(patch_id) = patch_id(name) {
-
                                CiEvent::PatchCreated {
+
                                CiEventV1::PatchCreated {
                                    from_node: *remote,
                                    repo: *rid,
                                    patch: patch_id,
                                    new_tip: *oid,
                                }
                            } else if let Ok(branch) = namespaced_branch(name) {
-
                                CiEvent::BranchCreated {
+
                                CiEventV1::BranchCreated {
                                    from_node: *remote,
                                    repo: *rid,
                                    branch: ref_string(branch)?,
@@ -129,7 +134,7 @@ impl CiEvent {
                            eprintln!("updated: {name:?}");
                            if let Ok(patch_id) = patch_id(name) {
                                eprintln!("it's a patch");
-
                                CiEvent::PatchUpdated {
+
                                CiEventV1::PatchUpdated {
                                    from_node: *remote,
                                    repo: *rid,
                                    patch: patch_id,
@@ -137,7 +142,7 @@ impl CiEvent {
                                }
                            } else if let Ok(branch) = namespaced_branch(name) {
                                eprintln!("it's a branch update");
-
                                CiEvent::BranchUpdated {
+
                                CiEventV1::BranchUpdated {
                                    from_node: *remote,
                                    repo: *rid,
                                    branch: ref_string(branch)?,
@@ -149,14 +154,14 @@ impl CiEvent {
                                continue;
                            }
                        }
-
                        RefUpdate::Deleted { name, oid } => CiEvent::BranchDeleted {
+
                        RefUpdate::Deleted { name, oid } => CiEventV1::BranchDeleted {
                            repo: *rid,
                            branch: branch(name, update)?,
                            tip: *oid,
                        },
                        RefUpdate::Skipped { .. } => continue,
                    };
-
                    events.push(e);
+
                    events.push(CiEvent::V1(e));
                }
                Ok(events)
            }
@@ -325,12 +330,12 @@ mod test {
            Ok(events) if !events.is_empty() => {
                for e in events {
                    match e {
-
                        CiEvent::BranchCreated {
+
                        CiEvent::V1(CiEventV1::BranchCreated {
                            from_node: _,
                            repo,
                            branch,
                            tip,
-
                        } if repo == rid && branch == main && tip == oid => {}
+
                        }) if repo == rid && branch == main && tip == oid => {}
                        _ => panic!("should not succeed that way"),
                    }
                }
@@ -360,13 +365,13 @@ mod test {
            Ok(events) if !events.is_empty() => {
                for e in events {
                    match e {
-
                        CiEvent::BranchUpdated {
+
                        CiEvent::V1(CiEventV1::BranchUpdated {
                            from_node: _,
                            repo,
                            branch,
                            tip,
                            old_tip,
-
                        } if repo == rid && branch == main && tip == oid && old_tip == oid => {}
+
                        }) if repo == rid && branch == main && tip == oid && old_tip == oid => {}
                        _ => panic!("should not succeed that way"),
                    }
                }
@@ -395,7 +400,7 @@ mod test {
            Ok(events) if !events.is_empty() => {
                for e in events {
                    match e {
-
                        CiEvent::BranchDeleted { repo, branch, tip }
+
                        CiEvent::V1(CiEventV1::BranchDeleted { repo, branch, tip })
                            if repo == rid && branch == main && tip == oid => {}
                        _ => panic!("should not succeed that way"),
                    }
@@ -425,12 +430,12 @@ mod test {
            Ok(events) if !events.is_empty() => {
                for e in events {
                    match e {
-
                        CiEvent::PatchCreated {
+
                        CiEvent::V1(CiEventV1::PatchCreated {
                            from_node: _,
                            repo,
                            patch,
                            new_tip,
-
                        } if repo == rid && patch == patch_id && new_tip == oid => {}
+
                        }) if repo == rid && patch == patch_id && new_tip == oid => {}
                        _ => panic!("should not succeed that way"),
                    }
                }
@@ -460,12 +465,12 @@ mod test {
            Ok(events) if !events.is_empty() => {
                for e in events {
                    match e {
-
                        CiEvent::PatchUpdated {
+
                        CiEvent::V1(CiEventV1::PatchUpdated {
                            from_node: _,
                            repo,
                            patch,
                            new_tip,
-
                        } if repo == rid && patch == patch_id && new_tip == oid => {}
+
                        }) if repo == rid && patch == patch_id && new_tip == oid => {}
                        _ => panic!("should not succeed that way"),
                    }
                }
modified src/filter.rs
@@ -5,7 +5,10 @@ use serde::{Deserialize, Serialize};
use radicle::{cob::patch::PatchId, git::RefString, prelude::RepoId};
use radicle_git_ext::Oid;

-
use crate::{ci_event::CiEvent, logger};
+
use crate::{
+
    ci_event::{CiEvent, CiEventV1},
+
    logger,
+
};

/// A Boolean expression for filtering broker events.
#[derive(Debug, Clone, Deserialize, Serialize)]
@@ -64,32 +67,32 @@ impl EventFilter {
        }

        match event {
-
            CiEvent::Shutdown => true,
-
            CiEvent::BranchCreated { repo, branch, .. } => match self {
+
            CiEvent::V1(CiEventV1::Shutdown) => true,
+
            CiEvent::V1(CiEventV1::BranchCreated { repo, branch, .. }) => match self {
                Self::Repository(wanted) => repo == wanted,
                Self::Branch(wanted) => branch == wanted,
                Self::BranchCreated => true,
                _ => false,
            },
-
            CiEvent::BranchUpdated { repo, branch, .. } => match self {
+
            CiEvent::V1(CiEventV1::BranchUpdated { repo, branch, .. }) => match self {
                Self::Repository(wanted) => repo == wanted,
                Self::Branch(wanted) => branch == wanted,
                Self::BranchUpdated => true,
                _ => false,
            },
-
            CiEvent::BranchDeleted { repo, branch, .. } => match self {
+
            CiEvent::V1(CiEventV1::BranchDeleted { repo, branch, .. }) => match self {
                Self::Repository(wanted) => repo == wanted,
                Self::Branch(wanted) => branch == wanted,
                Self::BranchDeleted => true,
                _ => false,
            },
-
            CiEvent::PatchCreated { repo, patch, .. } => match self {
+
            CiEvent::V1(CiEventV1::PatchCreated { repo, patch, .. }) => match self {
                Self::Repository(wanted) => repo == wanted,
                Self::Patch(wanted) => *patch == PatchId::from(wanted),
                Self::PatchCreated => true,
                _ => false,
            },
-
            CiEvent::PatchUpdated { repo, patch, .. } => match self {
+
            CiEvent::V1(CiEventV1::PatchUpdated { repo, patch, .. }) => match self {
                Self::Repository(wanted) => repo == wanted,
                Self::Patch(wanted) => *patch == PatchId::from(wanted),
                Self::PatchUpdated => true,
@@ -166,7 +169,7 @@ mod test {
    }

    fn shutdown() -> CiEvent {
-
        CiEvent::Shutdown
+
        CiEvent::V1(CiEventV1::Shutdown)
    }

    fn all_events(
@@ -178,32 +181,32 @@ mod test {
        old_tip: Oid,
    ) -> Vec<CiEvent> {
        vec![
-
            CiEvent::BranchCreated {
+
            CiEvent::V1(CiEventV1::BranchCreated {
                from_node: did.into(),
                repo,
                branch: branch.clone(),
                tip,
-
            },
-
            CiEvent::BranchUpdated {
+
            }),
+
            CiEvent::V1(CiEventV1::BranchUpdated {
                from_node: did.into(),
                repo,
                branch: branch.clone(),
                tip,
                old_tip,
-
            },
-
            CiEvent::BranchDeleted { repo, branch, tip },
-
            CiEvent::PatchCreated {
+
            }),
+
            CiEvent::V1(CiEventV1::BranchDeleted { repo, branch, tip }),
+
            CiEvent::V1(CiEventV1::PatchCreated {
                from_node: did.into(),
                repo,
                patch,
                new_tip: tip,
-
            },
-
            CiEvent::PatchUpdated {
+
            }),
+
            CiEvent::V1(CiEventV1::PatchUpdated {
                from_node: did.into(),
                repo,
                patch,
                new_tip: tip,
-
            },
+
            }),
        ]
    }

@@ -248,9 +251,9 @@ mod test {
        for e in events.iter().filter(|e| {
            matches!(
                e,
-
                CiEvent::BranchCreated { .. }
-
                    | CiEvent::BranchUpdated { .. }
-
                    | CiEvent::BranchDeleted { .. }
+
                CiEvent::V1(CiEventV1::BranchCreated { .. })
+
                    | CiEvent::V1(CiEventV1::BranchUpdated { .. })
+
                    | CiEvent::V1(CiEventV1::BranchDeleted { .. })
            )
        }) {
            eprintln!("{:#?} → {}", e, filter.allows(e));
@@ -283,7 +286,7 @@ mod test {
        eprintln!("filter: {filter:#?}");
        for e in all_events(did(), rid(), refstring("main"), patch_id(), oid(), oid())
            .iter()
-
            .filter(|e| matches!(e, CiEvent::BranchCreated { .. }))
+
            .filter(|e| matches!(e, CiEvent::V1(CiEventV1::BranchCreated { .. })))
        {
            eprintln!("{:#?} → {}", e, filter.allows(e));
            assert!(filter.allows(e));
@@ -297,7 +300,7 @@ mod test {
        eprintln!("filter: {filter:#?}");
        for e in all_events(did(), rid(), refstring("main"), patch_id(), oid(), oid())
            .iter()
-
            .filter(|e| !matches!(e, CiEvent::BranchCreated { .. }))
+
            .filter(|e| !matches!(e, CiEvent::V1(CiEventV1::BranchCreated { .. })))
        {
            eprintln!("{:#?} → {}", e, filter.allows(e));
            assert!(!filter.allows(e));
@@ -311,7 +314,7 @@ mod test {
        eprintln!("filter: {filter:#?}");
        for e in all_events(did(), rid(), refstring("main"), patch_id(), oid(), oid())
            .iter()
-
            .filter(|e| matches!(e, CiEvent::BranchUpdated { .. }))
+
            .filter(|e| matches!(e, CiEvent::V1(CiEventV1::BranchUpdated { .. })))
        {
            eprintln!("{:#?} → {}", e, filter.allows(e));
            assert!(filter.allows(e));
@@ -325,7 +328,7 @@ mod test {
        eprintln!("filter: {filter:#?}");
        for e in all_events(did(), rid(), refstring("main"), patch_id(), oid(), oid())
            .iter()
-
            .filter(|e| !matches!(e, CiEvent::BranchUpdated { .. }))
+
            .filter(|e| !matches!(e, CiEvent::V1(CiEventV1::BranchUpdated { .. })))
        {
            eprintln!("{:#?} → {}", e, filter.allows(e));
            assert!(!filter.allows(e));
@@ -339,7 +342,7 @@ mod test {
        eprintln!("filter: {filter:#?}");
        for e in all_events(did(), rid(), refstring("main"), patch_id(), oid(), oid())
            .iter()
-
            .filter(|e| matches!(e, CiEvent::BranchDeleted { .. }))
+
            .filter(|e| matches!(e, CiEvent::V1(CiEventV1::BranchDeleted { .. })))
        {
            eprintln!("{:#?} → {}", e, filter.allows(e));
            assert!(filter.allows(e));
@@ -353,7 +356,7 @@ mod test {
        eprintln!("filter: {filter:#?}");
        for e in all_events(did(), rid(), refstring("main"), patch_id(), oid(), oid())
            .iter()
-
            .filter(|e| !matches!(e, CiEvent::BranchDeleted { .. }))
+
            .filter(|e| !matches!(e, CiEvent::V1(CiEventV1::BranchDeleted { .. })))
        {
            eprintln!("{:#?} → {}", e, filter.allows(e));
            assert!(!filter.allows(e));
@@ -368,7 +371,8 @@ mod test {
        for e in events.iter().filter(|e| {
            matches!(
                e,
-
                CiEvent::PatchCreated { .. } | CiEvent::PatchUpdated { .. }
+
                CiEvent::V1(CiEventV1::PatchCreated { .. })
+
                    | CiEvent::V1(CiEventV1::PatchUpdated { .. })
            )
        }) {
            eprintln!("{:#?} → {}", e, filter.allows(e));
@@ -391,7 +395,8 @@ mod test {
        for e in events.iter().filter(|e| {
            matches!(
                e,
-
                CiEvent::PatchCreated { .. } | CiEvent::PatchUpdated { .. }
+
                CiEvent::V1(CiEventV1::PatchCreated { .. })
+
                    | CiEvent::V1(CiEventV1::PatchUpdated { .. })
            )
        }) {
            eprintln!("{:#?} → {}", e, filter.allows(e));
@@ -406,7 +411,7 @@ mod test {
        eprintln!("filter: {filter:#?}");
        for e in all_events(did(), rid(), refstring("main"), patch_id(), oid(), oid())
            .iter()
-
            .filter(|e| matches!(e, CiEvent::PatchCreated { .. }))
+
            .filter(|e| matches!(e, CiEvent::V1(CiEventV1::PatchCreated { .. })))
        {
            eprintln!("{:#?} → {}", e, filter.allows(e));
            assert!(filter.allows(e));
@@ -420,7 +425,7 @@ mod test {
        eprintln!("filter: {filter:#?}");
        for e in all_events(did(), rid(), refstring("main"), patch_id(), oid(), oid())
            .iter()
-
            .filter(|e| !matches!(e, CiEvent::PatchCreated { .. }))
+
            .filter(|e| !matches!(e, CiEvent::V1(CiEventV1::PatchCreated { .. })))
        {
            eprintln!("{:#?} → {}", e, filter.allows(e));
            assert!(!filter.allows(e));
@@ -434,7 +439,7 @@ mod test {
        eprintln!("filter: {filter:#?}");
        for e in all_events(did(), rid(), refstring("main"), patch_id(), oid(), oid())
            .iter()
-
            .filter(|e| matches!(e, CiEvent::PatchUpdated { .. }))
+
            .filter(|e| matches!(e, CiEvent::V1(CiEventV1::PatchUpdated { .. })))
        {
            eprintln!("{:#?} → {}", e, filter.allows(e));
            assert!(filter.allows(e));
@@ -448,7 +453,7 @@ mod test {
        eprintln!("filter: {filter:#?}");
        for e in all_events(did(), rid(), refstring("main"), patch_id(), oid(), oid())
            .iter()
-
            .filter(|e| !matches!(e, CiEvent::PatchUpdated { .. }))
+
            .filter(|e| !matches!(e, CiEvent::V1(CiEventV1::PatchUpdated { .. })))
        {
            eprintln!("{:#?} → {}", e, filter.allows(e));
            assert!(!filter.allows(e));
modified src/msg.rs
@@ -31,7 +31,7 @@ use radicle::{
    Profile,
};

-
use crate::ci_event::CiEvent;
+
use crate::ci_event::{CiEvent, CiEventV1};

// This gets put into every [`Request`] message so the adapter can
// detect its getting a message it knows how to handle.
@@ -132,12 +132,12 @@ impl<'a> RequestBuilder<'a> {

        match self.ci_event {
            None => Err(MessageError::CiEventNotSet),
-
            Some(CiEvent::BranchCreated {
+
            Some(CiEvent::V1(CiEventV1::BranchCreated {
                from_node,
                repo,
                branch,
                tip,
-
            }) => {
+
            })) => {
                let rad_repo = profile.storage.repository(*repo)?;
                let project_info = rad_repo.project()?;

@@ -170,13 +170,13 @@ impl<'a> RequestBuilder<'a> {
                    patch: None,
                })
            }
-
            Some(CiEvent::BranchUpdated {
+
            Some(CiEvent::V1(CiEventV1::BranchUpdated {
                from_node,
                repo,
                branch,
                tip,
                old_tip,
-
            }) => {
+
            })) => {
                let rad_repo = profile.storage.repository(*repo)?;
                let git_repo =
                    radicle_surf::Repository::open(paths::repository(&profile.storage, repo))?;
@@ -227,12 +227,12 @@ impl<'a> RequestBuilder<'a> {
                    patch: None,
                })
            }
-
            Some(CiEvent::PatchCreated {
+
            Some(CiEvent::V1(CiEventV1::PatchCreated {
                from_node,
                repo,
                patch: patch_id,
                new_tip,
-
            }) => {
+
            })) => {
                let rad_repo = profile.storage.repository(*repo)?;
                let git_repo =
                    radicle_surf::Repository::open(paths::repository(&profile.storage, repo))?;
@@ -317,12 +317,12 @@ impl<'a> RequestBuilder<'a> {
                    }),
                })
            }
-
            Some(CiEvent::PatchUpdated {
+
            Some(CiEvent::V1(CiEventV1::PatchUpdated {
                from_node,
                repo,
                patch: patch_id,
                new_tip,
-
            }) => {
+
            })) => {
                let rad_repo = profile.storage.repository(*repo)?;
                let git_repo =
                    radicle_surf::Repository::open(paths::repository(&profile.storage, repo))?;
@@ -908,7 +908,7 @@ pub enum MessageError {
#[cfg(test)]
#[allow(clippy::unwrap_used)] // OK in tests: panic is fine
pub mod trigger_from_ci_event_tests {
-
    use crate::ci_event::CiEvent;
+
    use crate::ci_event::{CiEvent, CiEventV1};
    use crate::msg::{EventType, Request, RequestBuilder};
    use radicle::git::RefString;
    use radicle::patch::{MergeTarget, Patches};
@@ -930,14 +930,14 @@ pub mod trigger_from_ci_event_tests {
            &project.backend,
        );

-
        let ci_event = CiEvent::BranchCreated {
+
        let ci_event = CiEvent::V1(CiEventV1::BranchCreated {
            from_node: *profile.id(),
            repo: project.id,
            branch: RefString::try_from(
                "refs/namespaces/$nid/refs/heads/master".replace("$nid", &profile.id().to_string()),
            )?,
            tip: cmt,
-
        };
+
        });

        let req = RequestBuilder::default()
            .profile(&profile)
@@ -981,7 +981,7 @@ pub mod trigger_from_ci_event_tests {
            &project.backend,
        );

-
        let ci_event = CiEvent::BranchUpdated {
+
        let ci_event = CiEvent::V1(CiEventV1::BranchUpdated {
            from_node: *profile.id(),
            repo: project.id,
            branch: RefString::try_from(
@@ -989,7 +989,7 @@ pub mod trigger_from_ci_event_tests {
            )?,
            old_tip: repo_head,
            tip: cmt,
-
        };
+
        });

        let req = RequestBuilder::default()
            .profile(&profile)
@@ -1048,12 +1048,12 @@ pub mod trigger_from_ci_event_tests {
            &node.signer,
        )?;

-
        let ci_event = CiEvent::PatchCreated {
+
        let ci_event = CiEvent::V1(CiEventV1::PatchCreated {
            from_node: *profile.id(),
            repo: project.id,
            patch: *patch_cob.id(),
            new_tip: cmt,
-
        };
+
        });

        let req = RequestBuilder::default()
            .profile(&profile)
@@ -1120,12 +1120,12 @@ pub mod trigger_from_ci_event_tests {
            &node.signer,
        )?;

-
        let ci_event = CiEvent::PatchUpdated {
+
        let ci_event = CiEvent::V1(CiEventV1::PatchUpdated {
            from_node: *profile.id(),
            repo: project.id,
            patch: *patch_cob.id(),
            new_tip: cmt,
-
        };
+
        });

        let req = RequestBuilder::default()
            .profile(&profile)
modified src/pages.rs
@@ -28,7 +28,7 @@ use radicle::{
};

use crate::{
-
    ci_event::CiEvent,
+
    ci_event::{CiEvent, CiEventV1},
    db::{Db, DbError, QueuedCiEvent},
    logger,
    msg::RunId,
@@ -179,33 +179,35 @@ impl PageData {
            }

            let event_element = match event.event() {
-
                CiEvent::Shutdown => Element::new(Tag::Span).with_text("shutdown"),
-
                CiEvent::BranchCreated {
+
                CiEvent::V1(CiEventV1::Shutdown) => Element::new(Tag::Span).with_text("shutdown"),
+
                CiEvent::V1(CiEventV1::BranchCreated {
                    from_node: _,
                    repo,
                    branch,
                    tip,
-
                } => render_event(repo, branch, tip),
-
                CiEvent::BranchUpdated {
+
                }) => render_event(repo, branch, tip),
+
                CiEvent::V1(CiEventV1::BranchUpdated {
                    from_node: _,
                    repo,
                    branch,
                    tip,
                    old_tip: _,
-
                } => render_event(repo, branch, tip),
-
                CiEvent::BranchDeleted { repo, branch, tip } => render_event(repo, branch, tip),
-
                CiEvent::PatchCreated {
+
                }) => render_event(repo, branch, tip),
+
                CiEvent::V1(CiEventV1::BranchDeleted { repo, branch, tip }) => {
+
                    render_event(repo, branch, tip)
+
                }
+
                CiEvent::V1(CiEventV1::PatchCreated {
                    from_node: _,
                    repo,
                    patch,
                    new_tip,
-
                } => render_event(repo, &patch.to_string(), new_tip),
-
                CiEvent::PatchUpdated {
+
                }) => render_event(repo, &patch.to_string(), new_tip),
+
                CiEvent::V1(CiEventV1::PatchUpdated {
                    from_node: _,
                    repo,
                    patch,
                    new_tip,
-
                } => render_event(repo, &patch.to_string(), new_tip),
+
                }) => render_event(repo, &patch.to_string(), new_tip),
            };

            table.push_child(
@@ -546,11 +548,11 @@ impl StatusPage {
                .iter()
                .filter_map(|id| match db.get_queued_ci_event(id) {
                    Ok(Some(event)) => match event.event() {
-
                        CiEvent::Shutdown => Some(Ok(event)),
-
                        CiEvent::BranchCreated { repo, .. }
-
                        | CiEvent::BranchUpdated { repo, .. }
-
                        | CiEvent::PatchCreated { repo, .. }
-
                        | CiEvent::PatchUpdated { repo, .. } => {
+
                        CiEvent::V1(CiEventV1::Shutdown) => Some(Ok(event)),
+
                        CiEvent::V1(CiEventV1::BranchCreated { repo, .. })
+
                        | CiEvent::V1(CiEventV1::BranchUpdated { repo, .. })
+
                        | CiEvent::V1(CiEventV1::PatchCreated { repo, .. })
+
                        | CiEvent::V1(CiEventV1::PatchUpdated { repo, .. }) => {
                            if Self::is_public_repo(profile, repo) {
                                Some(Ok(event))
                            } else {
modified src/queueproc.rs
@@ -12,7 +12,7 @@ use radicle::Profile;

use crate::{
    broker::{Broker, BrokerError},
-
    ci_event::CiEvent,
+
    ci_event::{CiEvent, CiEventV1},
    db::{Db, DbError, QueueId, QueuedCiEvent},
    logger,
    msg::{MessageError, RequestBuilder},
@@ -119,16 +119,16 @@ impl QueueProcessor {

    fn process_event(&mut self, event: &CiEvent) -> Result<bool, QueueError> {
        match event {
-
            CiEvent::Shutdown => {
+
            CiEvent::V1(CiEventV1::Shutdown) => {
                logger::queueproc_action_shutdown();
                Ok(true)
            }
-
            CiEvent::BranchCreated {
+
            CiEvent::V1(CiEventV1::BranchCreated {
                from_node: _,
                repo,
                branch: _,
                tip,
-
            } => {
+
            }) => {
                logger::queueproc_action_run(repo, tip);
                let trigger = RequestBuilder::default()
                    .profile(&self.profile)
@@ -140,13 +140,13 @@ impl QueueProcessor {
                    .map_err(QueueError::execute_ci)?;
                Ok(false)
            }
-
            CiEvent::BranchUpdated {
+
            CiEvent::V1(CiEventV1::BranchUpdated {
                from_node: _,
                repo,
                branch: _,
                tip,
                old_tip: _,
-
            } => {
+
            }) => {
                logger::queueproc_action_run(repo, tip);
                let trigger = RequestBuilder::default()
                    .profile(&self.profile)
modified src/test.rs
@@ -5,7 +5,7 @@ use std::{
};

use crate::adapter::Adapter;
-
use crate::ci_event::CiEvent;
+
use crate::ci_event::{CiEvent, CiEventV1};
use crate::msg::{Request, RequestBuilder};
use radicle::crypto::ssh::Keystore;
use radicle::crypto::test::signer::MockSigner;
@@ -64,14 +64,14 @@ pub fn trigger_request() -> TestResult<Request> {
    let cmt =
        radicle::test::fixtures::commit("my test commit", &[repo_head.into()], &project.backend);

-
    let ci_event = CiEvent::BranchCreated {
+
    let ci_event = CiEvent::V1(CiEventV1::BranchCreated {
        from_node: *profile.id(),
        repo: project.id,
        branch: RefString::try_from(
            "refs/namespaces/$nid/refs/heads/master".replace("$nid", &profile.id().to_string()),
        )?,
        tip: cmt,
-
    };
+
    });

    Ok(RequestBuilder::default()
        .profile(&profile)