sentry-cli 3.3.3__tar.gz → 3.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/Cargo.lock +1 -1
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/Cargo.toml +1 -1
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/PKG-INFO +1 -1
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/sentry_cli.egg-info/PKG-INFO +1 -1
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/sentry_cli.egg-info/SOURCES.txt +4 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/data_types/chunking/build.rs +7 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/data_types/chunking/mod.rs +1 -1
- sentry_cli-3.3.4/src/api/data_types/code_mappings.rs +37 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/data_types/mod.rs +2 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/data_types/snapshots.rs +2 -14
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/mod.rs +31 -1
- sentry_cli-3.3.4/src/commands/build/download.rs +106 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/build/mod.rs +2 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/build/snapshots.rs +39 -15
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/build/upload.rs +15 -0
- sentry_cli-3.3.4/src/commands/code_mappings/mod.rs +45 -0
- sentry_cli-3.3.4/src/commands/code_mappings/upload.rs +452 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/mod.rs +2 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/vcs.rs +19 -7
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/LICENSE +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/MANIFEST.in +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/README.md +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/apple-catalog-parsing/AGENTS.md +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/apple-catalog-parsing/CLAUDE.md +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/apple-catalog-parsing/Cargo.toml +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/apple-catalog-parsing/build.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/apple-catalog-parsing/native/swift/AssetCatalogParser/Package.swift +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/AssetCatalogParser/AssetCatalogReader.swift +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/include/safeValueForKey.h +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/safeValueForKey.m +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/AssetCatalogParserTests.swift +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/Resources/test.xcarchive/Info.plist +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/Resources/test.xcarchive/Products/Applications/DemoApp.app/Assets.car +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/apple-catalog-parsing/src/asset_catalog.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/apple-catalog-parsing/src/lib.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/build.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/pyproject.toml +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/sentry_cli.egg-info/dependency_links.txt +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/sentry_cli.egg-info/top_level.txt +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/setup.cfg +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/setup.py +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/AGENTS.md +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/CLAUDE.md +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/connection_manager.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/data_types/chunking/artifact.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/data_types/chunking/compression.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/data_types/chunking/dif.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/data_types/chunking/file_state.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/data_types/chunking/hash_algorithm.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/data_types/chunking/upload/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/data_types/chunking/upload/options.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/data_types/deploy.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/encoding.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/envelopes_api.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/errors/api_error.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/errors/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/errors/sentry_error.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/pagination.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/api/serialization.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/bashsupport.sh +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/bash_hook.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/dart_symbol_map/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/dart_symbol_map/upload.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/debug_files/bundle_jvm.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/debug_files/bundle_sources.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/debug_files/check.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/debug_files/find.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/debug_files/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/debug_files/print_sources.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/debug_files/upload.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/deploys/list.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/deploys/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/deploys/new.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/derive_parser.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/events/list.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/events/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/info.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/issues/list.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/issues/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/issues/mute.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/issues/resolve.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/issues/unresolve.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/login.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/logs/list.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/logs/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/monitors/list.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/monitors/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/monitors/run.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/organizations/list.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/organizations/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/proguard/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/proguard/upload.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/proguard/uuid.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/projects/list.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/projects/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/react_native/gradle.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/react_native/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/react_native/xcode.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/releases/archive.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/releases/delete.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/releases/finalize.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/releases/info.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/releases/list.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/releases/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/releases/new.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/releases/propose_version.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/releases/restore.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/releases/set_commits.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/repos/list.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/repos/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/send_envelope.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/send_event.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/send_metric/common_args.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/send_metric/increment.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/send_metric/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/send_metric/set.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/sourcemaps/inject.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/sourcemaps/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/sourcemaps/resolve.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/sourcemaps/upload.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/uninstall.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/update.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/upload_dif.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/upload_dsym.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/commands/upload_proguard.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/config.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/constants.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/main.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/android.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/args.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/auth_token/auth_token_impl.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/auth_token/error.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/auth_token/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/auth_token/org_auth_token.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/auth_token/redacting.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/auth_token/test.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/auth_token/user_auth_token.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/build/apple.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/build/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/build/normalize.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/build/validation.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/build_vcs.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/chunks/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/chunks/options.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/chunks/types.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/chunks/upload.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/ci.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/cordova.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/dif.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/dif_upload/error.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/dif_upload/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/event.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/file_search.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/file_upload.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/formatting.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/fs.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/http.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/logging.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/non_empty.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/progress.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/proguard/mapping.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/proguard/mod.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/proguard/upload.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/releases.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/retry.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_default_twenty.snap +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_ignore_missing.snap +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_set_base.snap +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_set_previous_commit.snap +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/snapshots/sentry_cli__utils__vcs__tests__get_commits_from_git.snap +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/source_bundle.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/sourcemaps/inject.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/sourcemaps.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/system.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/ui.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/update.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/value_parsers.rs +0 -0
- {sentry_cli-3.3.3 → sentry_cli-3.3.4}/src/utils/xcode.rs +0 -0
|
@@ -36,6 +36,7 @@ src/api/envelopes_api.rs
|
|
|
36
36
|
src/api/mod.rs
|
|
37
37
|
src/api/pagination.rs
|
|
38
38
|
src/api/serialization.rs
|
|
39
|
+
src/api/data_types/code_mappings.rs
|
|
39
40
|
src/api/data_types/deploy.rs
|
|
40
41
|
src/api/data_types/mod.rs
|
|
41
42
|
src/api/data_types/snapshots.rs
|
|
@@ -63,9 +64,12 @@ src/commands/update.rs
|
|
|
63
64
|
src/commands/upload_dif.rs
|
|
64
65
|
src/commands/upload_dsym.rs
|
|
65
66
|
src/commands/upload_proguard.rs
|
|
67
|
+
src/commands/build/download.rs
|
|
66
68
|
src/commands/build/mod.rs
|
|
67
69
|
src/commands/build/snapshots.rs
|
|
68
70
|
src/commands/build/upload.rs
|
|
71
|
+
src/commands/code_mappings/mod.rs
|
|
72
|
+
src/commands/code_mappings/upload.rs
|
|
69
73
|
src/commands/dart_symbol_map/mod.rs
|
|
70
74
|
src/commands/dart_symbol_map/upload.rs
|
|
71
75
|
src/commands/debug_files/bundle_jvm.rs
|
|
@@ -28,6 +28,13 @@ pub struct AssembleBuildResponse {
|
|
|
28
28
|
pub artifact_url: Option<String>,
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
#[derive(Debug, Deserialize)]
|
|
32
|
+
#[serde(rename_all = "camelCase")]
|
|
33
|
+
pub struct BuildInstallDetails {
|
|
34
|
+
pub is_installable: bool,
|
|
35
|
+
pub install_url: Option<String>,
|
|
36
|
+
}
|
|
37
|
+
|
|
31
38
|
/// VCS information for build app uploads
|
|
32
39
|
#[derive(Debug, Serialize)]
|
|
33
40
|
pub struct VcsInfo<'a> {
|
|
@@ -10,7 +10,7 @@ mod hash_algorithm;
|
|
|
10
10
|
mod upload;
|
|
11
11
|
|
|
12
12
|
pub use self::artifact::{AssembleArtifactsResponse, ChunkedArtifactRequest};
|
|
13
|
-
pub use self::build::{AssembleBuildResponse, ChunkedBuildRequest, VcsInfo};
|
|
13
|
+
pub use self::build::{AssembleBuildResponse, BuildInstallDetails, ChunkedBuildRequest, VcsInfo};
|
|
14
14
|
pub use self::compression::ChunkCompression;
|
|
15
15
|
pub use self::dif::{AssembleDifsRequest, AssembleDifsResponse, ChunkedDifRequest};
|
|
16
16
|
pub use self::file_state::ChunkedFileState;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//! Data types for the bulk code mappings API.
|
|
2
|
+
|
|
3
|
+
use serde::{Deserialize, Serialize};
|
|
4
|
+
|
|
5
|
+
#[derive(Debug, Serialize)]
|
|
6
|
+
#[serde(rename_all = "camelCase")]
|
|
7
|
+
pub struct BulkCodeMappingsRequest<'a> {
|
|
8
|
+
pub project: &'a str,
|
|
9
|
+
pub repository: &'a str,
|
|
10
|
+
pub default_branch: &'a str,
|
|
11
|
+
pub mappings: &'a [BulkCodeMapping],
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
#[derive(Debug, Deserialize, Serialize)]
|
|
15
|
+
#[serde(rename_all = "camelCase")]
|
|
16
|
+
pub struct BulkCodeMapping {
|
|
17
|
+
pub stack_root: String,
|
|
18
|
+
pub source_root: String,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#[derive(Debug, Deserialize)]
|
|
22
|
+
pub struct BulkCodeMappingsResponse {
|
|
23
|
+
pub created: u64,
|
|
24
|
+
pub updated: u64,
|
|
25
|
+
pub errors: u64,
|
|
26
|
+
pub mappings: Vec<BulkCodeMappingResult>,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
#[derive(Debug, Deserialize)]
|
|
30
|
+
#[serde(rename_all = "camelCase")]
|
|
31
|
+
pub struct BulkCodeMappingResult {
|
|
32
|
+
pub stack_root: String,
|
|
33
|
+
pub source_root: String,
|
|
34
|
+
pub status: String,
|
|
35
|
+
#[serde(default)]
|
|
36
|
+
pub detail: Option<String>,
|
|
37
|
+
}
|
|
@@ -7,7 +7,6 @@ use serde_json::Value;
|
|
|
7
7
|
|
|
8
8
|
use super::VcsInfo;
|
|
9
9
|
|
|
10
|
-
const IMAGE_FILE_NAME_FIELD: &str = "image_file_name";
|
|
11
10
|
const WIDTH_FIELD: &str = "width";
|
|
12
11
|
const HEIGHT_FIELD: &str = "height";
|
|
13
12
|
|
|
@@ -42,16 +41,7 @@ pub struct ImageMetadata {
|
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
impl ImageMetadata {
|
|
45
|
-
pub fn new(
|
|
46
|
-
image_file_name: String,
|
|
47
|
-
width: u32,
|
|
48
|
-
height: u32,
|
|
49
|
-
mut extra: HashMap<String, Value>,
|
|
50
|
-
) -> Self {
|
|
51
|
-
extra.insert(
|
|
52
|
-
IMAGE_FILE_NAME_FIELD.to_owned(),
|
|
53
|
-
Value::String(image_file_name),
|
|
54
|
-
);
|
|
44
|
+
pub fn new(width: u32, height: u32, mut extra: HashMap<String, Value>) -> Self {
|
|
55
45
|
extra.insert(WIDTH_FIELD.to_owned(), Value::from(width));
|
|
56
46
|
extra.insert(HEIGHT_FIELD.to_owned(), Value::from(height));
|
|
57
47
|
|
|
@@ -68,18 +58,16 @@ mod tests {
|
|
|
68
58
|
#[test]
|
|
69
59
|
fn cli_managed_fields_override_sidecar_fields() {
|
|
70
60
|
let extra = serde_json::from_value(json!({
|
|
71
|
-
(IMAGE_FILE_NAME_FIELD): "from-sidecar.png",
|
|
72
61
|
(WIDTH_FIELD): 1,
|
|
73
62
|
(HEIGHT_FIELD): 2,
|
|
74
63
|
"custom": "keep-me"
|
|
75
64
|
}))
|
|
76
65
|
.unwrap();
|
|
77
66
|
|
|
78
|
-
let metadata = ImageMetadata::new(
|
|
67
|
+
let metadata = ImageMetadata::new(100, 200, extra);
|
|
79
68
|
let serialized = serde_json::to_value(metadata).unwrap();
|
|
80
69
|
|
|
81
70
|
let expected = json!({
|
|
82
|
-
(IMAGE_FILE_NAME_FIELD): "from-cli.png",
|
|
83
71
|
(WIDTH_FIELD): 100,
|
|
84
72
|
(HEIGHT_FIELD): 200,
|
|
85
73
|
"custom": "keep-me"
|
|
@@ -16,7 +16,6 @@ use std::borrow::Cow;
|
|
|
16
16
|
use std::cell::RefCell;
|
|
17
17
|
use std::collections::HashMap;
|
|
18
18
|
use std::error::Error as _;
|
|
19
|
-
#[cfg(any(target_os = "macos", not(feature = "managed")))]
|
|
20
19
|
use std::fs::File;
|
|
21
20
|
use std::io::{self, Read as _, Write};
|
|
22
21
|
use std::rc::Rc;
|
|
@@ -724,6 +723,26 @@ impl AuthenticatedApi<'_> {
|
|
|
724
723
|
.convert_rnf(ApiErrorKind::ProjectNotFound)
|
|
725
724
|
}
|
|
726
725
|
|
|
726
|
+
pub fn get_build_install_details(
|
|
727
|
+
&self,
|
|
728
|
+
org: &str,
|
|
729
|
+
build_id: &str,
|
|
730
|
+
) -> ApiResult<BuildInstallDetails> {
|
|
731
|
+
let url = format!(
|
|
732
|
+
"/organizations/{}/preprodartifacts/{}/install-details/",
|
|
733
|
+
PathArg(org),
|
|
734
|
+
PathArg(build_id)
|
|
735
|
+
);
|
|
736
|
+
|
|
737
|
+
self.get(&url)?.convert()
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
pub fn download_installable_build(&self, url: &str, dst: &mut File) -> ApiResult<ApiResponse> {
|
|
741
|
+
self.request(Method::Get, url)?
|
|
742
|
+
.progress_bar_mode(ProgressBarMode::Response)
|
|
743
|
+
.send_into(dst)
|
|
744
|
+
}
|
|
745
|
+
|
|
727
746
|
/// List all organizations associated with the authenticated token
|
|
728
747
|
/// in the given `Region`. If no `Region` is provided, we assume
|
|
729
748
|
/// we're issuing a request to a monolith deployment.
|
|
@@ -978,6 +997,17 @@ impl AuthenticatedApi<'_> {
|
|
|
978
997
|
Ok(rv)
|
|
979
998
|
}
|
|
980
999
|
|
|
1000
|
+
/// Bulk uploads code mappings for an organization.
|
|
1001
|
+
pub fn bulk_upload_code_mappings(
|
|
1002
|
+
&self,
|
|
1003
|
+
org: &str,
|
|
1004
|
+
body: &BulkCodeMappingsRequest,
|
|
1005
|
+
) -> ApiResult<BulkCodeMappingsResponse> {
|
|
1006
|
+
let path = format!("/organizations/{}/code-mappings/bulk/", PathArg(org));
|
|
1007
|
+
self.post(&path, body)?
|
|
1008
|
+
.convert_rnf(ApiErrorKind::OrganizationNotFound)
|
|
1009
|
+
}
|
|
1010
|
+
|
|
981
1011
|
/// Creates a preprod snapshot artifact for the given project.
|
|
982
1012
|
pub fn create_preprod_snapshot<S: Serialize>(
|
|
983
1013
|
&self,
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
use std::fs;
|
|
2
|
+
use std::path::PathBuf;
|
|
3
|
+
|
|
4
|
+
use anyhow::{bail, Result};
|
|
5
|
+
use clap::{Arg, ArgMatches, Command};
|
|
6
|
+
use log::info;
|
|
7
|
+
|
|
8
|
+
use crate::api::Api;
|
|
9
|
+
use crate::config::Config;
|
|
10
|
+
use crate::utils::args::ArgExt as _;
|
|
11
|
+
use crate::utils::fs::TempFile;
|
|
12
|
+
|
|
13
|
+
const EXPERIMENTAL_WARNING: &str =
|
|
14
|
+
"[EXPERIMENTAL] The \"build download\" command is experimental. \
|
|
15
|
+
The command is subject to breaking changes, including removal, in any Sentry CLI release.";
|
|
16
|
+
|
|
17
|
+
pub fn make_command(command: Command) -> Command {
|
|
18
|
+
command
|
|
19
|
+
.about("[EXPERIMENTAL] Download a build artifact.")
|
|
20
|
+
.long_about(format!(
|
|
21
|
+
"Download a build artifact.\n\n{EXPERIMENTAL_WARNING}"
|
|
22
|
+
))
|
|
23
|
+
.org_arg()
|
|
24
|
+
.arg(
|
|
25
|
+
Arg::new("build_id")
|
|
26
|
+
.long("build-id")
|
|
27
|
+
.short('b')
|
|
28
|
+
.required(true)
|
|
29
|
+
.help("The ID of the build to download."),
|
|
30
|
+
)
|
|
31
|
+
.arg(Arg::new("output").long("output").help(
|
|
32
|
+
"The output file path. Defaults to \
|
|
33
|
+
'preprod_artifact_<build_id>.<ext>' in the current directory, \
|
|
34
|
+
where ext is ipa or apk depending on the platform.",
|
|
35
|
+
))
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/// For iOS builds, the install URL points to a plist manifest.
|
|
39
|
+
/// Replace the response_format to download the actual IPA binary instead.
|
|
40
|
+
fn ensure_binary_format(url: &str) -> String {
|
|
41
|
+
url.replace("response_format=plist", "response_format=ipa")
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/// Extract the file extension from the response_format query parameter.
|
|
45
|
+
fn extension_from_url(url: &str) -> Result<&str> {
|
|
46
|
+
if url.contains("response_format=ipa") {
|
|
47
|
+
Ok("ipa")
|
|
48
|
+
} else if url.contains("response_format=apk") {
|
|
49
|
+
Ok("apk")
|
|
50
|
+
} else {
|
|
51
|
+
bail!("Unsupported build format in download URL.")
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
pub fn execute(matches: &ArgMatches) -> Result<()> {
|
|
56
|
+
eprintln!("{EXPERIMENTAL_WARNING}");
|
|
57
|
+
let config = Config::current();
|
|
58
|
+
let org = config.get_org(matches)?;
|
|
59
|
+
let build_id = matches
|
|
60
|
+
.get_one::<String>("build_id")
|
|
61
|
+
.expect("build_id is required");
|
|
62
|
+
|
|
63
|
+
let api = Api::current();
|
|
64
|
+
let authenticated_api = api.authenticated()?;
|
|
65
|
+
|
|
66
|
+
info!("Fetching install details for build {build_id}");
|
|
67
|
+
let details = authenticated_api.get_build_install_details(&org, build_id)?;
|
|
68
|
+
|
|
69
|
+
if !details.is_installable {
|
|
70
|
+
bail!("Build {build_id} is not installable.");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let install_url = details
|
|
74
|
+
.install_url
|
|
75
|
+
.ok_or_else(|| anyhow::anyhow!("Build {build_id} has no install URL."))?;
|
|
76
|
+
|
|
77
|
+
let download_url = ensure_binary_format(&install_url);
|
|
78
|
+
|
|
79
|
+
let output_path = match matches.get_one::<String>("output") {
|
|
80
|
+
Some(path) => PathBuf::from(path),
|
|
81
|
+
None => {
|
|
82
|
+
let ext = extension_from_url(&download_url)?;
|
|
83
|
+
PathBuf::from(format!("preprod_artifact_{build_id}.{ext}"))
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
info!("Downloading build {build_id} to {}", output_path.display());
|
|
88
|
+
|
|
89
|
+
let tmp = TempFile::create()?;
|
|
90
|
+
let mut file = tmp.open()?;
|
|
91
|
+
let response = authenticated_api.download_installable_build(&download_url, &mut file)?;
|
|
92
|
+
|
|
93
|
+
if response.failed() {
|
|
94
|
+
bail!(
|
|
95
|
+
"Failed to download build (server returned status {}).",
|
|
96
|
+
response.status()
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
drop(file);
|
|
101
|
+
fs::copy(tmp.path(), &output_path)?;
|
|
102
|
+
|
|
103
|
+
println!("Successfully downloaded build to {}", output_path.display());
|
|
104
|
+
|
|
105
|
+
Ok(())
|
|
106
|
+
}
|
|
@@ -3,11 +3,13 @@ use clap::{ArgMatches, Command};
|
|
|
3
3
|
|
|
4
4
|
use crate::utils::args::ArgExt as _;
|
|
5
5
|
|
|
6
|
+
pub mod download;
|
|
6
7
|
pub mod snapshots;
|
|
7
8
|
pub mod upload;
|
|
8
9
|
|
|
9
10
|
macro_rules! each_subcommand {
|
|
10
11
|
($mac:ident) => {
|
|
12
|
+
$mac!(download);
|
|
11
13
|
$mac!(snapshots);
|
|
12
14
|
$mac!(upload);
|
|
13
15
|
};
|
|
@@ -331,11 +331,28 @@ fn upload_images(
|
|
|
331
331
|
|
|
332
332
|
let mut many_builder = session.many();
|
|
333
333
|
let mut manifest_entries = HashMap::new();
|
|
334
|
-
let
|
|
335
|
-
|
|
334
|
+
let mut collisions: HashMap<String, Vec<String>> = HashMap::new();
|
|
335
|
+
let mut kept_paths: HashMap<String, String> = HashMap::new();
|
|
336
336
|
for image in images {
|
|
337
337
|
debug!("Processing image: {}", image.path.display());
|
|
338
338
|
|
|
339
|
+
let image_file_name = image
|
|
340
|
+
.relative_path
|
|
341
|
+
.file_name()
|
|
342
|
+
.unwrap_or_default()
|
|
343
|
+
.to_string_lossy()
|
|
344
|
+
.into_owned();
|
|
345
|
+
|
|
346
|
+
let relative_path = crate::utils::fs::path_as_url(&image.relative_path);
|
|
347
|
+
|
|
348
|
+
if manifest_entries.contains_key(&image_file_name) {
|
|
349
|
+
collisions
|
|
350
|
+
.entry(image_file_name)
|
|
351
|
+
.or_default()
|
|
352
|
+
.push(relative_path);
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
|
|
339
356
|
let hash = compute_sha256_hash(&image.path)?;
|
|
340
357
|
let file = runtime
|
|
341
358
|
.block_on(tokio::fs::File::open(&image.path))
|
|
@@ -353,33 +370,40 @@ fn upload_images(
|
|
|
353
370
|
.expiration_policy(expiration),
|
|
354
371
|
);
|
|
355
372
|
|
|
356
|
-
let
|
|
357
|
-
.relative_path
|
|
358
|
-
.file_name()
|
|
359
|
-
.unwrap_or_default()
|
|
360
|
-
.to_string_lossy()
|
|
361
|
-
.into_owned();
|
|
362
|
-
|
|
363
|
-
let extra = read_sidecar_metadata(&image.path).unwrap_or_else(|err| {
|
|
373
|
+
let mut extra = read_sidecar_metadata(&image.path).unwrap_or_else(|err| {
|
|
364
374
|
warn!("Error reading sidecar metadata, ignoring it instead: {err:#}");
|
|
365
375
|
HashMap::new()
|
|
366
376
|
});
|
|
377
|
+
extra.insert("content_hash".to_owned(), serde_json::Value::String(hash));
|
|
367
378
|
|
|
379
|
+
kept_paths.insert(image_file_name.clone(), relative_path);
|
|
368
380
|
manifest_entries.insert(
|
|
369
|
-
|
|
370
|
-
ImageMetadata::new(
|
|
381
|
+
image_file_name,
|
|
382
|
+
ImageMetadata::new(image.width, image.height, extra),
|
|
371
383
|
);
|
|
372
384
|
}
|
|
373
385
|
|
|
386
|
+
if !collisions.is_empty() {
|
|
387
|
+
let mut details = String::new();
|
|
388
|
+
for (name, excluded_paths) in &collisions {
|
|
389
|
+
let mut all_paths = vec![kept_paths[name].as_str()];
|
|
390
|
+
all_paths.extend(excluded_paths.iter().map(|s| s.as_str()));
|
|
391
|
+
details.push_str(&format!("\n {name}: {}", all_paths.join(", ")));
|
|
392
|
+
}
|
|
393
|
+
warn!("Some images share identical file names. Only the first occurrence of each is included:{details}");
|
|
394
|
+
}
|
|
395
|
+
|
|
374
396
|
let result = runtime.block_on(async { many_builder.send().error_for_failures().await });
|
|
375
397
|
|
|
398
|
+
let uploaded_count = manifest_entries.len();
|
|
399
|
+
|
|
376
400
|
match result {
|
|
377
401
|
Ok(()) => {
|
|
378
402
|
println!(
|
|
379
403
|
"{} Uploaded {} image {}",
|
|
380
404
|
style(">").dim(),
|
|
381
|
-
style(
|
|
382
|
-
if
|
|
405
|
+
style(uploaded_count).yellow(),
|
|
406
|
+
if uploaded_count == 1 { "file" } else { "files" }
|
|
383
407
|
);
|
|
384
408
|
Ok(manifest_entries)
|
|
385
409
|
}
|
|
@@ -391,7 +415,7 @@ fn upload_images(
|
|
|
391
415
|
eprintln!(" {}", style(format!("{error:#}")).red());
|
|
392
416
|
error_count += 1;
|
|
393
417
|
}
|
|
394
|
-
anyhow::bail!("Failed to upload {error_count} out of {
|
|
418
|
+
anyhow::bail!("Failed to upload {error_count} out of {uploaded_count} images")
|
|
395
419
|
}
|
|
396
420
|
}
|
|
397
421
|
}
|
|
@@ -143,6 +143,20 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
|
|
|
143
143
|
return Err(anyhow!("Path does not exist: {}", path.display()));
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
+
// On non-Apple Silicon, reject xcarchive/IPA early before trying to
|
|
147
|
+
// open the path as a file (xcarchive is a directory, so ByteView::open
|
|
148
|
+
// would fail with a confusing I/O error).
|
|
149
|
+
#[cfg(not(all(target_os = "macos", target_arch = "aarch64")))]
|
|
150
|
+
{
|
|
151
|
+
let ext = path.extension().and_then(|e| e.to_str()).unwrap_or("");
|
|
152
|
+
if ext.eq_ignore_ascii_case("xcarchive") || ext.eq_ignore_ascii_case("ipa") {
|
|
153
|
+
return Err(anyhow!(
|
|
154
|
+
"Uploading XCArchive and IPA files requires an Apple Silicon Mac: {}",
|
|
155
|
+
path.display()
|
|
156
|
+
));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
146
160
|
let byteview = ByteView::open(path)?;
|
|
147
161
|
debug!("Loaded file with {} bytes", byteview.len());
|
|
148
162
|
|
|
@@ -301,6 +315,7 @@ fn validate_is_supported_build(path: &Path, bytes: &[u8]) -> Result<()> {
|
|
|
301
315
|
}
|
|
302
316
|
|
|
303
317
|
debug!("File format validation failed");
|
|
318
|
+
|
|
304
319
|
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
|
|
305
320
|
let format_list = "APK, AAB, XCArchive, or IPA";
|
|
306
321
|
#[cfg(not(all(target_os = "macos", target_arch = "aarch64")))]
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
use anyhow::Result;
|
|
2
|
+
use clap::{ArgMatches, Command};
|
|
3
|
+
|
|
4
|
+
use crate::utils::args::ArgExt as _;
|
|
5
|
+
|
|
6
|
+
pub mod upload;
|
|
7
|
+
|
|
8
|
+
macro_rules! each_subcommand {
|
|
9
|
+
($mac:ident) => {
|
|
10
|
+
$mac!(upload);
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
pub fn make_command(mut command: Command) -> Command {
|
|
15
|
+
macro_rules! add_subcommand {
|
|
16
|
+
($name:ident) => {{
|
|
17
|
+
command = command.subcommand(crate::commands::code_mappings::$name::make_command(
|
|
18
|
+
Command::new(stringify!($name).replace('_', "-")),
|
|
19
|
+
));
|
|
20
|
+
}};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
command = command
|
|
24
|
+
.about("Manage code mappings for Sentry. Code mappings link stack trace paths to source code paths in your repository, enabling source context and code linking in Sentry.")
|
|
25
|
+
.subcommand_required(true)
|
|
26
|
+
.arg_required_else_help(true)
|
|
27
|
+
.org_arg()
|
|
28
|
+
.project_arg(false);
|
|
29
|
+
each_subcommand!(add_subcommand);
|
|
30
|
+
command
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
pub fn execute(matches: &ArgMatches) -> Result<()> {
|
|
34
|
+
macro_rules! execute_subcommand {
|
|
35
|
+
($name:ident) => {{
|
|
36
|
+
if let Some(sub_matches) =
|
|
37
|
+
matches.subcommand_matches(&stringify!($name).replace('_', "-"))
|
|
38
|
+
{
|
|
39
|
+
return crate::commands::code_mappings::$name::execute(&sub_matches);
|
|
40
|
+
}
|
|
41
|
+
}};
|
|
42
|
+
}
|
|
43
|
+
each_subcommand!(execute_subcommand);
|
|
44
|
+
unreachable!();
|
|
45
|
+
}
|