bitbucket_cli/api/
pipelines.rs1use anyhow::Result;
2
3use super::BitbucketClient;
4use crate::models::{Paginated, Pipeline, PipelineStep, TriggerPipelineRequest};
5
6impl BitbucketClient {
7 pub async fn list_pipelines(
9 &self,
10 workspace: &str,
11 repo_slug: &str,
12 page: Option<u32>,
13 pagelen: Option<u32>,
14 ) -> Result<Paginated<Pipeline>> {
15 let mut query = Vec::new();
16
17 query.push(("sort", "-created_on".to_string()));
19
20 if let Some(p) = page {
21 query.push(("page", p.to_string()));
22 }
23 if let Some(len) = pagelen {
24 query.push(("pagelen", len.to_string()));
25 }
26
27 let query_refs: Vec<(&str, &str)> = query.iter().map(|(k, v)| (*k, v.as_str())).collect();
28
29 let path = format!("/repositories/{}/{}/pipelines", workspace, repo_slug);
30 self.get_with_query(&path, &query_refs).await
31 }
32
33 pub async fn get_pipeline(
35 &self,
36 workspace: &str,
37 repo_slug: &str,
38 pipeline_uuid: &str,
39 ) -> Result<Pipeline> {
40 let path = format!(
41 "/repositories/{}/{}/pipelines/{}",
42 workspace, repo_slug, pipeline_uuid
43 );
44 self.get(&path).await
45 }
46
47 pub async fn trigger_pipeline(
49 &self,
50 workspace: &str,
51 repo_slug: &str,
52 request: &TriggerPipelineRequest,
53 ) -> Result<Pipeline> {
54 let path = format!("/repositories/{}/{}/pipelines", workspace, repo_slug);
55 self.post(&path, request).await
56 }
57
58 pub async fn stop_pipeline(
60 &self,
61 workspace: &str,
62 repo_slug: &str,
63 pipeline_uuid: &str,
64 ) -> Result<()> {
65 let path = format!(
66 "/repositories/{}/{}/pipelines/{}/stopPipeline",
67 workspace, repo_slug, pipeline_uuid
68 );
69 self.post_no_response(&path, &serde_json::json!({})).await
70 }
71
72 pub async fn list_pipeline_steps(
74 &self,
75 workspace: &str,
76 repo_slug: &str,
77 pipeline_uuid: &str,
78 ) -> Result<Paginated<PipelineStep>> {
79 let path = format!(
80 "/repositories/{}/{}/pipelines/{}/steps",
81 workspace, repo_slug, pipeline_uuid
82 );
83 self.get(&path).await
84 }
85
86 pub async fn get_pipeline_step(
88 &self,
89 workspace: &str,
90 repo_slug: &str,
91 pipeline_uuid: &str,
92 step_uuid: &str,
93 ) -> Result<PipelineStep> {
94 let path = format!(
95 "/repositories/{}/{}/pipelines/{}/steps/{}",
96 workspace, repo_slug, pipeline_uuid, step_uuid
97 );
98 self.get(&path).await
99 }
100
101 pub async fn get_step_log(
103 &self,
104 workspace: &str,
105 repo_slug: &str,
106 pipeline_uuid: &str,
107 step_uuid: &str,
108 ) -> Result<String> {
109 let path = format!(
110 "/repositories/{}/{}/pipelines/{}/steps/{}/log",
111 workspace, repo_slug, pipeline_uuid, step_uuid
112 );
113
114 let response = reqwest::Client::new()
115 .get(self.url(&path))
116 .header("Authorization", self.auth_header())
117 .send()
118 .await?;
119
120 if response.status().is_success() {
121 Ok(response.text().await?)
122 } else {
123 anyhow::bail!("Failed to get step log: {}", response.status())
124 }
125 }
126
127 pub async fn get_pipeline_by_build_number(
129 &self,
130 workspace: &str,
131 repo_slug: &str,
132 build_number: u64,
133 ) -> Result<Pipeline> {
134 let pipelines = self
136 .list_pipelines(workspace, repo_slug, Some(1), Some(100))
137 .await?;
138
139 pipelines
140 .values
141 .into_iter()
142 .find(|p| p.build_number == build_number)
143 .ok_or_else(|| anyhow::anyhow!("Pipeline #{} not found", build_number))
144 }
145}