Radish alpha
r
Radicle CI broker
Radicle
Git (anonymous pull)
Log in to clone via SSH
feat: add broker run id to Run
Lars Wirzenius committed 1 year ago
commit a4a03b414af62570e1cf300030cf1a51ada01531
parent 17828919aef9596bf76c5cf9575ce7368ab6ab40
5 files changed +76 -19
modified ci-broker.md
@@ -230,7 +230,7 @@ when I run cibtool --db ci-broker.db event list
then stdout is exactly ""

when I run cibtool --db ci-broker.db run list --json
-
then stdout contains ""run_id": "xyzzy""
+
then stdout contains ""id": "xyzzy""
~~~


@@ -871,4 +871,7 @@ then stdout is exactly ""
when I run cibtool --db x.db run add --id x --repo rad:zwTxygwuz5LDGBq255RA2CbNGrz8 --alias x --url https://x/1 --branch main --commit f1815dde6ae406d8fe3cec0b96c4486766342716 --who x --finished --failure --timestamp 2024-07-09T02:00:00
when I run cibtool --db x.db run list --json
then stdout contains "rad:zwTxygwuz5LDGBq255RA2CbNGrz8"
+

+
when I run cibtool --db x.db run list --adapter-run-id abracadabra
+
then stdout is exactly ""
~~~
modified src/bin/cibtool.rs
@@ -628,7 +628,7 @@ impl AddRun {
            RunResult::Failure
        });

-
        db.push_run(run)?;
+
        db.push_run(&run)?;

        Ok(())
    }
@@ -638,6 +638,9 @@ impl AddRun {
struct ListRuns {
    #[clap(long)]
    json: bool,
+

+
    #[clap(long)]
+
    adapter_run_id: Option<RunId>,
}

impl ListRuns {
@@ -645,14 +648,19 @@ impl ListRuns {
    fn run(&self, args: &Args) -> Result<(), CibToolError> {
        let db = args.open_db()?;

+
        let runs = if let Some(wanted) = &self.adapter_run_id {
+
            db.find_runs(wanted)?
+
        } else {
+
            db.get_all_runs()?
+
        };
+

        if self.json {
-
            let runs: Vec<RunInfo> = db.get_all_runs()?.iter().map(RunInfo::from).collect();
            println!(
                "{}",
                serde_json::to_string_pretty(&runs).map_err(CibToolError::RunToJson)?
            );
        } else {
-
            for run in db.get_all_runs()? {
+
            for run in runs {
                println!(
                    "{}",
                    run.adapter_run_id()
modified src/broker.rs
@@ -129,7 +129,7 @@ impl Broker {
            run.set_adapter_run_id(RunId::default());
        }

-
        self.db.push_run(run.clone())?;
+
        self.db.push_run(&run)?;

        Ok(run)
    }
modified src/db.rs
@@ -60,7 +60,7 @@ impl Db {
        const TABLES: &[&str] = &[
            "CREATE TABLE IF NOT EXISTS counter_test (counter INT)",
            "CREATE TABLE IF NOT EXISTS event_queue (id TEXT PRIMARY KEY, timestamp TEXT, event TEXT)",
-
            "CREATE TABLE IF NOT EXISTS ci_runs (run_id TEXT PRIMARY KEY, json TEXT)",
+
            "CREATE TABLE IF NOT EXISTS ci_runs (broker_run_id TEXT PRIMARY KEY, json TEXT)",
        ];

        for table in TABLES.iter() {
@@ -294,7 +294,7 @@ impl Db {

    /// Return list of CI runs currently in the database.
    pub fn list_runs(&self) -> Result<Vec<RunId>, DbError> {
-
        let mut select = self.prepare("SELECT run_id FROM ci_runs")?;
+
        let mut select = self.prepare("SELECT broker_run_id FROM ci_runs")?;

        let mut run_ids = vec![];

@@ -304,7 +304,7 @@ impl Db {
                Ok(State::Row) => {
                    let run_id: String = select
                        .stmt
-
                        .read("run_id")
+
                        .read("broker_run_id")
                        .map_err(|e| DbError::get_run(&select.sql, e))?;
                    let run_id = RunId::from(run_id.as_str());
                    run_ids.push(run_id);
@@ -354,7 +354,7 @@ impl Db {

    /// Return a specific CI run, given is id, if one exists.
    pub fn get_run(&self, id: &RunId) -> Result<Option<Run>, DbError> {
-
        let mut select = self.prepare("SELECT json FROM ci_runs WHERE run_id = :id")?;
+
        let mut select = self.prepare("SELECT json FROM ci_runs WHERE broker_run_id = :id")?;
        select
            .stmt
            .bind((":id", id.to_string().as_str()))
@@ -387,13 +387,27 @@ impl Db {
        Ok(run)
    }

+
    /// Return a list of broker run IDs that their adapter run ID set
+
    /// to a given value.
+
    pub fn find_runs(&self, adapter_runid: &RunId) -> Result<Vec<Run>, DbError> {
+
        let runs = self
+
            .get_all_runs()?
+
            .iter()
+
            .filter(|run| run.adapter_run_id() == Some(adapter_runid))
+
            .cloned()
+
            .collect();
+

+
        Ok(runs)
+
    }
+

    /// Add a new CI run to the database, returning its id.
-
    pub fn push_run(&self, run: Run) -> Result<RunId, DbError> {
-
        let id = run.adapter_run_id().ok_or(DbError::without_id())?.clone();
+
    pub fn push_run(&self, run: &Run) -> Result<RunId, DbError> {
+
        let id = run.broker_run_id().clone();

        let json = serde_json::to_string(&run).map_err(DbError::event_to_json)?;

-
        let mut insert = self.prepare("INSERT INTO ci_runs (run_id, json) VALUES (:id, :json)")?;
+
        let mut insert =
+
            self.prepare("INSERT INTO ci_runs (broker_run_id, json) VALUES (:id, :json)")?;
        insert
            .stmt
            .bind((":id", id.to_string().as_str()))
@@ -411,6 +425,31 @@ impl Db {
        Ok(id)
    }

+
    /// Update a CI run in the database.
+
    pub fn update_run(&self, run: &Run) -> Result<(), DbError> {
+
        let id = run.broker_run_id().clone();
+

+
        let json = serde_json::to_string(&run).map_err(DbError::event_to_json)?;
+

+
        let mut update =
+
            self.prepare("UPDATE ci_runs SET json = :json WHERE broker_run_id = :id")?;
+
        update
+
            .stmt
+
            .bind((":id", id.to_string().as_str()))
+
            .map_err(|e| DbError::bind(&update.sql, e))?;
+
        update
+
            .stmt
+
            .bind((":json", json.as_str()))
+
            .map_err(|e| DbError::bind(&update.sql, e))?;
+

+
        match update.stmt.next() {
+
            Ok(_) => (),
+
            Err(e) => return Err(DbError::update_run(&update.sql, e)),
+
        }
+

+
        Ok(())
+
    }
+

    /// Remove a CI run from database, given its id. It's OK if the run is
    /// not in the database, that is just silently ignored.
    pub fn remove_run(&self, id: &RunId) -> Result<(), DbError> {
@@ -584,12 +623,12 @@ pub enum DbError {
    #[error("failed to retrieve a CI run from database")]
    GetRun(String, #[source] sqlite::Error),

-
    #[error("programming error: pushed run does not have its run ID set")]
-
    WithoutId,
-

    #[error("failed to insert a CI run into database")]
    PushRun(String, #[source] sqlite::Error),

+
    #[error("failed to update a CI run in database")]
+
    UpdateRun(String, #[source] sqlite::Error),
+

    #[error("failed to remove a CI run from database")]
    RemoveRun(String, #[source] sqlite::Error),
}
@@ -679,14 +718,14 @@ impl DbError {
        Self::GetRun(sql.into(), e)
    }

-
    fn without_id() -> Self {
-
        Self::WithoutId
-
    }
-

    fn push_run(sql: &str, e: sqlite::Error) -> Self {
        Self::PushRun(sql.into(), e)
    }

+
    fn update_run(sql: &str, e: sqlite::Error) -> Self {
+
        Self::UpdateRun(sql.into(), e)
+
    }
+

    fn remove_run(sql: &str, e: sqlite::Error) -> Self {
        Self::RemoveRun(sql.into(), e)
    }
modified src/run.rs
@@ -9,6 +9,7 @@ use crate::msg::{Revision, RunId, RunResult};

#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct Run {
+
    broker_run_id: RunId,
    adapter_run_id: Option<RunId>,
    adapter_info_url: Option<String>,
    repo_id: RepoId,
@@ -23,6 +24,7 @@ impl Run {
    /// Create a new run.
    pub fn new(repo_id: RepoId, alias: &str, whence: Whence, timestamp: String) -> Self {
        Self {
+
            broker_run_id: RunId::default(),
            adapter_run_id: None,
            adapter_info_url: None,
            repo_id,
@@ -54,6 +56,11 @@ impl Run {
        &self.whence
    }

+
    /// Return the run id assigned by the CI broker itself. This always exists.
+
    pub fn broker_run_id(&self) -> &RunId {
+
        &self.broker_run_id
+
    }
+

    /// Set the run id assigned by the adapter.
    pub fn set_adapter_run_id(&mut self, run_id: RunId) {
        assert!(self.adapter_run_id.is_none());