Skip to content

Commit e900afe

Browse files
committed
Show mobile-app upload show analysis URL
1 parent 5f9403e commit e900afe

2 files changed

Lines changed: 47 additions & 28 deletions

File tree

src/api/data_types/chunking/mobile_app.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ pub struct AssembleMobileAppResponse {
2020
pub state: ChunkedFileState,
2121
pub missing_chunks: Vec<Digest>,
2222
pub detail: Option<String>,
23+
pub artifact_id: Option<String>,
2324
}

src/commands/mobile_app/upload.rs

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use symbolic::common::ByteView;
1616
use zip::write::SimpleFileOptions;
1717
use zip::{DateTime, ZipWriter};
1818

19-
use crate::api::{Api, AuthenticatedApi, ChunkUploadCapability};
19+
use crate::api::{Api, AssembleMobileAppResponse, AuthenticatedApi, ChunkUploadCapability};
2020
use crate::config::Config;
2121
use crate::utils::args::ArgExt as _;
2222
use crate::utils::chunks::{upload_chunks, Chunk, ASSEMBLE_POLL_INTERVAL};
@@ -130,8 +130,8 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
130130
let config = Config::current();
131131
let (org, project) = config.get_org_and_project(matches)?;
132132

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![];
135135
for (path, zip) in normalized_zips {
136136
info!("Uploading file: {}", path.display());
137137
let bytes = ByteView::open(zip.path())?;
@@ -143,41 +143,55 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
143143
sha.as_deref(),
144144
build_configuration,
145145
) {
146-
Ok(_) => {
146+
Ok(artifact_id) => {
147147
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));
149149
}
150150
Err(e) => {
151151
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));
153153
}
154154
}
155155
}
156156

157-
if !errored_paths.is_empty() {
157+
if !errored_paths_and_reasons.is_empty() {
158158
warn!(
159159
"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+
}
162166
);
163-
for path in errored_paths {
164-
warn!(" - {}", path.display());
167+
for (path, reason) in errored_paths_and_reasons {
168+
warn!(" - {} ({})", path.display(), reason);
165169
}
166170
}
167171

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());
176-
}
177-
}
178-
179-
if uploaded_paths.is_empty() {
172+
if uploaded_paths_and_ids.is_empty() {
180173
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!(
187+
"{}/preprod/{}/{}",
188+
config.get_base_url().unwrap_or(""),
189+
project,
190+
artifact_id
191+
);
192+
println!(" - {} {}", path.display(), url);
193+
}
194+
}
181195
}
182196
Ok(())
183197
}
@@ -337,14 +351,15 @@ fn normalize_directory(path: &Path) -> Result<TempFile> {
337351
Ok(temp_file)
338352
}
339353

354+
/// Returns artifact id if upload was successful.
340355
fn upload_file(
341356
api: &AuthenticatedApi,
342357
bytes: &[u8],
343358
org: &str,
344359
project: &str,
345360
sha: Option<&str>,
346361
build_configuration: Option<&str>,
347-
) -> Result<()> {
362+
) -> Result<String> {
348363
const SELF_HOSTED_ERROR_HINT: &str = "If you are using a self-hosted Sentry server, \
349364
update to the latest version of Sentry to use the mobile-app upload command.";
350365

@@ -400,7 +415,7 @@ fn upload_file(
400415
println!("Nothing to upload, all files are on the server");
401416
}
402417

403-
poll_assemble(
418+
let response = poll_assemble(
404419
api,
405420
checksum,
406421
&checksums,
@@ -409,7 +424,10 @@ fn upload_file(
409424
sha,
410425
build_configuration,
411426
)?;
412-
Ok(())
427+
428+
response
429+
.artifact_id
430+
.ok_or(anyhow!("Missing artifactId in response"))
413431
}
414432

415433
fn poll_assemble(
@@ -420,7 +438,7 @@ fn poll_assemble(
420438
project: &str,
421439
sha: Option<&str>,
422440
build_configuration: Option<&str>,
423-
) -> Result<()> {
441+
) -> Result<AssembleMobileAppResponse> {
424442
debug!("Polling assemble for checksum: {}", checksum);
425443

426444
let progress_style = ProgressStyle::default_spinner().template("{spinner} Processing files...");
@@ -453,7 +471,7 @@ fn poll_assemble(
453471
info!("File processing complete");
454472
}
455473

456-
Ok(())
474+
Ok(response)
457475
}
458476

459477
#[cfg(not(windows))]

0 commit comments

Comments
 (0)