1pub mod yaml;
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
6#[serde(rename_all = "snake_case")]
7pub enum JobStatus {
8 Queued,
9 Running,
10 Success,
11 Failure,
12 Skipped,
13 Cancelled,
14}
15
16#[derive(Clone, Debug, Serialize, Deserialize)]
17pub struct Job {
18 pub id: String,
19 pub name: String,
20 pub status: JobStatus,
21 pub command: String,
22 pub duration_secs: Option<u64>,
23 #[serde(default)]
25 pub started_at: Option<f64>,
26 pub depends_on: Vec<String>,
27 pub output: Option<String>,
28 #[serde(default)]
30 pub required_labels: Vec<String>,
31 #[serde(default)]
33 pub max_retries: u32,
34 #[serde(default)]
36 pub attempt: u32,
37}
38
39#[derive(Clone, Debug, Serialize, Deserialize)]
40pub struct Workflow {
41 pub id: String,
42 pub name: String,
43 pub trigger: String,
44 pub jobs: Vec<Job>,
45}
46
47impl Workflow {
48 pub fn sample() -> Self {
50 Workflow {
51 id: "ci-1".into(),
52 name: "ci.yml".into(),
53 trigger: "on: push".into(),
54 jobs: vec![
55 Job {
56 id: "unit-tests".into(),
57 name: "Unit Tests".into(),
58 status: JobStatus::Queued,
59 command: "echo 'Running unit tests' && sleep 2".into(),
60 duration_secs: None,
61 depends_on: vec![],
62 started_at: None,
63 output: None,
64 required_labels: vec![],
65 max_retries: 0,
66 attempt: 0,
67 },
68 Job {
69 id: "lint".into(),
70 name: "Lint".into(),
71 status: JobStatus::Queued,
72 command: "echo 'Running linter' && sleep 1".into(),
73 duration_secs: None,
74 depends_on: vec![],
75 started_at: None,
76 output: None,
77 required_labels: vec![],
78 max_retries: 0,
79 attempt: 0,
80 },
81 Job {
82 id: "typecheck".into(),
83 name: "Typecheck".into(),
84 status: JobStatus::Queued,
85 command: "echo 'Running typecheck' && sleep 2".into(),
86 duration_secs: None,
87 depends_on: vec![],
88 started_at: None,
89 output: None,
90 required_labels: vec![],
91 max_retries: 0,
92 attempt: 0,
93 },
94 Job {
95 id: "build".into(),
96 name: "Build".into(),
97 status: JobStatus::Queued,
98 command: "echo 'Building project' && sleep 3".into(),
99 duration_secs: None,
100 depends_on: vec!["unit-tests".into(), "lint".into(), "typecheck".into()],
101 started_at: None,
102 output: None,
103 required_labels: vec![],
104 max_retries: 0,
105 attempt: 0,
106 },
107 Job {
108 id: "deploy-db".into(),
109 name: "Deploy DB Migrations".into(),
110 status: JobStatus::Queued,
111 command: "echo 'Deploying DB migrations' && sleep 1".into(),
112 duration_secs: None,
113 depends_on: vec!["build".into()],
114 started_at: None,
115 output: None,
116 required_labels: vec![],
117 max_retries: 0,
118 attempt: 0,
119 },
120 Job {
121 id: "e2e-tests".into(),
122 name: "E2E Tests".into(),
123 status: JobStatus::Queued,
124 command: "echo 'Running E2E tests' && sleep 5".into(),
125 duration_secs: None,
126 depends_on: vec!["build".into()],
127 started_at: None,
128 output: None,
129 required_labels: vec![],
130 max_retries: 0,
131 attempt: 0,
132 },
133 Job {
134 id: "deploy-preview".into(),
135 name: "Deploy Preview".into(),
136 status: JobStatus::Queued,
137 command: "echo 'Deploying preview' && sleep 1".into(),
138 duration_secs: None,
139 depends_on: vec!["build".into()],
140 started_at: None,
141 output: None,
142 required_labels: vec![],
143 max_retries: 0,
144 attempt: 0,
145 },
146 Job {
147 id: "deploy-web".into(),
148 name: "Deploy Web".into(),
149 status: JobStatus::Queued,
150 command: "echo 'Deploying to production' && sleep 3".into(),
151 duration_secs: None,
152 depends_on: vec!["deploy-db".into()],
153 started_at: None,
154 output: None,
155 required_labels: vec![],
156 max_retries: 0,
157 attempt: 0,
158 },
159 ],
160 }
161 }
162}