1+ use crate :: test_record;
12use anyhow:: { anyhow, Context } ;
23use async_trait:: async_trait;
34use bytes:: Bytes ;
@@ -30,15 +31,18 @@ impl GithubClient {
3031 . build ( )
3132 . with_context ( || format ! ( "building reqwest {}" , req_dbg) ) ?;
3233
34+ let test_capture_info = test_record:: capture_request ( & req) ;
3335 let mut resp = self . client . execute ( req. try_clone ( ) . unwrap ( ) ) . await ?;
3436 if let Some ( sleep) = Self :: needs_retry ( & resp) . await {
3537 resp = self . retry ( req, sleep, MAX_ATTEMPTS ) . await ?;
3638 }
39+ let status = resp. status ( ) ;
3740 let maybe_err = resp. error_for_status_ref ( ) . err ( ) ;
3841 let body = resp
3942 . bytes ( )
4043 . await
4144 . with_context ( || format ! ( "failed to read response body {req_dbg}" ) ) ?;
45+ test_record:: record_request ( test_capture_info, status, & body) ;
4246 if let Some ( e) = maybe_err {
4347 return Err ( anyhow:: Error :: new ( e) )
4448 . with_context ( || format ! ( "response: {}" , String :: from_utf8_lossy( & body) ) ) ;
@@ -247,7 +251,7 @@ pub struct Issue {
247251 pub number : u64 ,
248252 #[ serde( deserialize_with = "opt_string" ) ]
249253 pub body : String ,
250- created_at : chrono:: DateTime < Utc > ,
254+ pub created_at : chrono:: DateTime < Utc > ,
251255 pub updated_at : chrono:: DateTime < Utc > ,
252256 /// The SHA for a merge commit.
253257 ///
@@ -263,6 +267,7 @@ pub struct Issue {
263267 pub html_url : String ,
264268 pub user : User ,
265269 pub labels : Vec < Label > ,
270+ pub milestone : Option < Milestone > ,
266271 pub assignees : Vec < User > ,
267272 /// Indicator if this is a pull request.
268273 ///
@@ -329,6 +334,7 @@ impl ZulipGitHubReference {
329334
330335#[ derive( Debug , serde:: Deserialize ) ]
331336pub struct Comment {
337+ pub id : i64 ,
332338 #[ serde( deserialize_with = "opt_string" ) ]
333339 pub body : String ,
334340 pub html_url : String ,
@@ -475,12 +481,22 @@ impl Issue {
475481 self . state == IssueState :: Open
476482 }
477483
478- pub async fn get_comment ( & self , client : & GithubClient , id : usize ) -> anyhow:: Result < Comment > {
484+ pub async fn get_comment ( & self , client : & GithubClient , id : u64 ) -> anyhow:: Result < Comment > {
479485 let comment_url = format ! ( "{}/issues/comments/{}" , self . repository( ) . url( client) , id) ;
480486 let comment = client. json ( client. get ( & comment_url) ) . await ?;
481487 Ok ( comment)
482488 }
483489
490+ pub async fn get_comments ( & self , client : & GithubClient ) -> anyhow:: Result < Vec < Comment > > {
491+ let comment_url = format ! (
492+ "{}/issues/{}/comments" ,
493+ self . repository( ) . url( client) ,
494+ self . number
495+ ) ;
496+ let comments = client. json ( client. get ( & comment_url) ) . await ?;
497+ Ok ( comments)
498+ }
499+
484500 pub async fn edit_body ( & self , client : & GithubClient , body : & str ) -> anyhow:: Result < ( ) > {
485501 let edit_url = format ! ( "{}/issues/{}" , self . repository( ) . url( client) , self . number) ;
486502 #[ derive( serde:: Serialize ) ]
@@ -854,8 +870,8 @@ struct MilestoneCreateBody<'a> {
854870
855871#[ derive( Debug , serde:: Deserialize ) ]
856872pub struct Milestone {
857- number : u64 ,
858- title : String ,
873+ pub number : u64 ,
874+ pub title : String ,
859875}
860876
861877#[ derive( Debug , serde:: Deserialize ) ]
@@ -1064,6 +1080,15 @@ impl Repository {
10641080 || filters. iter ( ) . any ( |& ( key, _) | key == "no" )
10651081 || is_pr && !include_labels. is_empty ( ) ;
10661082
1083+ let set_is_pr = |issues : & mut [ Issue ] | {
1084+ if !is_pr {
1085+ return ;
1086+ }
1087+ for issue in issues {
1088+ issue. pull_request = Some ( PullRequestDetails { } ) ;
1089+ }
1090+ } ;
1091+
10671092 // If there are more than `per_page` of issues, we need to paginate
10681093 let mut issues = vec ! [ ] ;
10691094 loop {
@@ -1083,10 +1108,11 @@ impl Repository {
10831108
10841109 let result = client. get ( & url) ;
10851110 if use_search_api {
1086- let result = client
1111+ let mut result = client
10871112 . json :: < IssueSearchResult > ( result)
10881113 . await
10891114 . with_context ( || format ! ( "failed to list issues from {}" , url) ) ?;
1115+ set_is_pr ( & mut result. items ) ;
10901116 issues. extend ( result. items ) ;
10911117 if issues. len ( ) < result. total_count {
10921118 ordering. page += 1 ;
@@ -1097,7 +1123,8 @@ impl Repository {
10971123 issues = client
10981124 . json ( result)
10991125 . await
1100- . with_context ( || format ! ( "failed to list issues from {}" , url) ) ?
1126+ . with_context ( || format ! ( "failed to list issues from {}" , url) ) ?;
1127+ set_is_pr ( & mut issues) ;
11011128 }
11021129
11031130 break ;
@@ -1237,7 +1264,7 @@ impl Repository {
12371264 client : & GithubClient ,
12381265 refname : & str ,
12391266 sha : & str ,
1240- ) -> anyhow:: Result < ( ) > {
1267+ ) -> anyhow:: Result < GitReference > {
12411268 let url = format ! ( "{}/git/refs/{}" , self . url( client) , refname) ;
12421269 client
12431270 . json ( client. patch ( & url) . json ( & serde_json:: json!( {
@@ -1250,8 +1277,7 @@ impl Repository {
12501277 "{} failed to update reference {refname} to {sha}" ,
12511278 self . full_name
12521279 )
1253- } ) ?;
1254- Ok ( ( ) )
1280+ } )
12551281 }
12561282
12571283 /// Returns a list of recent commits on the given branch.
@@ -1511,6 +1537,16 @@ impl Repository {
15111537 } ) ?;
15121538 Ok ( ( ) )
15131539 }
1540+
1541+ pub async fn get_pr ( & self , client : & GithubClient , number : u64 ) -> anyhow:: Result < Issue > {
1542+ let url = format ! ( "{}/pulls/{number}" , self . url( client) ) ;
1543+ let mut pr: Issue = client
1544+ . json ( client. get ( & url) )
1545+ . await
1546+ . with_context ( || format ! ( "{} failed to get pr {number}" , self . full_name) ) ?;
1547+ pr. pull_request = Some ( PullRequestDetails { } ) ;
1548+ Ok ( pr)
1549+ }
15141550}
15151551
15161552pub struct Query < ' a > {
@@ -1812,12 +1848,14 @@ impl GithubClient {
18121848 let req = req
18131849 . build ( )
18141850 . with_context ( || format ! ( "failed to build request {:?}" , req_dbg) ) ?;
1851+ let test_capture_info = test_record:: capture_request ( & req) ;
18151852 let resp = self . client . execute ( req) . await . context ( req_dbg. clone ( ) ) ?;
18161853 let status = resp. status ( ) ;
18171854 let body = resp
18181855 . bytes ( )
18191856 . await
18201857 . with_context ( || format ! ( "failed to read response body {req_dbg}" ) ) ?;
1858+ test_record:: record_request ( test_capture_info, status, & body) ;
18211859 match status {
18221860 StatusCode :: OK => Ok ( Some ( body) ) ,
18231861 StatusCode :: NOT_FOUND => Ok ( None ) ,
@@ -1970,6 +2008,7 @@ pub struct GitTreeEntry {
19702008 pub sha : String ,
19712009}
19722010
2011+ #[ derive( Debug ) ]
19732012pub struct RecentCommit {
19742013 pub title : String ,
19752014 pub pr_num : Option < i32 > ,
0 commit comments