Skip to content

Commit bc11168

Browse files
authored
fix: Refactor code generation and improve TypeScript types (#1587)
* fix: Refactor code generation and improve TypeScript types * feat(core): inject environment variables for task and workflow run IDs * ci(workflows): remove Windows job from deprecated test workflow
1 parent 25e4615 commit bc11168

File tree

12 files changed

+588
-234
lines changed

12 files changed

+588
-234
lines changed

.github/workflows/deprecated-test.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ jobs:
1717
include:
1818
- os: ubuntu-latest
1919
db_required: true
20-
- os: windows-latest
21-
db_required: false
2220

2321
steps:
2422
- name: Check out Git repository

crates/cli/src/ascii_art.rs

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,43 @@
11
use console::style;
22

33
pub fn print_ascii_art() {
4-
println!("{}", style(" __ __ __ ").green());
5-
println!("{}", style(" / / /\\ \\ /\\ \\ ").green());
6-
println!("{}", style(" / / ___ ___ \\_\\ \\ __ ___ ___ ___ \\_\\ \\ ").green());
7-
println!("{}", style(" / / /'___\\ / __`\\ /'_` \\ /'__`\\ /' __` __`\\ / __`\\ /'_` \\ ").green());
4+
println!(
5+
"{}",
6+
style(" __ __ __ ")
7+
.green()
8+
);
9+
println!(
10+
"{}",
11+
style(" / / /\\ \\ /\\ \\ ")
12+
.green()
13+
);
14+
println!(
15+
"{}",
16+
style(" / / ___ ___ \\_\\ \\ __ ___ ___ ___ \\_\\ \\ ")
17+
.green()
18+
);
19+
println!(
20+
"{}",
21+
style(" / / /'___\\ / __`\\ /'_` \\ /'__`\\ /' __` __`\\ / __`\\ /'_` \\ ")
22+
.green()
23+
);
824
println!("{}", style(" / / /\\ \\__/ /\\ \\L\\ \\/\\ \\L\\ \\ /\\ __/ /\\ \\/\\ \\/\\ \\ /\\ \\L\\ \\/\\ \\L\\ \\ __ ").green());
925
println!("{}", style(" /_/ \\ \\____\\\\ \\____/\\ \\___,_\\\\ \\____\\\\ \\_\\ \\_\\ \\_\\\\ \\____/\\ \\___,_\\/\\_\\").green());
10-
println!("{}", style("/_/ \\/____/ \\/___/ \\/__,_ / \\/____/ \\/_/\\/_/\\/_/ \\/___/ \\/__,_ /\\/_/").green());
11-
println!("{}", style(" ").green());
12-
println!("{}", style(" ").green());
26+
println!(
27+
"{}",
28+
style(
29+
"/_/ \\/____/ \\/___/ \\/__,_ / \\/____/ \\/_/\\/_/\\/_/ \\/___/ \\/__,_ /\\/_/"
30+
)
31+
.green()
32+
);
33+
println!(
34+
"{}",
35+
style(" ")
36+
.green()
37+
);
38+
println!(
39+
"{}",
40+
style(" ")
41+
.green()
42+
);
1343
}

crates/cli/src/commands/login.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use anyhow::{anyhow, Result};
22
use clap::Args;
33
use log::{info, warn};
44

5-
use crate::auth::{OidcClient, TokenStorage};
65
use crate::ascii_art::print_ascii_art;
6+
use crate::auth::{OidcClient, TokenStorage};
77

88
#[derive(Args, Debug)]
99
pub struct Command {

crates/cli/src/commands/whoami.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use anyhow::{anyhow, Result};
22
use chrono::Utc;
33
use clap::Args;
44

5-
use crate::auth::{OidcClient, TokenStorage};
65
use crate::ascii_art::print_ascii_art;
6+
use crate::auth::{OidcClient, TokenStorage};
77

88
#[derive(Args, Debug)]
99
pub struct Command {
@@ -36,7 +36,7 @@ pub async fn handler(args: &Command) -> Result<()> {
3636
match oidc_client.get_auth_status()? {
3737
Some(stored_auth) => {
3838
print_ascii_art();
39-
println!("✓ Logged in to: {}", registry_url);
39+
println!("✓ Logged in to: {registry_url}");
4040
println!("Username: {}", stored_auth.user.username);
4141
println!("Email: {}", stored_auth.user.email);
4242
println!("User ID: {}", stored_auth.user.id);

crates/cli/src/main.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@ use anyhow::Result;
22
use clap::{Args, Parser, Subcommand};
33
use log::info;
44

5+
mod ascii_art;
56
mod auth;
67
mod auth_provider;
7-
mod ascii_art;
88
mod commands;
99
mod engine;
1010
mod workflow_runner;
1111
use ascii_art::print_ascii_art;
1212

1313
#[derive(Parser)]
1414
#[command(name = "codemod")]
15-
#[command(about = "A self-hostable workflow engine for code transformations", long_about = "\x1b[32m __ __ __ \x1b[0m\n\x1b[32m / / /\\ \\ /\\ \\ \x1b[0m\n\x1b[32m / / ___ ___ \\_\\ \\ __ ___ ___ ___ \\_\\ \\ \x1b[0m\n\x1b[32m / / /'___\\ / __`\\ /'_` \\ /'__`\\ /' __` __`\\ / __`\\ /'_` \\ \x1b[0m\n\x1b[32m / / /\\ \\__/ /\\ \\L\\ \\/\\ \\L\\ \\ /\\ __/ /\\ \\/\\ \\/\\ \\ /\\ \\L\\ \\/\\ \\L\\ \\ __ \x1b[0m\n\x1b[32m /_/ \\ \\____\\\\ \\____/\\ \\___,_\\\\ \\____\\\\ \\_\\ \\_\\ \\_\\\\ \\____/\\ \\___,_\\/\\_\\\x1b[0m\n\x1b[32m/_/ \\/____/ \\/___/ \\/__,_ / \\/____/ \\/_/\\/_/\\/_/ \\/___/ \\/__,_ /\\/_/\x1b[0m\n\x1b[32m \x1b[0m\n\x1b[32m \x1b[0m\n\nA self-hostable workflow engine for code transformations")]
15+
#[command(
16+
about = "A self-hostable workflow engine for code transformations",
17+
long_about = "\x1b[32m __ __ __ \x1b[0m\n\x1b[32m / / /\\ \\ /\\ \\ \x1b[0m\n\x1b[32m / / ___ ___ \\_\\ \\ __ ___ ___ ___ \\_\\ \\ \x1b[0m\n\x1b[32m / / /'___\\ / __`\\ /'_` \\ /'__`\\ /' __` __`\\ / __`\\ /'_` \\ \x1b[0m\n\x1b[32m / / /\\ \\__/ /\\ \\L\\ \\/\\ \\L\\ \\ /\\ __/ /\\ \\/\\ \\/\\ \\ /\\ \\L\\ \\/\\ \\L\\ \\ __ \x1b[0m\n\x1b[32m /_/ \\ \\____\\\\ \\____/\\ \\___,_\\\\ \\____\\\\ \\_\\ \\_\\ \\_\\\\ \\____/\\ \\___,_\\/\\_\\\x1b[0m\n\x1b[32m/_/ \\/____/ \\/___/ \\/__,_ / \\/____/ \\/_/\\/_/\\/_/ \\/___/ \\/__,_ /\\/_/\x1b[0m\n\x1b[32m \x1b[0m\n\x1b[32m \x1b[0m\n\nA self-hostable workflow engine for code transformations"
18+
)]
1619
struct Cli {
1720
#[command(subcommand)]
1821
command: Option<Commands>,

crates/core/src/engine.rs

Lines changed: 48 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -235,9 +235,42 @@ impl Engine {
235235
.collect();
236236

237237
if awaiting_tasks.is_empty() {
238-
return Err(Error::Other(format!(
239-
"No tasks in workflow run {workflow_run_id} are awaiting triggers"
240-
)));
238+
// Check if all tasks are complete
239+
let active_tasks = tasks.iter().any(|t| {
240+
matches!(
241+
t.status,
242+
TaskStatus::Pending | TaskStatus::Running | TaskStatus::AwaitingTrigger
243+
)
244+
});
245+
246+
// If no tasks are active, mark the workflow as completed
247+
if !active_tasks {
248+
let mut fields = HashMap::new();
249+
fields.insert(
250+
"status".to_string(),
251+
FieldDiff {
252+
operation: DiffOperation::Update,
253+
value: Some(serde_json::to_value(WorkflowStatus::Completed)?),
254+
},
255+
);
256+
let workflow_run_diff = WorkflowRunDiff {
257+
workflow_run_id,
258+
fields,
259+
};
260+
261+
self.state_adapter
262+
.lock()
263+
.await
264+
.apply_workflow_run_diff(&workflow_run_diff)
265+
.await?;
266+
267+
info!("Workflow run {workflow_run_id} is now complete");
268+
return Ok(());
269+
}
270+
271+
// If we reached here, it means the workflow is still running but no tasks need triggers
272+
info!("No tasks in workflow run {workflow_run_id} are awaiting triggers");
273+
return Ok(());
241274
}
242275

243276
let mut triggered = false;
@@ -273,8 +306,10 @@ impl Engine {
273306
info!("Triggered task {} ({})", task.id, task.node_id);
274307
}
275308

309+
// If no tasks were triggered, it means they're all done or in progress
310+
// We don't need to error out, just return successfully
276311
if !triggered {
277-
return Err(Error::Other("No tasks were awaiting trigger".to_string()));
312+
return Ok(());
278313
}
279314

280315
let mut fields = HashMap::new();
@@ -442,7 +477,7 @@ impl Engine {
442477
///
443478
/// Examples of cycles that will be detected:
444479
/// - Direct cycle: A → A
445-
/// - Two-step cycle: A → B → A
480+
/// - Two-step cycle: A → B → A
446481
/// - Multi-step cycle: A → B → C → A
447482
///
448483
/// # Arguments
@@ -799,58 +834,6 @@ impl Engine {
799834
});
800835
}
801836

802-
// Check for tasks that have failed dependencies and mark them as WontDo
803-
for task in &tasks_after_recompilation {
804-
if task.status != TaskStatus::Pending {
805-
continue;
806-
}
807-
808-
// Get the node for this task
809-
let node = current_workflow_run
810-
.workflow
811-
.nodes
812-
.iter()
813-
.find(|n| n.id == task.node_id);
814-
815-
if let Some(node) = node {
816-
// Check if any dependency has failed
817-
let has_failed_dependency = node.depends_on.iter().any(|dep_id| {
818-
tasks_after_recompilation
819-
.iter()
820-
.filter(|t| t.node_id == *dep_id)
821-
.any(|t| t.status == TaskStatus::Failed)
822-
});
823-
824-
if has_failed_dependency {
825-
debug!(
826-
"Marking task {} as WontDo due to failed dependency",
827-
task.id
828-
);
829-
830-
// Create a task diff to mark as WontDo
831-
let mut fields = HashMap::new();
832-
fields.insert(
833-
"status".to_string(),
834-
FieldDiff {
835-
operation: DiffOperation::Update,
836-
value: Some(serde_json::to_value(TaskStatus::WontDo)?),
837-
},
838-
);
839-
let task_diff = TaskDiff {
840-
task_id: task.id,
841-
fields,
842-
};
843-
844-
// Apply the diff
845-
self.state_adapter
846-
.lock()
847-
.await
848-
.apply_task_diff(&task_diff)
849-
.await?;
850-
}
851-
}
852-
}
853-
854837
// Wait a bit before checking again
855838
time::sleep(Duration::from_secs(1)).await;
856839
}
@@ -1714,6 +1697,14 @@ impl Engine {
17141697
.to_string(),
17151698
);
17161699

1700+
// Add task and workflow run IDs
1701+
env.insert(String::from("CODEMOD_TASK_ID"), task.id.to_string());
1702+
1703+
env.insert(
1704+
String::from("CODEMOD_WORKFLOW_RUN_ID"),
1705+
task.workflow_run_id.to_string(),
1706+
);
1707+
17171708
// Resolve variables
17181709
let resolved_command = resolve_variables(run, params, state, task.matrix_values.as_ref())?;
17191710

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy