Radish alpha
r
rad:z3qg5TKmN83afz2fj9z3fQjU8vaYE
Radicle CI adapter for native CI
Radicle
Git
always write run.yaml
Lars Wirzenius committed 2 years ago
commit 0d5f6a5492e38220367e9ba4a75153dfeb4139ee
parent 142675e
2 files changed +60 -36
modified src/main.rs
@@ -54,14 +54,30 @@ fn fallible_main() -> Result<(), NativeError> {
    let config = Config::load_via_env()?;
    let mut logfile = config.open_log()?;

-
    let result = fallible_main_inner(&config, &mut logfile);
-
    logfile.write_str("update report page\n")?;
+
    let mut builder = RunInfo::builder();
+

+
    let result = fallible_main_inner(&config, &mut logfile, &mut builder);
+
    if result.is_ok() {
+
        builder.result(RunResult::Success);
+
    } else {
+
        builder.result(RunResult::Failure);
+
    }
+
    builder.build()?.write()?;
+

+
    logfile.write(format!(
+
        "update report page in {}\n",
+
        config.state.display()
+
    ))?;
    report::build_report(&config.state)?;
    logfile.write(format!("radicle-native-ci ends: {:?}\n", result))?;
    result
}

-
fn fallible_main_inner(config: &Config, logfile: &mut LogFile) -> Result<(), NativeError> {
+
fn fallible_main_inner(
+
    config: &Config,
+
    logfile: &mut LogFile,
+
    builder: &mut RunInfoBuilder,
+
) -> Result<(), NativeError> {
    let (run_id, run_dir) = mkdir_run(config)?;
    let run_id = RunId::from(format!("{}", run_id).as_str());
    logfile.write(format!("run directory {}\n", run_dir.display()))?;
@@ -72,37 +88,32 @@ fn fallible_main_inner(config: &Config, logfile: &mut LogFile) -> Result<(), Nat

    let profile = Profile::load().map_err(NativeError::LoadProfile)?;
    let storage = profile.storage.path();
-
    logfile.write(format!("profile: {:#?}\n", profile))?;
+
    // logfile.write(format!("profile: {:#?}\n", profile))?;

    let req = read_request()?;
    logfile.write(format!("request: {:#?}\n", req))?;

-
    let mut builder = RunInfo::builder()
-
        .id(run_id.clone())
-
        .log(&config.state, run_log.clone());
+
    builder.id(run_id.clone());
+
    builder.log(&config.state, run_log.clone());
+
    builder.run_info(run_info_file.clone());

    if let Request::Trigger { repo, commit } = req {
        info!("Request to trigger CI on {}, {}", repo, commit);
-
        builder = builder.repo(repo).commit(commit);
+
        builder.repo(repo);
+
        builder.commit(commit);
        let result = run(
            run_id, storage, repo, commit, &src, logfile, &run_log, builder,
        );
-
        logfile.write(format!("CI result: {:?}\n", result))?;
        if let Err(e) = result {
            error!("CI run failed: {}", e);
+
            logfile.write(format!("CI failed: {:?}\n", e))?;
+
            builder.result(RunResult::Failure);
            return Err(e);
        }
        logfile.write_str("CI run exited zero")?;
-
        let run_info = result.unwrap();
-
        run_info.write(&run_info_file)?;
    } else {
        write_response(&Response::error("first request was not Trigger\n"))?;
-
        let run_info = RunInfo::builder()
-
            .id(run_id)
-
            .log(&config.state, run_log)
-
            .result(RunResult::Error("first request was not Trigger".into()))
-
            .build()?;
-
        run_info.write(&run_info_file)?;
+
        builder.result(RunResult::Error("first request was not Trigger".into()));
    };

    logfile.write_str("radicle-native-ci ends successfully")?;
@@ -149,8 +160,8 @@ fn run(
    src: &Path,
    log: &mut LogFile,
    run_log: &Path,
-
    builder: RunInfoBuilder,
-
) -> Result<RunInfo, NativeError> {
+
    builder: &mut RunInfoBuilder,
+
) -> Result<(), NativeError> {
    let mut run_log = LogFile::open(run_log)?;

    log.write(format!("CI run on {}, {}\n", repo, commit))?;
@@ -167,6 +178,7 @@ fn run(
    debug!("repo path: {}", repo_path.display());

    debug!("cloning repository to {}", src.display());
+
    log.write_str("clone repository\n")?;
    runcmd(
        &mut run_log,
        &[
@@ -179,12 +191,14 @@ fn run(
    )?;

    debug!("checking out commit {}", commit);
+
    log.write_str("check out commit\n")?;
    runcmd(&mut run_log, &["git", "checkout", &commit.to_string()], src)?;

    let runspec = RunSpec::from_file(&src.join(RUNSPEC_PATH))?;
    log.write(format!("CI run spec: {:#?}\n", runspec))?;

    debug!("running CI in cloned repository");
+
    log.write_str("run shell snippet in repository\n")?;
    let snippet = format!("set -xeuo pipefail\n{}", &runspec.shell);
    runcmd(&mut run_log, &["bash", "-c", &snippet], src)?;

@@ -196,9 +210,9 @@ fn run(

    std::fs::remove_dir_all(src).map_err(|e| NativeError::RemoveDir(src.into(), e))?;

-
    let info = builder.result(result).build()?;
+
    builder.result(result);

-
    Ok(info)
+
    Ok(())
}

/// Run a command in a directory.
@@ -364,6 +378,9 @@ pub struct RunInfo {
    /// Name of log file.
    log: PathBuf,

+
    /// Name of run info file.
+
    run_info: PathBuf,
+

    /// Timestamp of when the run ended (the value was created).
    /// ISO8601 format.
    timestamp: String,
@@ -374,10 +391,11 @@ impl RunInfo {
        RunInfoBuilder::default()
    }

-
    fn write(&self, filename: &Path) -> Result<(), NativeError> {
+
    fn write(&self) -> Result<(), NativeError> {
+
        info!("Writing run info to {}", self.run_info.display());
        let yaml = serde_yaml::to_string(&self).map_err(NativeError::SerializeRunInfo)?;
-
        std::fs::write(filename, yaml.as_bytes())
-
            .map_err(|e| NativeError::WriteRunInfo(filename.into(), e))?;
+
        std::fs::write(&self.run_info, yaml.as_bytes())
+
            .map_err(|e| NativeError::WriteRunInfo(self.run_info.clone(), e))?;
        Ok(())
    }
}
@@ -390,32 +408,32 @@ struct RunInfoBuilder {
    id: Option<String>,
    result: Option<RunResult>,
    log: Option<PathBuf>,
+
    run_info: Option<PathBuf>,
}

impl RunInfoBuilder {
-
    fn repo(mut self, repo: Id) -> Self {
+
    fn repo(&mut self, repo: Id) {
        self.repo = Some(repo);
-
        self
    }

-
    fn commit(mut self, commit: Oid) -> Self {
+
    fn commit(&mut self, commit: Oid) {
        self.commit = Some(commit);
-
        self
    }

-
    fn id(mut self, id: RunId) -> Self {
+
    fn id(&mut self, id: RunId) {
        self.id = Some(format!("{}", id));
-
        self
    }

-
    fn result(mut self, result: RunResult) -> Self {
+
    fn result(&mut self, result: RunResult) {
        self.result = Some(result);
-
        self
    }

-
    fn log(mut self, state: &Path, log: PathBuf) -> Self {
+
    fn log(&mut self, state: &Path, log: PathBuf) {
        self.log = Some(log.strip_prefix(state).unwrap().into());
-
        self
+
    }
+

+
    fn run_info(&mut self, filename: PathBuf) {
+
        self.run_info = Some(filename);
    }

    fn build(self) -> Result<RunInfo, NativeError> {
@@ -432,6 +450,9 @@ impl RunInfoBuilder {
                .result
                .ok_or(NativeError::MissingInfo("result".into()))?,
            log: self.log.ok_or(NativeError::MissingInfo("log".into()))?,
+
            run_info: self
+
                .run_info
+
                .ok_or(NativeError::MissingInfo("run_info".into()))?,
            timestamp: now,
        })
    }
modified test.sh
@@ -38,9 +38,12 @@ export RADICLE_NATIVE_CI_LOG=debug

python3 test.py --commit b3a9a809420c89d08460046683f33d8a5bdfdc0a >"$tmp/test-request.yaml"
expect_failure
+
find "$tmp/test.state" -type f | grep -vF /.git/

-
# echo "test.log"
-
# cat "$tmp/test.log"
+
# cat "$tmp/test.state/index.html"
+

+
echo "test.log"
+
cat "$tmp/test.log"

# echo
# echo "log.txt"