mirror of
https://codeberg.org/Toasterson/solstice-ci.git
synced 2026-04-10 21:30:41 +00:00
Add step slugification and category-based NDJSON logging
- Introduce `slugify_step_name` to generate URL-friendly step name slugs. - Attach per-step categories to NDJSON logs for better traceability. - Update stdout and stderr logging with step-specific categories. Signed-off-by: Till Wegmueller <toasterson@gmail.com>
This commit is contained in:
parent
633f658639
commit
102f4a1c52
1 changed files with 37 additions and 12 deletions
|
|
@ -650,12 +650,35 @@ fn parse_workflow_for_job(kdl: &str, wanted_job: Option<&str>) -> Option<Workflo
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn slugify_step_name(name: &str) -> String {
|
||||||
|
// Lowercase, replace non-alphanumeric with '-', collapse dashes, trim.
|
||||||
|
let mut out = String::with_capacity(name.len());
|
||||||
|
let mut prev_dash = false;
|
||||||
|
for ch in name.chars() {
|
||||||
|
let c = ch.to_ascii_lowercase();
|
||||||
|
if c.is_ascii_alphanumeric() {
|
||||||
|
out.push(c);
|
||||||
|
prev_dash = false;
|
||||||
|
} else if !prev_dash {
|
||||||
|
out.push('-');
|
||||||
|
prev_dash = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// trim leading/trailing '-'
|
||||||
|
let s = out.trim_matches('-').to_string();
|
||||||
|
if s.is_empty() { "step".to_string() } else { s }
|
||||||
|
}
|
||||||
|
|
||||||
async fn run_step(workdir: &str, step: &WorkflowStep, idx: usize, total: usize) -> Result<i32> {
|
async fn run_step(workdir: &str, step: &WorkflowStep, idx: usize, total: usize) -> Result<i32> {
|
||||||
// Announce step start
|
// Derive per-step category from the step name (slugified)
|
||||||
|
let step_slug = slugify_step_name(&step.name);
|
||||||
|
let step_category = format!("step:{}", step_slug);
|
||||||
|
|
||||||
|
// Announce step start in the step-specific category
|
||||||
println!(
|
println!(
|
||||||
"{}",
|
"{}",
|
||||||
ndjson_line(
|
ndjson_line(
|
||||||
"step",
|
&step_category,
|
||||||
"info",
|
"info",
|
||||||
&format!("starting step: {}", step.name),
|
&format!("starting step: {}", step.name),
|
||||||
Some(
|
Some(
|
||||||
|
|
@ -672,14 +695,14 @@ async fn run_step(workdir: &str, step: &WorkflowStep, idx: usize, total: usize)
|
||||||
.stderr(Stdio::piped());
|
.stderr(Stdio::piped());
|
||||||
let mut child = cmd.spawn().into_diagnostic()?;
|
let mut child = cmd.spawn().into_diagnostic()?;
|
||||||
|
|
||||||
// Stream output with step fields
|
// Stream output with step fields; use per-step category for both stdout and stderr
|
||||||
let extra =
|
let extra = serde_json::json!({"step_name": step.name, "step_index": idx, "total_steps": total});
|
||||||
serde_json::json!({"step_name": step.name, "step_index": idx, "total_steps": total});
|
let step_cat_clone_out = step_category.clone();
|
||||||
|
|
||||||
if let Some(stdout) = child.stdout.take() {
|
if let Some(stdout) = child.stdout.take() {
|
||||||
let mut reader = BufReader::new(stdout);
|
let mut reader = BufReader::new(stdout);
|
||||||
let extra_out = extra.clone();
|
let extra_out = extra.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
|
let cat = step_cat_clone_out;
|
||||||
loop {
|
loop {
|
||||||
let mut buf = Vec::with_capacity(256);
|
let mut buf = Vec::with_capacity(256);
|
||||||
match reader.read_until(b'\n', &mut buf).await {
|
match reader.read_until(b'\n', &mut buf).await {
|
||||||
|
|
@ -690,14 +713,14 @@ async fn run_step(workdir: &str, step: &WorkflowStep, idx: usize, total: usize)
|
||||||
.to_string();
|
.to_string();
|
||||||
println!(
|
println!(
|
||||||
"{}",
|
"{}",
|
||||||
ndjson_line("step_run", "info", &line, Some(extra_out.clone()))
|
ndjson_line(&cat, "info", &line, Some(extra_out.clone()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"{}",
|
"{}",
|
||||||
ndjson_line(
|
ndjson_line(
|
||||||
"step_run",
|
&cat,
|
||||||
"error",
|
"error",
|
||||||
&format!("error reading stdout: {}", e),
|
&format!("error reading stdout: {}", e),
|
||||||
Some(extra_out.clone())
|
Some(extra_out.clone())
|
||||||
|
|
@ -712,7 +735,9 @@ async fn run_step(workdir: &str, step: &WorkflowStep, idx: usize, total: usize)
|
||||||
if let Some(stderr) = child.stderr.take() {
|
if let Some(stderr) = child.stderr.take() {
|
||||||
let mut reader = BufReader::new(stderr);
|
let mut reader = BufReader::new(stderr);
|
||||||
let extra_err = extra.clone();
|
let extra_err = extra.clone();
|
||||||
|
let step_cat_clone_err = step_category.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
|
let cat = step_cat_clone_err;
|
||||||
loop {
|
loop {
|
||||||
let mut buf = Vec::with_capacity(256);
|
let mut buf = Vec::with_capacity(256);
|
||||||
match reader.read_until(b'\n', &mut buf).await {
|
match reader.read_until(b'\n', &mut buf).await {
|
||||||
|
|
@ -723,14 +748,14 @@ async fn run_step(workdir: &str, step: &WorkflowStep, idx: usize, total: usize)
|
||||||
.to_string();
|
.to_string();
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"{}",
|
"{}",
|
||||||
ndjson_line("step_run", "error", &line, Some(extra_err.clone()))
|
ndjson_line(&cat, "error", &line, Some(extra_err.clone()))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"{}",
|
"{}",
|
||||||
ndjson_line(
|
ndjson_line(
|
||||||
"step_run",
|
&cat,
|
||||||
"error",
|
"error",
|
||||||
&format!("error reading stderr: {}", e),
|
&format!("error reading stderr: {}", e),
|
||||||
Some(extra_err.clone())
|
Some(extra_err.clone())
|
||||||
|
|
@ -749,7 +774,7 @@ async fn run_step(workdir: &str, step: &WorkflowStep, idx: usize, total: usize)
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"{}",
|
"{}",
|
||||||
ndjson_line(
|
ndjson_line(
|
||||||
"step",
|
&step_category,
|
||||||
"error",
|
"error",
|
||||||
&format!("step failed: {} (exit {})", step.name, code),
|
&format!("step failed: {} (exit {})", step.name, code),
|
||||||
Some(extra)
|
Some(extra)
|
||||||
|
|
@ -759,7 +784,7 @@ async fn run_step(workdir: &str, step: &WorkflowStep, idx: usize, total: usize)
|
||||||
println!(
|
println!(
|
||||||
"{}",
|
"{}",
|
||||||
ndjson_line(
|
ndjson_line(
|
||||||
"step",
|
&step_category,
|
||||||
"info",
|
"info",
|
||||||
&format!("completed step: {}", step.name),
|
&format!("completed step: {}", step.name),
|
||||||
Some(
|
Some(
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue