josh_github_graphql/operations/
pull_request.rs1use crate::connection::GithubApiConnection;
2use anyhow::anyhow;
3
4use josh_github_codegen_graphql::{
5 close_pull_request, convert_pull_request_to_draft, create_pull_request, get_pr_by_head,
6 mark_pull_request_ready_for_review, update_pull_request, ClosePullRequest,
7 ConvertPullRequestToDraft, CreatePullRequest, GetPrByHead, MarkPullRequestReadyForReview,
8 UpdatePullRequest,
9};
10
11impl GithubApiConnection {
12 pub async fn find_pull_request_by_head(
14 &self,
15 owner: &str,
16 name: &str,
17 head_ref_name: &str,
18 ) -> anyhow::Result<Option<(String, i64, bool)>> {
19 let variables = get_pr_by_head::Variables {
20 owner: owner.to_string(),
21 name: name.to_string(),
22 head_ref_name: head_ref_name.to_string(),
23 };
24 let response = self.make_request::<GetPrByHead>(variables).await?;
25 let repo = match response.repository {
26 Some(r) => r,
27 None => return Ok(None),
28 };
29 let nodes = repo.pull_requests.nodes.unwrap_or_default();
30 let pr = nodes.into_iter().flatten().next();
31 Ok(pr.map(|n| (n.id, n.number, n.is_draft)))
32 }
33
34 pub async fn update_pull_request(
36 &self,
37 pull_request_id: &str,
38 title: Option<&str>,
39 body: Option<&str>,
40 base_ref_name: Option<&str>,
41 ) -> anyhow::Result<(String, i64)> {
42 let variables = update_pull_request::Variables {
43 pull_request_id: pull_request_id.to_string(),
44 title: title.map(String::from),
45 body: body.map(String::from),
46 base_ref_name: base_ref_name.map(String::from),
47 };
48 let response = self.make_request::<UpdatePullRequest>(variables).await?;
49 let response = match response.update_pull_request {
50 Some(r) => r,
51 None => return Err(anyhow!("Failed to parse response: update_pull_request")),
52 };
53 let pr = match response.pull_request {
54 Some(p) => p,
55 None => return Err(anyhow!("Failed to parse response: pull_request")),
56 };
57 Ok((pr.id, pr.number))
58 }
59
60 pub async fn convert_pull_request_to_draft(
61 &self,
62 pull_request_id: &str,
63 ) -> anyhow::Result<(String, i64, bool)> {
64 let variables = convert_pull_request_to_draft::Variables {
65 pull_request_id: pull_request_id.to_string(),
66 };
67 let response = self
68 .make_request::<ConvertPullRequestToDraft>(variables)
69 .await?;
70 let response = match response.convert_pull_request_to_draft {
71 Some(r) => r,
72 None => {
73 return Err(anyhow!(
74 "Failed to parse response: convert_pull_request_to_draft"
75 ))
76 }
77 };
78 let pr = match response.pull_request {
79 Some(p) => p,
80 None => return Err(anyhow!("Failed to parse response: pull_request")),
81 };
82 Ok((pr.id, pr.number, pr.is_draft))
83 }
84
85 pub async fn mark_pull_request_ready_for_review(
86 &self,
87 pull_request_id: &str,
88 ) -> anyhow::Result<(String, i64, bool)> {
89 let variables = mark_pull_request_ready_for_review::Variables {
90 pull_request_id: pull_request_id.to_string(),
91 };
92 let response = self
93 .make_request::<MarkPullRequestReadyForReview>(variables)
94 .await?;
95 let response = match response.mark_pull_request_ready_for_review {
96 Some(r) => r,
97 None => {
98 return Err(anyhow!(
99 "Failed to parse response: mark_pull_request_ready_for_review"
100 ))
101 }
102 };
103 let pr = match response.pull_request {
104 Some(p) => p,
105 None => return Err(anyhow!("Failed to parse response: pull_request")),
106 };
107 Ok((pr.id, pr.number, pr.is_draft))
108 }
109
110 pub async fn create_pull_request(
111 &self,
112 repository_id: &str,
113 base_branch: &str,
114 head_branch: &str,
115 title: &str,
116 body: &str,
117 draft: bool,
118 ) -> anyhow::Result<(String, i64)> {
119 let variables = create_pull_request::Variables {
120 repository_id: repository_id.to_string(),
121 base_ref_name: base_branch.into(),
122 head_ref_name: head_branch.into(),
123 title: title.to_string(),
124 body: body.to_string(),
125 draft,
126 };
127
128 let response = self.make_request::<CreatePullRequest>(variables).await?;
129 let response = match response.create_pull_request {
130 Some(response) => response,
131 None => return Err(anyhow!("Failed to parse response: create_pull_request")),
132 };
133
134 let response = match response.pull_request {
135 Some(response) => response,
136 None => return Err(anyhow!("Failed to parse response: pull_request")),
137 };
138
139 Ok((response.id, response.number))
140 }
141
142 pub async fn close_pull_request(
143 &self,
144 pull_request_node_id: &str,
146 ) -> anyhow::Result<()> {
147 let variables = close_pull_request::Variables {
148 pull_request_node_id: pull_request_node_id.to_string(),
149 };
150
151 let response = self.make_request::<ClosePullRequest>(variables).await?;
152 if response.close_pull_request.is_none() {
153 return Err(anyhow!("Failed to parse response: close_pull_request"));
154 };
155
156 Ok(())
157 }
158}