Radish alpha
r
rad:zwTxygwuz5LDGBq255RA2CbNGrz8
Radicle CI broker
Radicle
Git
feat: log job COB problems, but do not propagate them
Lars Wirzenius committed 9 months ago
commit 022466a3565be5fae3f97352d370a08629d9e0e2
parent d3681d2
4 files changed +94 -38
modified src/adapter.rs
@@ -269,8 +269,7 @@ impl Adapter {
                        run.whence().oid(),
                        run.broker_run_id().clone(),
                        &url,
-
                    )
-
                    .ok();
+
                    );
                }
                _ => {
                    return Err(AdapterError::NotTriggered(resp));
@@ -300,8 +299,7 @@ impl Adapter {
                    match &result {
                        RunResult::Success => succeeded(repo_id, oid, run_id),
                        RunResult::Failure => failed(repo_id, oid, run_id),
-
                    }
-
                    .ok();
+
                    };
                }
                _ => {
                    return Err(AdapterError::NotFinished(resp));
modified src/broker.rs
@@ -125,7 +125,7 @@ impl Broker {
        // it. We won't do anything about a failure, as there's
        // nothing useful we can do about it, as long as we let CI
        // run, which want to do.
-
        create_job(trigger.repo(), oid).ok();
+
        create_job(trigger.repo(), oid);

        // We run the adapter, but if that fails, we just
        // log the error. The `Run` value records the
modified src/cob.rs
@@ -28,53 +28,93 @@ use crate::{logger, msg::RunId};
/// it is not necessary to keep the job id (indeed, that is not
/// returned). Separate instances of the CI broker have no way of
/// communicating the job id.
-
pub fn create_job(repo_id: RepoId, oid: Oid) -> Result<(), JobError> {
-
    let profile = profile()?;
-
    let repo = repository(&profile, repo_id)?;
-
    let signer = profile.signer().map_err(JobError::Signer)?;
-

-
    let mut jobs = jobs(&repo)?;
-
    match job_for_commit(&jobs, oid) {
-
        Err(JobError::NoJob(_)) => {
-
            let job = jobs.create(oid, &signer).map_err(JobError::CreateJob)?;
-
            announce(&profile, repo_id)?;
-
            logger::job_create(&repo_id, &oid, job.id());
-
            Ok(())
+
pub fn create_job(repo_id: RepoId, oid: Oid) {
+
    fn fallible_create(repo_id: RepoId, oid: Oid) -> Result<(), JobError> {
+
        let profile = profile()?;
+
        let repo = repository(&profile, repo_id)?;
+
        let signer = profile.signer().map_err(JobError::Signer)?;
+

+
        let mut jobs = jobs(&repo)?;
+
        match job_for_commit(&jobs, oid) {
+
            Err(JobError::NoJob(_)) => {
+
                let job = jobs.create(oid, &signer).map_err(JobError::CreateJob)?;
+
                announce(&profile, repo_id)?;
+
                logger::job_create(&repo_id, &oid, job.id());
+
                Ok(())
+
            }
+
            Err(err) => {
+
                logger::job_failure(
+
                    "failed to find job COB for Git object",
+
                    &repo_id,
+
                    &oid,
+
                    Some(&err),
+
                );
+
                Err(err)
+
            }
+
            Ok(_) => {
+
                logger::job_failure(
+
                    "job COB for Git object already exists",
+
                    &repo_id,
+
                    &oid,
+
                    None,
+
                );
+
                Err(JobError::JobExists(oid))
+
            }
        }
-
        Err(err) => Err(err),
-
        Ok(_) => Err(JobError::JobExists(oid)),
    }
+

+
    fallible_create(repo_id, oid).ok();
}

/// Create a new run for an existing job. The run id should be the one
/// assigned by the CI broker, not the one by the adapter. The log URL
/// has to be the from the adapter.
-
pub fn create_run(repo_id: RepoId, oid: Oid, run_id: RunId, url: &Url) -> Result<(), JobError> {
-
    let uuid = Uuid::from_str(run_id.as_str()).map_err(JobError::Uuid)?;
-

-
    let profile = profile()?;
-
    let repo = repository(&profile, repo_id)?;
-
    let signer = profile.signer().map_err(JobError::Signer)?;
-

-
    let mut jobs = jobs(&repo)?;
-
    let job_id = job_for_commit(&jobs, oid)?;
-
    let mut job = jobs.get_mut(&job_id).map_err(JobError::GetJobMut)?;
-
    job.run(uuid, url.clone(), &signer)
-
        .map_err(JobError::AddRun)?;
-
    announce(&profile, repo_id)?;
+
pub fn create_run(repo_id: RepoId, oid: Oid, run_id: RunId, url: &Url) {
+
    fn fallible_crate(repo_id: RepoId, oid: Oid, run_id: RunId, url: &Url) -> Result<(), JobError> {
+
        let uuid = Uuid::from_str(run_id.as_str()).map_err(JobError::Uuid)?;
+

+
        let profile = profile()?;
+
        let repo = repository(&profile, repo_id)?;
+
        let signer = profile.signer().map_err(JobError::Signer)?;
+

+
        let mut jobs = jobs(&repo)?;
+
        let job_id = job_for_commit(&jobs, oid)?;
+
        let mut job = jobs.get_mut(&job_id).map_err(JobError::GetJobMut)?;
+
        job.run(uuid, url.clone(), &signer)
+
            .map_err(JobError::AddRun)?;
+
        announce(&profile, repo_id)?;
+

+
        logger::job_run_create(job_id, uuid);
+
        Ok(())
+
    }

-
    logger::job_run_create(job_id, uuid);
-
    Ok(())
+
    if let Err(err) = fallible_crate(repo_id, oid, run_id, url) {
+
        logger::job_failure(
+
            "failed to add a run to a job COB",
+
            &repo_id,
+
            &oid,
+
            Some(&err),
+
        );
+
    }
}

/// Mark a run as having finished successfully.
-
pub fn succeeded(repo_id: RepoId, oid: Oid, run_id: RunId) -> Result<(), JobError> {
-
    finish(repo_id, oid, run_id, Reason::Succeeded)
+
pub fn succeeded(repo_id: RepoId, oid: Oid, run_id: RunId) {
+
    if let Err(err) = finish(repo_id, oid, run_id, Reason::Succeeded) {
+
        logger::job_failure(
+
            "failed to mark a run as succeeded",
+
            &repo_id,
+
            &oid,
+
            Some(&err),
+
        );
+
    }
}

/// Mark a run as having finished in failure.
-
pub fn failed(repo_id: RepoId, oid: Oid, run_id: RunId) -> Result<(), JobError> {
-
    finish(repo_id, oid, run_id, Reason::Failed)
+
pub fn failed(repo_id: RepoId, oid: Oid, run_id: RunId) {
+
    if let Err(err) = finish(repo_id, oid, run_id, Reason::Failed) {
+
        logger::job_failure("failed to mark a run as failed", &repo_id, &oid, Some(&err));
+
    }
}

fn finish(repo_id: RepoId, oid: Oid, run_id: RunId, reason: Reason) -> Result<(), JobError> {
modified src/logger.rs
@@ -135,6 +135,7 @@ enum Id {
    CibStart,

    JobCreate,
+
    JobFailure,
    JobRunCreate,
    JobRunFinished,

@@ -827,6 +828,23 @@ pub fn adapter_did_not_exit(error: TimeoutError) {
    );
}

+
pub fn job_failure(
+
    msg: &'static str,
+
    repo_id: &RepoId,
+
    oid: &Oid,
+
    error: Option<&crate::cob::JobError>,
+
) {
+
    info!(
+
        msg_id = ?Id::JobFailure,
+
        kind = %Kind::StartRun,
+
        ?repo_id,
+
        ?oid,
+
        ?error,
+
        msg,
+
        "failed to created or update job COB",
+
    );
+
}
+

pub fn job_create(repo_id: &RepoId, oid: &Oid, job_id: &JobId) {
    debug!(
        msg_id = ?Id::JobCreate,