@@ -64,6 +64,7 @@ impl Github {
64
64
65
65
fn start_jwt_request ( & mut self ) -> anyhow:: Result < ( ) > {
66
66
self . client . reset ( ) ;
67
+ self . client . useragent ( "rust-lang/promote-release" ) . unwrap ( ) ;
67
68
let mut headers = curl:: easy:: List :: new ( ) ;
68
69
headers. append ( & format ! ( "Authorization: Bearer {}" , self . jwt( ) ) ) ?;
69
70
self . client . http_headers ( headers) ?;
@@ -81,7 +82,11 @@ impl Github {
81
82
struct InstallationResponse {
82
83
id : u32 ,
83
84
}
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 ;
85
90
86
91
self . start_jwt_request ( ) ?;
87
92
self . client . post ( true ) ?;
@@ -92,7 +97,11 @@ impl Github {
92
97
struct TokenResponse {
93
98
token : String ,
94
99
}
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 ;
96
105
Ok ( RepositoryClient {
97
106
github : self ,
98
107
repo : repository. to_owned ( ) ,
@@ -104,13 +113,38 @@ impl Github {
104
113
impl RepositoryClient < ' _ > {
105
114
fn start_new_request ( & mut self ) -> anyhow:: Result < ( ) > {
106
115
self . github . client . reset ( ) ;
116
+ self . github . client . useragent ( "rust-lang/promote-release" ) ?;
107
117
let mut headers = curl:: easy:: List :: new ( ) ;
108
118
headers. append ( & format ! ( "Authorization: token {}" , self . token) ) ?;
109
119
self . github . client . http_headers ( headers) ?;
110
120
Ok ( ( ) )
111
121
}
112
122
113
123
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
+
114
148
#[ derive( serde:: Deserialize ) ]
115
149
struct CreatedTag {
116
150
sha : String ,
@@ -121,9 +155,10 @@ impl RepositoryClient<'_> {
121
155
"https://api.github.com/repos/{repository}/git/tags" ,
122
156
repository = self . repo,
123
157
) ) ?;
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 {
127
162
tag : tag. tag_name ,
128
163
message : tag. message ,
129
164
object : tag. commit ,
@@ -132,8 +167,8 @@ impl RepositoryClient<'_> {
132
167
name : tag. tagger_name ,
133
168
email : tag. tagger_email ,
134
169
} ,
135
- } ,
136
- ) ?;
170
+ } )
171
+ . send_with_response :: < CreatedTag > ( ) ?;
137
172
138
173
// This mostly exists to make sure the request is successful rather than
139
174
// really checking the created ref (which we already know).
@@ -149,13 +184,34 @@ impl RepositoryClient<'_> {
149
184
"https://api.github.com/repos/{repository}/git/refs" ,
150
185
repository = self . repo,
151
186
) ) ?;
152
- send_request_body :: < CreatedTagRef , _ > (
153
- & mut self . github . client ,
154
- CreateRefInternal {
187
+ self . github
188
+ . client
189
+ . with_body ( CreateRefInternal {
155
190
ref_ : & format ! ( "refs/tags/{}" , tag. tag_name) ,
156
191
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 ( ) ?;
159
215
160
216
Ok ( ( ) )
161
217
}
@@ -170,66 +226,68 @@ pub(crate) struct CreateTag<'a> {
170
226
pub ( crate ) tagger_email : & ' a str ,
171
227
}
172
228
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 < ' _ , ( ) > ;
182
232
}
183
233
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
+ }
188
247
}
189
248
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 ,
195
252
}
196
253
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) ) )
217
275
}
218
- serde_json:: from_slice ( & response)
219
- . with_context ( || format ! ( "{}" , String :: from_utf8_lossy( & response) ) )
220
- }
221
276
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 ( ( ) )
232
292
}
233
- serde_json:: from_slice ( & response)
234
- . with_context ( || format ! ( "{}" , String :: from_utf8_lossy( & response) ) )
235
293
}
0 commit comments