@@ -11,15 +11,14 @@ use clap::{Arg, ArgAction, ArgMatches, Command};
11
11
use indicatif:: ProgressStyle ;
12
12
use itertools:: Itertools as _;
13
13
use log:: { debug, info, warn} ;
14
- use sha1_smol:: Digest ;
15
14
use symbolic:: common:: ByteView ;
16
15
use zip:: write:: SimpleFileOptions ;
17
16
use zip:: { DateTime , ZipWriter } ;
18
17
19
18
use crate :: api:: { Api , AuthenticatedApi , ChunkUploadCapability } ;
20
19
use crate :: config:: Config ;
21
20
use crate :: utils:: args:: ArgExt as _;
22
- use crate :: utils:: chunks:: { upload_chunks, Chunk , ASSEMBLE_POLL_INTERVAL } ;
21
+ use crate :: utils:: chunks:: { upload_chunks, Chunk } ;
23
22
use crate :: utils:: fs:: get_sha1_checksums;
24
23
#[ cfg( all( target_os = "macos" , target_arch = "aarch64" ) ) ]
25
24
use crate :: utils:: fs:: TempDir ;
@@ -129,9 +128,10 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
129
128
130
129
let config = Config :: current ( ) ;
131
130
let ( org, project) = config. get_org_and_project ( matches) ?;
131
+ let base_url = config. get_base_url ( ) ?;
132
132
133
- let mut uploaded_paths = vec ! [ ] ;
134
- let mut errored_paths = vec ! [ ] ;
133
+ let mut uploaded_paths_and_ids = vec ! [ ] ;
134
+ let mut errored_paths_and_reasons = vec ! [ ] ;
135
135
for ( path, zip) in normalized_zips {
136
136
info ! ( "Uploading file: {}" , path. display( ) ) ;
137
137
let bytes = ByteView :: open ( zip. path ( ) ) ?;
@@ -143,41 +143,50 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
143
143
sha. as_deref ( ) ,
144
144
build_configuration,
145
145
) {
146
- Ok ( _ ) => {
146
+ Ok ( artifact_id ) => {
147
147
info ! ( "Successfully uploaded file: {}" , path. display( ) ) ;
148
- uploaded_paths . push ( path. to_path_buf ( ) ) ;
148
+ uploaded_paths_and_ids . push ( ( path. to_path_buf ( ) , artifact_id ) ) ;
149
149
}
150
150
Err ( e) => {
151
151
debug ! ( "Failed to upload file at path {}: {}" , path. display( ) , e) ;
152
- errored_paths . push ( path. to_path_buf ( ) ) ;
152
+ errored_paths_and_reasons . push ( ( path. to_path_buf ( ) , e ) ) ;
153
153
}
154
154
}
155
155
}
156
156
157
- if !errored_paths . is_empty ( ) {
157
+ if !errored_paths_and_reasons . is_empty ( ) {
158
158
warn ! (
159
159
"Failed to upload {} file{}:" ,
160
- errored_paths. len( ) ,
161
- if errored_paths. len( ) == 1 { "" } else { "s" }
160
+ errored_paths_and_reasons. len( ) ,
161
+ if errored_paths_and_reasons. len( ) == 1 {
162
+ ""
163
+ } else {
164
+ "s"
165
+ }
162
166
) ;
163
- for path in errored_paths {
164
- warn ! ( " - {}" , path. display( ) ) ;
165
- }
166
- }
167
-
168
- println ! (
169
- "Successfully uploaded {} file{} to Sentry" ,
170
- uploaded_paths. len( ) ,
171
- if uploaded_paths. len( ) == 1 { "" } else { "s" }
172
- ) ;
173
- if uploaded_paths. len ( ) < 3 {
174
- for path in & uploaded_paths {
175
- println ! ( " - {}" , path. display( ) ) ;
167
+ for ( path, reason) in errored_paths_and_reasons {
168
+ warn ! ( " - {} ({})" , path. display( ) , reason) ;
176
169
}
177
170
}
178
171
179
- if uploaded_paths . is_empty ( ) {
172
+ if uploaded_paths_and_ids . is_empty ( ) {
180
173
bail ! ( "Failed to upload any files" ) ;
174
+ } else {
175
+ println ! (
176
+ "Successfully uploaded {} file{} to Sentry" ,
177
+ uploaded_paths_and_ids. len( ) ,
178
+ if uploaded_paths_and_ids. len( ) == 1 {
179
+ ""
180
+ } else {
181
+ "s"
182
+ }
183
+ ) ;
184
+ if uploaded_paths_and_ids. len ( ) < 3 {
185
+ for ( path, artifact_id) in & uploaded_paths_and_ids {
186
+ let url = format ! ( "{base_url}/{org}/preprod/{project}/{artifact_id}" ) ;
187
+ println ! ( " - {} {url}" , path. display( ) ) ;
188
+ }
189
+ }
181
190
}
182
191
Ok ( ( ) )
183
192
}
@@ -337,14 +346,15 @@ fn normalize_directory(path: &Path) -> Result<TempFile> {
337
346
Ok ( temp_file)
338
347
}
339
348
349
+ /// Returns artifact id if upload was successful.
340
350
fn upload_file (
341
351
api : & AuthenticatedApi ,
342
352
bytes : & [ u8 ] ,
343
353
org : & str ,
344
354
project : & str ,
345
355
sha : Option < & str > ,
346
356
build_configuration : Option < & str > ,
347
- ) -> Result < ( ) > {
357
+ ) -> Result < String > {
348
358
const SELF_HOSTED_ERROR_HINT : & str = "If you are using a self-hosted Sentry server, \
349
359
update to the latest version of Sentry to use the mobile-app upload command.";
350
360
@@ -371,7 +381,7 @@ fn upload_file(
371
381
}
372
382
373
383
let progress_style =
374
- ProgressStyle :: default_spinner ( ) . template ( "{spinner} Optimizing bundle for upload..." ) ;
384
+ ProgressStyle :: default_spinner ( ) . template ( "{spinner} Preparing for upload..." ) ;
375
385
let pb = ProgressBar :: new_spinner ( ) ;
376
386
pb. enable_steady_tick ( 100 ) ;
377
387
pb. set_style ( progress_style) ;
@@ -384,76 +394,33 @@ fn upload_file(
384
394
. map ( |( data, checksum) | Chunk ( ( * checksum, data) ) )
385
395
. collect :: < Vec < _ > > ( ) ;
386
396
387
- pb. finish_with_duration ( "Finishing upload" ) ;
388
-
389
- let response =
390
- api. assemble_mobile_app ( org, project, checksum, & checksums, sha, build_configuration) ?;
391
- chunks. retain ( |Chunk ( ( digest, _) ) | response. missing_chunks . contains ( digest) ) ;
392
-
393
- if !chunks. is_empty ( ) {
394
- let upload_progress_style = ProgressStyle :: default_bar ( ) . template (
395
- "{prefix:.dim} Uploading files...\
396
- \n {wide_bar} {bytes}/{total_bytes} ({eta})",
397
- ) ;
398
- upload_chunks ( & chunks, & chunk_upload_options, upload_progress_style) ?;
399
- } else {
400
- println ! ( "Nothing to upload, all files are on the server" ) ;
401
- }
402
-
403
- poll_assemble (
404
- api,
405
- checksum,
406
- & checksums,
407
- org,
408
- project,
409
- sha,
410
- build_configuration,
411
- ) ?;
412
- Ok ( ( ) )
413
- }
414
-
415
- fn poll_assemble (
416
- api : & AuthenticatedApi ,
417
- checksum : Digest ,
418
- chunks : & [ Digest ] ,
419
- org : & str ,
420
- project : & str ,
421
- sha : Option < & str > ,
422
- build_configuration : Option < & str > ,
423
- ) -> Result < ( ) > {
424
- debug ! ( "Polling assemble for checksum: {}" , checksum) ;
425
-
426
- let progress_style = ProgressStyle :: default_spinner ( ) . template ( "{spinner} Processing files..." ) ;
427
- let pb = ProgressBar :: new_spinner ( ) ;
428
-
429
- pb. enable_steady_tick ( 100 ) ;
430
- pb. set_style ( progress_style) ;
397
+ pb. finish_with_duration ( "Preparing for upload" ) ;
431
398
432
- let response = loop {
399
+ let result = loop {
433
400
let response =
434
- api. assemble_mobile_app ( org, project, checksum, chunks, sha, build_configuration) ?;
401
+ api. assemble_mobile_app ( org, project, checksum, & checksums, sha, build_configuration) ?;
402
+ chunks. retain ( |Chunk ( ( digest, _) ) | response. missing_chunks . contains ( digest) ) ;
403
+
404
+ if !chunks. is_empty ( ) {
405
+ let upload_progress_style = ProgressStyle :: default_bar ( ) . template (
406
+ "{prefix:.dim} Uploading files...\
407
+ \n {wide_bar} {bytes}/{total_bytes} ({eta})",
408
+ ) ;
409
+ upload_chunks ( & chunks, & chunk_upload_options, upload_progress_style) ?;
410
+ }
435
411
436
- if response. state . is_finished ( ) {
437
- break response;
412
+ // is_err() is not_found or error and is_finished() is ok or error, the both is only error
413
+ if response. state . is_finished ( ) && response. state . is_err ( ) {
414
+ let message = response. detail . as_deref ( ) . unwrap_or ( "unknown error" ) ;
415
+ bail ! ( "Failed to process uploaded files: {}" , message) ;
438
416
}
439
417
440
- std:: thread:: sleep ( ASSEMBLE_POLL_INTERVAL ) ;
418
+ if let Some ( artifact_id) = response. artifact_id {
419
+ break Ok ( artifact_id) ;
420
+ }
441
421
} ;
442
422
443
- pb. finish_with_duration ( "Processing" ) ;
444
-
445
- if response. state . is_err ( ) {
446
- let message = response. detail . as_deref ( ) . unwrap_or ( "unknown error" ) ;
447
- bail ! ( "Failed to process uploaded files: {}" , message) ;
448
- }
449
-
450
- if response. state . is_pending ( ) {
451
- info ! ( "File upload complete (processing pending on server)" ) ;
452
- } else {
453
- info ! ( "File processing complete" ) ;
454
- }
455
-
456
- Ok ( ( ) )
423
+ result
457
424
}
458
425
459
426
#[ cfg( not( windows) ) ]
0 commit comments