@@ -64,6 +64,7 @@ impl Github {
6464
6565 fn start_jwt_request ( & mut self ) -> anyhow:: Result < ( ) > {
6666 self . client . reset ( ) ;
67+ self . client . useragent ( "rust-lang/promote-release" ) . unwrap ( ) ;
6768 let mut headers = curl:: easy:: List :: new ( ) ;
6869 headers. append ( & format ! ( "Authorization: Bearer {}" , self . jwt( ) ) ) ?;
6970 self . client . http_headers ( headers) ?;
@@ -81,7 +82,11 @@ impl Github {
8182 struct InstallationResponse {
8283 id : u32 ,
8384 }
84- let installation_id = send_request :: < InstallationResponse > ( & mut self . client ) ?. id ;
85+ let installation_id = self
86+ . client
87+ . without_body ( )
88+ . send_with_response :: < InstallationResponse > ( ) ?
89+ . id ;
8590
8691 self . start_jwt_request ( ) ?;
8792 self . client . post ( true ) ?;
@@ -92,7 +97,11 @@ impl Github {
9297 struct TokenResponse {
9398 token : String ,
9499 }
95- let token = send_request :: < TokenResponse > ( & mut self . client ) ?. token ;
100+ let token = self
101+ . client
102+ . without_body ( )
103+ . send_with_response :: < TokenResponse > ( ) ?
104+ . token ;
96105 Ok ( RepositoryClient {
97106 github : self ,
98107 repo : repository. to_owned ( ) ,
@@ -104,13 +113,38 @@ impl Github {
104113impl RepositoryClient < ' _ > {
105114 fn start_new_request ( & mut self ) -> anyhow:: Result < ( ) > {
106115 self . github . client . reset ( ) ;
116+ self . github . client . useragent ( "rust-lang/promote-release" ) ?;
107117 let mut headers = curl:: easy:: List :: new ( ) ;
108118 headers. append ( & format ! ( "Authorization: token {}" , self . token) ) ?;
109119 self . github . client . http_headers ( headers) ?;
110120 Ok ( ( ) )
111121 }
112122
113123 pub ( crate ) fn tag ( & mut self , tag : CreateTag < ' _ > ) -> anyhow:: Result < ( ) > {
124+ #[ derive( serde:: Serialize ) ]
125+ struct CreateTagInternal < ' a > {
126+ tag : & ' a str ,
127+ message : & ' a str ,
128+ /// sha of the object being tagged
129+ object : & ' a str ,
130+ #[ serde( rename = "type" ) ]
131+ type_ : & ' a str ,
132+ tagger : CreateTagTaggerInternal < ' a > ,
133+ }
134+
135+ #[ derive( serde:: Serialize ) ]
136+ struct CreateTagTaggerInternal < ' a > {
137+ name : & ' a str ,
138+ email : & ' a str ,
139+ }
140+
141+ #[ derive( serde:: Serialize ) ]
142+ struct CreateRefInternal < ' a > {
143+ #[ serde( rename = "ref" ) ]
144+ ref_ : & ' a str ,
145+ sha : & ' a str ,
146+ }
147+
114148 #[ derive( serde:: Deserialize ) ]
115149 struct CreatedTag {
116150 sha : String ,
@@ -121,9 +155,10 @@ impl RepositoryClient<'_> {
121155 "https://api.github.com/repos/{repository}/git/tags" ,
122156 repository = self . repo,
123157 ) ) ?;
124- let created = send_request_body :: < CreatedTag , _ > (
125- & mut self . github . client ,
126- CreateTagInternal {
158+ let created = self
159+ . github
160+ . client
161+ . with_body ( CreateTagInternal {
127162 tag : tag. tag_name ,
128163 message : tag. message ,
129164 object : tag. commit ,
@@ -132,8 +167,8 @@ impl RepositoryClient<'_> {
132167 name : tag. tagger_name ,
133168 email : tag. tagger_email ,
134169 } ,
135- } ,
136- ) ?;
170+ } )
171+ . send_with_response :: < CreatedTag > ( ) ?;
137172
138173 // This mostly exists to make sure the request is successful rather than
139174 // really checking the created ref (which we already know).
@@ -149,13 +184,34 @@ impl RepositoryClient<'_> {
149184 "https://api.github.com/repos/{repository}/git/refs" ,
150185 repository = self . repo,
151186 ) ) ?;
152- send_request_body :: < CreatedTagRef , _ > (
153- & mut self . github . client ,
154- CreateRefInternal {
187+ self . github
188+ . client
189+ . with_body ( CreateRefInternal {
155190 ref_ : & format ! ( "refs/tags/{}" , tag. tag_name) ,
156191 sha : & created. sha ,
157- } ,
158- ) ?;
192+ } )
193+ . send_with_response :: < CreatedTagRef > ( ) ?;
194+
195+ Ok ( ( ) )
196+ }
197+
198+ pub ( crate ) fn workflow_dispatch ( & mut self , workflow : & str , branch : & str ) -> anyhow:: Result < ( ) > {
199+ #[ derive( serde:: Serialize ) ]
200+ struct Request < ' a > {
201+ #[ serde( rename = "ref" ) ]
202+ ref_ : & ' a str ,
203+ }
204+ self . start_new_request ( ) ?;
205+ self . github . client . post ( true ) ?;
206+ self . github . client . url ( & format ! (
207+ "https://api.github.com/repos/{repository}/actions/workflows/{workflow}/dispatches" ,
208+ repository = self . repo,
209+ ) ) ?;
210+
211+ self . github
212+ . client
213+ . with_body ( Request { ref_ : branch } )
214+ . send ( ) ?;
159215
160216 Ok ( ( ) )
161217 }
@@ -170,66 +226,68 @@ pub(crate) struct CreateTag<'a> {
170226 pub ( crate ) tagger_email : & ' a str ,
171227}
172228
173- #[ derive( serde:: Serialize ) ]
174- struct CreateTagInternal < ' a > {
175- tag : & ' a str ,
176- message : & ' a str ,
177- /// sha of the object being tagged
178- object : & ' a str ,
179- #[ serde( rename = "type" ) ]
180- type_ : & ' a str ,
181- tagger : CreateTagTaggerInternal < ' a > ,
229+ trait BodyExt {
230+ fn with_body < S > ( & mut self , body : S ) -> Request < ' _ , S > ;
231+ fn without_body ( & mut self ) -> Request < ' _ , ( ) > ;
182232}
183233
184- #[ derive( serde:: Serialize ) ]
185- struct CreateTagTaggerInternal < ' a > {
186- name : & ' a str ,
187- email : & ' a str ,
234+ impl BodyExt for Easy {
235+ fn with_body < S > ( & mut self , body : S ) -> Request < ' _ , S > {
236+ Request {
237+ body : Some ( body) ,
238+ client : self ,
239+ }
240+ }
241+ fn without_body ( & mut self ) -> Request < ' _ , ( ) > {
242+ Request {
243+ body : None ,
244+ client : self ,
245+ }
246+ }
188247}
189248
190- #[ derive( serde:: Serialize ) ]
191- struct CreateRefInternal < ' a > {
192- #[ serde( rename = "ref" ) ]
193- ref_ : & ' a str ,
194- sha : & ' a str ,
249+ struct Request < ' a , S > {
250+ body : Option < S > ,
251+ client : & ' a mut Easy ,
195252}
196253
197- fn send_request_body < T : serde:: de:: DeserializeOwned , S : serde:: Serialize > (
198- client : & mut Easy ,
199- body : S ,
200- ) -> anyhow:: Result < T > {
201- use std:: io:: Read ;
202- client. useragent ( "rust-lang/promote-release" ) . unwrap ( ) ;
203- let mut response = Vec :: new ( ) ;
204- let body = serde_json:: to_vec ( & body) . unwrap ( ) ;
205- {
206- let mut transfer = client. transfer ( ) ;
207- let mut body = & body[ ..] ;
208- // The unwrap in the read_function is basically guaranteed to not
209- // happen: reading into a slice can't fail. We can't use `?` since the
210- // return type inside transfer isn't compatible with io::Error.
211- transfer. read_function ( move |dest| Ok ( body. read ( dest) . unwrap ( ) ) ) ?;
212- transfer. write_function ( |new_data| {
213- response. extend_from_slice ( new_data) ;
214- Ok ( new_data. len ( ) )
215- } ) ?;
216- transfer. perform ( ) ?;
254+ impl < S : serde:: Serialize > Request < ' _ , S > {
255+ fn send_with_response < T : serde:: de:: DeserializeOwned > ( self ) -> anyhow:: Result < T > {
256+ use std:: io:: Read ;
257+ let mut response = Vec :: new ( ) ;
258+ let body = self . body . map ( |body| serde_json:: to_vec ( & body) . unwrap ( ) ) ;
259+ {
260+ let mut transfer = self . client . transfer ( ) ;
261+ // The unwrap in the read_function is basically guaranteed to not
262+ // happen: reading into a slice can't fail. We can't use `?` since the
263+ // return type inside transfer isn't compatible with io::Error.
264+ if let Some ( mut body) = body. as_deref ( ) {
265+ transfer. read_function ( move |dest| Ok ( body. read ( dest) . unwrap ( ) ) ) ?;
266+ }
267+ transfer. write_function ( |new_data| {
268+ response. extend_from_slice ( new_data) ;
269+ Ok ( new_data. len ( ) )
270+ } ) ?;
271+ transfer. perform ( ) ?;
272+ }
273+ serde_json:: from_slice ( & response)
274+ . with_context ( || format ! ( "{}" , String :: from_utf8_lossy( & response) ) )
217275 }
218- serde_json:: from_slice ( & response)
219- . with_context ( || format ! ( "{}" , String :: from_utf8_lossy( & response) ) )
220- }
221276
222- fn send_request < T : serde:: de:: DeserializeOwned > ( client : & mut Easy ) -> anyhow:: Result < T > {
223- client. useragent ( "rust-lang/promote-release" ) . unwrap ( ) ;
224- let mut response = Vec :: new ( ) ;
225- {
226- let mut transfer = client. transfer ( ) ;
227- transfer. write_function ( |new_data| {
228- response. extend_from_slice ( new_data) ;
229- Ok ( new_data. len ( ) )
230- } ) ?;
231- transfer. perform ( ) ?;
277+ fn send ( self ) -> anyhow:: Result < ( ) > {
278+ use std:: io:: Read ;
279+ let body = self . body . map ( |body| serde_json:: to_vec ( & body) . unwrap ( ) ) ;
280+ {
281+ let mut transfer = self . client . transfer ( ) ;
282+ // The unwrap in the read_function is basically guaranteed to not
283+ // happen: reading into a slice can't fail. We can't use `?` since the
284+ // return type inside transfer isn't compatible with io::Error.
285+ if let Some ( mut body) = body. as_deref ( ) {
286+ transfer. read_function ( move |dest| Ok ( body. read ( dest) . unwrap ( ) ) ) ?;
287+ }
288+ transfer. perform ( ) ?;
289+ }
290+
291+ Ok ( ( ) )
232292 }
233- serde_json:: from_slice ( & response)
234- . with_context ( || format ! ( "{}" , String :: from_utf8_lossy( & response) ) )
235293}
0 commit comments