Radish alpha
r
rad:zwTxygwuz5LDGBq255RA2CbNGrz8
Radicle CI broker
Radicle
Git
fix "cibtool trigger", and Request::commit
Merged liw opened 1 year ago

cibtool trigger created a “ref changed” event without a base commit. This meant that the rest of the CI broker couldn’t construct a list of commits since the base commit, which meant it could not create a Request::Trigger message to the CI adapter. This meant that cibtool trigger was useless. Fix that by making sure the base commit is added: either the parent commit of the what is specified with --commit or that commit itself, if there is no parent commit.

Request::commit has always been fallible, but previously it has not returned a Result, and instead if anything went wrong, it panicked. Panics are not good, so change the method to return a Result instead. That’s a breaking change: callers will now have to handle the result.

2 files changed +27 -6 a3fbb6e0 17828919
modified src/bin/cibtool.rs
@@ -770,7 +770,9 @@ impl TriggerCmd {
        let name =
            RefString::try_from(name.clone()).map_err(|e| CibToolError::RefString(name, e))?;

-
        let event = BrokerEvent::new(&rid, &name, &oid, None);
+
        let base = self.lookup_commit(rid, &format!("{oid}^")).unwrap_or(oid);
+

+
        let event = BrokerEvent::new(&rid, &name, &oid, Some(base));

        let db = args.open_db()?;
        let id = db.push_queued_event(event)?;
modified src/msg.rs
@@ -264,11 +264,14 @@ impl<'a> RequestBuilder<'a> {
        before: Oid,
        after: Oid,
    ) -> Result<PushEvent, MessageError> {
-
        let push_commits: Vec<Oid> = repo
+
        let mut push_commits: Vec<Oid> = repo
            .history(after)?
            .take_while(|c| if let Ok(c) = c { c.id != before } else { false })
            .map(|r| r.map(|c| c.id))
            .collect::<Result<Vec<Oid>, _>>()?;
+
        if push_commits.is_empty() {
+
            push_commits = vec![before];
+
        }
        Ok(PushEvent {
            pusher,
            before,
@@ -315,7 +318,7 @@ impl Request {

    /// Return the commit the event concerns. In other words, the
    /// commit that CI should run against.
-
    pub fn commit(&self) -> Oid {
+
    pub fn commit(&self) -> Result<Oid, MessageError> {
        match self {
            Self::Trigger {
                common: _,
@@ -323,11 +326,19 @@ impl Request {
                patch,
            } => {
                if let Some(push) = push {
-
                    *push.commits.first().unwrap()
+
                    if let Some(oid) = push.commits.first() {
+
                        Ok(*oid)
+
                    } else {
+
                        Err(MessageError::NoCommits)
+
                    }
                } else if let Some(patch) = patch {
-
                    *patch.patch.commits.first().unwrap()
+
                    if let Some(oid) = patch.patch.commits.first() {
+
                        Ok(*oid)
+
                    } else {
+
                        Err(MessageError::NoCommits)
+
                    }
                } else {
-
                    panic!("neither push not panic: {self:#?}");
+
                    Err(MessageError::UnknownRequest)
                }
            }
        }
@@ -698,6 +709,14 @@ pub enum MessageError {
    #[error("RequestBuilder has no event handler set")]
    NoEventHandler,

+
    /// Request message lacks commits to run CI on.
+
    #[error("unacceptable request message: lacks Git commits to run CI on")]
+
    NoCommits,
+

+
    /// Request message is neither a "push" nor a "patch"
+
    #[error("unacceptable request message: neither 'push' nor 'patch'")]
+
    UnknownRequest,
+

    /// Failed to serialize a request message as JSON. This should
    /// never happen and likely indicates a programming failure.
    #[error("failed to serialize a request into JSON to a file handle")]