Skip to main content

dk_runner/workflow/
types.rs

1use serde::Deserialize;
2use std::path::PathBuf;
3use std::time::Duration;
4
5// --- TOML deserialization types ---
6
7#[derive(Debug, Clone, Deserialize)]
8#[serde(deny_unknown_fields)]
9pub struct WorkflowFile {
10    pub pipeline: PipelineConfig,
11    #[serde(default)]
12    pub stage: Vec<StageConfig>,
13}
14
15#[derive(Debug, Clone, Deserialize)]
16#[serde(deny_unknown_fields)]
17pub struct PipelineConfig {
18    pub name: String,
19    #[serde(default = "default_timeout")]
20    pub timeout: String,
21}
22
23fn default_timeout() -> String {
24    "10m".to_string()
25}
26
27#[derive(Debug, Clone, Deserialize)]
28#[serde(deny_unknown_fields)]
29pub struct StageConfig {
30    pub name: String,
31    #[serde(default)]
32    pub parallel: bool,
33    #[serde(default)]
34    pub step: Vec<StepConfig>,
35}
36
37#[derive(Debug, Clone, Deserialize)]
38#[serde(deny_unknown_fields)]
39pub struct StepConfig {
40    pub name: String,
41    #[serde(default)]
42    pub run: Option<String>,
43    #[serde(default, rename = "type")]
44    pub step_type: Option<String>,
45    #[serde(default)]
46    pub timeout: Option<String>,
47    #[serde(default)]
48    pub changeset_aware: bool,
49    #[serde(default = "default_required")]
50    pub required: bool,
51    #[serde(default)]
52    pub check: Vec<String>,
53    #[serde(default)]
54    pub prompt: Option<String>,
55}
56
57fn default_required() -> bool {
58    true
59}
60
61// --- YAML deserialization types ---
62
63#[derive(Debug, Clone, Deserialize)]
64#[serde(deny_unknown_fields)]
65pub struct YamlWorkflowFile {
66    pub pipeline: YamlPipelineConfig,
67    #[serde(default)]
68    pub stages: Vec<YamlStageConfig>,
69}
70
71#[derive(Debug, Clone, Deserialize)]
72#[serde(deny_unknown_fields)]
73pub struct YamlPipelineConfig {
74    pub name: String,
75    #[serde(default = "default_timeout")]
76    pub timeout: String,
77    #[serde(default)]
78    pub allowed_commands: Vec<String>,
79}
80
81#[derive(Debug, Clone, Deserialize)]
82#[serde(deny_unknown_fields)]
83pub struct YamlStageConfig {
84    pub name: String,
85    #[serde(default)]
86    pub parallel: bool,
87    #[serde(default)]
88    pub steps: Vec<YamlStepConfig>,
89}
90
91#[derive(Debug, Clone, Deserialize)]
92#[serde(deny_unknown_fields)]
93pub struct YamlStepConfig {
94    pub name: String,
95    #[serde(default)]
96    pub run: Option<String>,
97    #[serde(default, rename = "type")]
98    pub step_type: Option<String>,
99    #[serde(default)]
100    pub timeout: Option<String>,
101    #[serde(default)]
102    pub changeset_aware: bool,
103    #[serde(default = "default_required")]
104    pub required: bool,
105    #[serde(default)]
106    pub check: Vec<String>,
107    #[serde(default)]
108    pub prompt: Option<String>,
109}
110
111// --- Resolved types (post-parsing) ---
112
113#[derive(Debug, Clone)]
114pub struct Workflow {
115    pub name: String,
116    pub timeout: Duration,
117    pub stages: Vec<Stage>,
118    /// Per-repo command allowlist. Empty means "use default allowlist".
119    pub allowed_commands: Vec<String>,
120}
121
122#[derive(Debug, Clone)]
123pub struct Stage {
124    pub name: String,
125    pub parallel: bool,
126    pub steps: Vec<Step>,
127}
128
129#[derive(Debug, Clone)]
130pub struct Step {
131    pub name: String,
132    pub step_type: StepType,
133    pub timeout: Duration,
134    pub required: bool,
135    pub changeset_aware: bool,
136    /// Optional subdirectory to run this step in, relative to the repo root.
137    pub work_dir: Option<PathBuf>,
138}
139
140#[derive(Debug, Clone)]
141pub enum StepType {
142    Command { run: String },
143    Semantic { checks: Vec<String> },
144    AgentReview { prompt: String },
145    HumanApprove,
146}