Skip to content

Commit 8f67a63

Browse files
feat(proguard): Upload ProGuard with chunked uploading (#2918)
### Description ⚠️ **Breaking change:** Do not merge until ready to release in a major. Use chunked uploading for `sentry-cli upload-proguard`, as chunked uploads are generally more reliable than non-chunked uploads, and chunked uploading is the uploading method used by all other file uploading commands in Sentry CLI. Users who previously had set the `SENTRY_EXPERIMENTAL_PROGUARD_CHUNK_UPLOAD` environment variable to opt into the chunk uploading behavior no longer need to set this variable, as all ProGuard files are always uploaded with chunked uploading. ### Issues - Resolves #2328 - Resolves [CLI-13](https://linear.app/getsentry/issue/CLI-13/make-chunk-uploads-the-default-for-proguard-files) _______ BREAKING CHANGE: The `sentry-cli upload-proguard` file can no longer upload to Sentry servers which lack support for receiving ProGuard mappings via chunked upload.
1 parent d83b059 commit 8f67a63

File tree

8 files changed

+28
-106
lines changed

8 files changed

+28
-106
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ we should rename this section to "Unreleased" -->
1414

1515
- Removed the `upload-proguard` subcommand's `--app-id`, `--version`, and `--version-code` arguments ([#2876](https://github.com/getsentry/sentry-cli/pull/2876)). Users using these arguments should stop using them, as they are unnecessary. The information passed to these arguments is no longer visible in Sentry.
1616

17+
### Improvements
18+
19+
- The `sentry-cli upload-proguard` command now uses chunked uploading by default ([#2918](https://github.com/getsentry/sentry-cli/pull/2918)). Users who previously set the `SENTRY_EXPERIMENTAL_PROGUARD_CHUNK_UPLOAD` environment variable to opt into this behavior no longer need to set the variable.
20+
1721
### Fixes
1822

1923
- Fixed misleading error message claiming the server doesn't support chunk uploading when the actual error was a non-existent organization ([#2930](https://github.com/getsentry/sentry-cli/pull/2930)).

src/commands/upload_proguard.rs

Lines changed: 22 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use std::env;
21
use std::io;
32

43
use anyhow::{bail, Error, Result};
@@ -9,16 +8,13 @@ use symbolic::common::ByteView;
98
use uuid::Uuid;
109

1110
use crate::api::Api;
11+
use crate::api::ChunkUploadCapability;
1212
use crate::config::Config;
1313
use crate::utils::android::dump_proguard_uuids_as_properties;
1414
use crate::utils::args::ArgExt as _;
15-
use crate::utils::fs::TempFile;
1615
use crate::utils::proguard;
1716
use crate::utils::proguard::ProguardMapping;
1817
use crate::utils::system::QuietExit;
19-
use crate::utils::ui::{copy_with_progress, make_byte_progress_bar};
20-
21-
const CHUNK_UPLOAD_ENV_VAR: &str = "SENTRY_EXPERIMENTAL_PROGUARD_CHUNK_UPLOAD";
2218

2319
pub fn make_command(command: Command) -> Command {
2420
command
@@ -167,79 +163,31 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
167163
let api = Api::current();
168164
let config = Config::current();
169165

170-
// Don't initialize these until we confirm the user did not pass the --no-upload flag,
171-
// or if we are using chunked uploading. This is because auth token, org, and project
172-
// are not needed for the no-upload case.
173-
let authenticated_api;
174-
let (org, project);
175-
176-
if env::var(CHUNK_UPLOAD_ENV_VAR) == Ok("1".into()) {
177-
log::warn!(
178-
"EXPERIMENTAL FEATURE: Uploading proguard mappings using chunked uploading. \
179-
Some functionality may be unavailable when using chunked uploading. Please unset \
180-
the {CHUNK_UPLOAD_ENV_VAR} variable if you encounter any \
181-
problems."
182-
);
183-
184-
authenticated_api = api.authenticated()?;
185-
(org, project) = config.get_org_and_project(matches)?;
186-
187-
let chunk_upload_options = authenticated_api.get_chunk_upload_options(&org)?;
188-
189-
proguard::chunk_upload(&mappings, chunk_upload_options, &org, &project)?;
190-
} else {
191-
if mappings.is_empty() && matches.get_flag("require_one") {
192-
println!();
193-
eprintln!("{}", style("error: found no mapping files to upload").red());
194-
return Err(QuietExit(1).into());
195-
}
196-
197-
println!("{} compressing mappings", style(">").dim());
198-
let tf = TempFile::create()?;
199-
{
200-
let mut zip = zip::ZipWriter::new(tf.open()?);
201-
for mapping in &mappings {
202-
let pb = make_byte_progress_bar(mapping.len() as u64);
203-
zip.start_file(
204-
format!("proguard/{}.txt", mapping.uuid()),
205-
zip::write::SimpleFileOptions::default(),
206-
)?;
207-
copy_with_progress(&pb, &mut mapping.as_ref(), &mut zip)?;
208-
pb.finish_and_clear();
209-
}
210-
}
166+
if mappings.is_empty() && matches.get_flag("require_one") {
167+
println!();
168+
eprintln!("{}", style("error: found no mapping files to upload").red());
169+
return Err(QuietExit(1).into());
170+
}
211171

212-
// write UUIDs into the mapping file.
213-
if let Some(p) = matches.get_one::<String>("write_properties") {
214-
let uuids: Vec<_> = mappings.iter().map(|x| x.uuid()).collect();
215-
dump_proguard_uuids_as_properties(p, &uuids)?;
216-
}
172+
// write UUIDs into the mapping file.
173+
if let Some(p) = matches.get_one::<String>("write_properties") {
174+
let uuids: Vec<_> = mappings.iter().map(|x| x.uuid()).collect();
175+
dump_proguard_uuids_as_properties(p, &uuids)?;
176+
}
217177

218-
if matches.get_flag("no_upload") {
219-
println!("{} skipping upload.", style(">").dim());
220-
return Ok(());
221-
}
178+
if matches.get_flag("no_upload") {
179+
println!("{} skipping upload.", style(">").dim());
180+
return Ok(());
181+
}
222182

223-
println!("{} uploading mappings", style(">").dim());
224-
(org, project) = config.get_org_and_project(matches)?;
183+
let authenticated_api = api.authenticated()?;
184+
let (org, project) = config.get_org_and_project(matches)?;
225185

226-
authenticated_api = api.authenticated()?;
186+
let chunk_upload_options = authenticated_api.get_chunk_upload_options(&org)?;
227187

228-
let rv = authenticated_api
229-
.region_specific(&org)
230-
.upload_dif_archive(&project, tf.path())?;
231-
println!(
232-
"{} Uploaded a total of {} new mapping files",
233-
style(">").dim(),
234-
style(rv.len()).yellow()
235-
);
236-
if !rv.is_empty() {
237-
println!("Newly uploaded debug symbols:");
238-
for df in rv {
239-
println!(" {}", style(&df.id()).dim());
240-
}
241-
}
188+
if chunk_upload_options.supports(ChunkUploadCapability::Proguard) {
189+
proguard::chunk_upload(&mappings, chunk_upload_options, &org, &project)
190+
} else {
191+
Err(anyhow::anyhow!("Server does not support uploading ProGuard mappings via chunked upload. Please update your Sentry server."))
242192
}
243-
244-
Ok(())
245193
}

src/utils/proguard/mapping.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,6 @@ pub struct ProguardMapping<'a> {
1919
}
2020

2121
impl<'a> ProguardMapping<'a> {
22-
/// Get the length of the mapping in bytes.
23-
pub fn len(&self) -> usize {
24-
self.bytes.len()
25-
}
26-
2722
/// Get the UUID of the mapping.
2823
pub fn uuid(&self) -> Uuid {
2924
self.uuid

tests/integration/_cases/upload_proguard/upload_proguard-no-upload.trycmd

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
$ sentry-cli upload-proguard tests/integration/_fixtures/proguard.txt --no-upload
33
? success
44
warning: ignoring proguard mapping 'tests/integration/_fixtures/proguard.txt': Proguard mapping does not contain line information
5-
> compressing mappings
65
> skipping upload.
76

87
```

tests/integration/_cases/upload_proguard/upload_proguard.trycmd

Lines changed: 0 additions & 9 deletions
This file was deleted.

tests/integration/_responses/debug_files/get-chunk-upload.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@
77
"concurrency": 8,
88
"hashAlgorithm": "sha1",
99
"compression": ["gzip"],
10-
"accept": ["debug_files", "release_files", "pdbs", "portablepdbs", "sources", "bcsymbolmaps"]
10+
"accept": ["debug_files", "release_files", "pdbs", "portablepdbs", "sources", "bcsymbolmaps", "proguard"]
1111
}

tests/integration/test_utils/test_manager.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,6 @@ impl AssertCmdTestManager {
201201
self
202202
}
203203

204-
/// Set a custom environment variable for the test.
205-
pub fn env(mut self, variable: impl AsRef<OsStr>, value: impl AsRef<OsStr>) -> Self {
206-
self.command.env(variable, value);
207-
self
208-
}
209-
210204
/// Run the command and perform assertions.
211205
///
212206
/// This function asserts both the mocks and the command result.

tests/integration/upload_proguard.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,7 @@ use crate::integration::{MockEndpointBuilder, TestManager};
88

99
#[test]
1010
fn command_upload_proguard() {
11-
TestManager::new()
12-
.mock_endpoint(
13-
MockEndpointBuilder::new("POST", "/api/0/projects/wat-org/wat-project/files/dsyms/")
14-
.with_response_body("[]"),
15-
)
16-
.register_trycmd_test("upload_proguard/*.trycmd")
17-
.with_default_token();
11+
TestManager::new().register_trycmd_test("upload_proguard/*.trycmd");
1812
}
1913

2014
#[test]
@@ -72,7 +66,6 @@ fn chunk_upload_already_there() {
7266
"tests/integration/_fixtures/upload_proguard/mapping.txt",
7367
])
7468
.with_default_token()
75-
.env("SENTRY_EXPERIMENTAL_PROGUARD_CHUNK_UPLOAD", "1")
7669
.run_and_assert(AssertCommand::Success)
7770
}
7871

@@ -166,7 +159,6 @@ fn chunk_upload_needs_upload() {
166159
"tests/integration/_fixtures/upload_proguard/mapping.txt",
167160
])
168161
.with_default_token()
169-
.env("SENTRY_EXPERIMENTAL_PROGUARD_CHUNK_UPLOAD", "1")
170162
.run_and_assert(AssertCommand::Success)
171163
}
172164

@@ -289,6 +281,5 @@ fn chunk_upload_two_files() {
289281
"tests/integration/_fixtures/upload_proguard/mapping-2.txt",
290282
])
291283
.with_default_token()
292-
.env("SENTRY_EXPERIMENTAL_PROGUARD_CHUNK_UPLOAD", "1")
293284
.run_and_assert(AssertCommand::Success)
294285
}

0 commit comments

Comments
 (0)