1use crate::{Client, Requestable, Result};
2use async_trait::async_trait;
3use serde::Deserialize;
4
5#[derive(Debug, Deserialize)]
6pub struct PipelineError {
7 pub kind: PipelineErrorKind,
8 pub message: String,
9}
10
11#[derive(Debug, Deserialize)]
12pub enum PipelineErrorKind {
13 Config,
14 ConfigFetch,
15 Timeout,
16 Permission,
17 Other,
18 Plan,
19}
20
21#[derive(Debug, Deserialize)]
22#[serde(rename_all = "snake_case")]
23pub enum PipelineState {
24 Created,
25 Errored,
26 SetupPending,
27 Setup,
28 Pending,
29}
30
31#[derive(Debug, Deserialize)]
32pub struct Commit {
33 pub subject: Option<String>,
34 pub body: Option<String>,
35}
36
37#[derive(Debug, Deserialize)]
38pub struct PipelineVCS {
39 pub provider_name: String,
40 pub target_repository_url: String,
41 pub origin_repository_url: String,
42 pub revision: String,
43 pub branch: Option<String>,
44 pub review_id: Option<String>,
45 pub review_url: Option<String>,
46 pub tag: Option<String>,
47 pub commit: Option<Commit>,
48}
49
50#[derive(Debug, Deserialize)]
51pub struct CiPipeline {
52 pub created_at: String,
53 pub errors: Vec<PipelineError>,
54 pub id: String,
55 pub number: i64,
56 pub project_slug: String,
57 pub state: PipelineState,
58 pub updated_at: Option<String>,
59 pub vcs: Option<PipelineVCS>,
60}
61
62#[derive(Debug, Default, Deserialize)]
63pub struct PipelineListResponse {
64 pub items: Vec<CiPipeline>,
65 pub next_page_token: Option<String>,
66}
67
68#[derive(Debug, Default, Deserialize)]
69pub struct PipelineListRequest {
70 pub org_slug: String,
71 pub page_token: Option<String>,
72 pub mine: bool,
73}
74
75impl Requestable for PipelineListRequest {
76 fn path(&self, base: &str) -> String {
77 format!("{}/pipeline", base)
78 }
79
80 fn query_params(&self) -> Vec<(&str, &str)> {
81 let mut out = vec![("org-slug", self.org_slug.as_str())];
82
83 if let Some(p) = &self.page_token {
84 out.push(("page-token", p.as_str()))
85 }
86
87 if self.mine {
88 out.push(("mine", "true"))
89 }
90
91 out
92 }
93}
94
95#[derive(Debug, Deserialize)]
96#[serde(rename_all = "snake_case")]
97pub enum WorkflowStatus {
98 Success,
99 Running,
100 NotRun,
101 Failed,
102 Error,
103 Failing,
104 OnHold,
105 Canceled,
106 Unauthorized,
107}
108
109#[derive(Debug, Deserialize)]
110pub struct Workflow {
111 pub pipeline_id: String,
112 pub canceled_by: Option<String>,
113 pub id: String,
114 pub name: String,
115 pub project_slug: String,
116 pub errored_by: Option<String>,
117 pub tag: Option<String>,
118 pub status: WorkflowStatus,
119 pub started_by: String,
120 pub pipeline_number: i64,
121 pub created_at: String,
122 pub stopped_at: String,
123}
124
125#[derive(Debug, Default, Deserialize)]
126pub struct WorkflowListResponse {
127 pub items: Vec<Workflow>,
128 pub next_page_token: Option<String>,
129}
130
131#[derive(Debug, Default, Deserialize)]
132pub struct WorkflowListRequest {
133 pub pipeline_id: String,
134 pub page_token: Option<String>,
135}
136
137impl Requestable for WorkflowListRequest {
138 fn path(&self, base: &str) -> String {
139 format!("{}/pipeline/{}/workflow", base, self.pipeline_id)
140 }
141
142 fn query_params(&self) -> Vec<(&str, &str)> {
143 let mut out = vec![];
144
145 if let Some(p) = &self.page_token {
146 out.push(("page-token", p.as_str()))
147 }
148
149 out
150 }
151}
152
153#[async_trait]
154pub trait Pipeline {
155 async fn list_pipelines(
160 &self,
161 params: PipelineListRequest,
162 ) -> Result<PipelineListResponse>;
163
164 async fn list_workflows_by_pipeline_id(
168 &self,
169 params: WorkflowListRequest,
170 ) -> Result<WorkflowListResponse>;
171}
172
173#[async_trait]
174impl Pipeline for Client {
175 async fn list_pipelines(
180 &self,
181 params: PipelineListRequest,
182 ) -> Result<PipelineListResponse> {
183 Ok(self.get(¶ms).await?.json().await?)
184 }
185
186 async fn list_workflows_by_pipeline_id(
190 &self,
191 params: WorkflowListRequest,
192 ) -> Result<WorkflowListResponse> {
193 Ok(self.get(¶ms).await?.json().await?)
194 }
195}