sentry-cli 3.3.0__tar.gz → 3.3.1__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.0 → sentry_cli-3.3.1}/Cargo.lock +1 -1
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/Cargo.toml +1 -1
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/PKG-INFO +2 -2
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/README.md +1 -1
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/sentry_cli.egg-info/PKG-INFO +2 -2
- sentry_cli-3.3.1/src/api/data_types/snapshots.rs +86 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/build/snapshots.rs +135 -17
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/proguard/upload.rs +1 -4
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/proguard/uuid.rs +1 -2
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/dif.rs +11 -13
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/proguard/mapping.rs +4 -29
- sentry_cli-3.3.0/src/api/data_types/snapshots.rs +0 -31
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/LICENSE +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/MANIFEST.in +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/AGENTS.md +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/CLAUDE.md +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/Cargo.toml +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/build.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Package.swift +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/AssetCatalogParser/AssetCatalogReader.swift +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/include/safeValueForKey.h +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/safeValueForKey.m +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/AssetCatalogParserTests.swift +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/Resources/test.xcarchive/Info.plist +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/Resources/test.xcarchive/Products/Applications/DemoApp.app/Assets.car +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/src/asset_catalog.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/apple-catalog-parsing/src/lib.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/build.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/pyproject.toml +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/sentry_cli.egg-info/SOURCES.txt +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/sentry_cli.egg-info/dependency_links.txt +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/sentry_cli.egg-info/top_level.txt +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/setup.cfg +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/setup.py +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/AGENTS.md +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/CLAUDE.md +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/connection_manager.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/artifact.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/build.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/compression.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/dif.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/file_state.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/hash_algorithm.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/upload/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/chunking/upload/options.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/deploy.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/data_types/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/encoding.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/envelopes_api.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/errors/api_error.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/errors/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/errors/sentry_error.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/pagination.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/api/serialization.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/bashsupport.sh +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/bash_hook.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/build/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/build/upload.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/dart_symbol_map/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/dart_symbol_map/upload.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/debug_files/bundle_jvm.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/debug_files/bundle_sources.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/debug_files/check.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/debug_files/find.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/debug_files/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/debug_files/print_sources.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/debug_files/upload.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/deploys/list.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/deploys/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/deploys/new.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/derive_parser.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/events/list.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/events/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/info.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/issues/list.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/issues/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/issues/mute.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/issues/resolve.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/issues/unresolve.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/login.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/logs/list.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/logs/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/monitors/list.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/monitors/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/monitors/run.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/organizations/list.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/organizations/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/proguard/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/projects/list.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/projects/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/react_native/gradle.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/react_native/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/react_native/xcode.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/archive.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/delete.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/finalize.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/info.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/list.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/new.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/propose_version.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/restore.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/releases/set_commits.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/repos/list.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/repos/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/send_envelope.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/send_event.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/send_metric/common_args.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/send_metric/increment.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/send_metric/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/send_metric/set.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/sourcemaps/inject.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/sourcemaps/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/sourcemaps/resolve.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/sourcemaps/upload.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/uninstall.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/update.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/upload_dif.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/upload_dsym.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/commands/upload_proguard.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/config.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/constants.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/main.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/android.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/args.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/auth_token/auth_token_impl.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/auth_token/error.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/auth_token/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/auth_token/org_auth_token.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/auth_token/redacting.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/auth_token/test.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/auth_token/user_auth_token.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/build/apple.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/build/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/build/normalize.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/build/validation.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/chunks/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/chunks/options.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/chunks/types.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/chunks/upload.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/ci.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/cordova.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/dif_upload/error.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/dif_upload/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/event.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/file_search.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/file_upload.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/formatting.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/fs.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/http.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/logging.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/non_empty.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/progress.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/proguard/mod.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/proguard/upload.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/releases.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/retry.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_default_twenty.snap +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_ignore_missing.snap +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_set_base.snap +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_set_previous_commit.snap +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/snapshots/sentry_cli__utils__vcs__tests__get_commits_from_git.snap +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/source_bundle.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/sourcemaps/inject.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/sourcemaps.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/system.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/ui.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/update.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/value_parsers.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/vcs.rs +0 -0
- {sentry_cli-3.3.0 → sentry_cli-3.3.1}/src/utils/xcode.rs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sentry_cli
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.1
|
|
4
4
|
Summary: A command line utility to work with Sentry.
|
|
5
5
|
Home-page: https://github.com/getsentry/sentry-cli
|
|
6
6
|
Author: Sentry
|
|
@@ -50,7 +50,7 @@ Users who are using Sentry Self-Hosted versions older than 24.11.1 are encourage
|
|
|
50
50
|
| **Sentry Self-Hosted Version** | **Newest Compatible Sentry CLI Version** |
|
|
51
51
|
| ------------------------------ | --------------------------------------------------------------------- |
|
|
52
52
|
| ≥ 24.11.1 | [latest](https://github.com/getsentry/sentry-cli/releases/latest) |
|
|
53
|
-
| < 24.11.1 | [2.58.
|
|
53
|
+
| < 24.11.1 | [2.58.5](https://github.com/getsentry/sentry-cli/releases/tag/2.58.5) |
|
|
54
54
|
|
|
55
55
|
Note that we can only provide support for officially-supported Sentry Self-Hosted versions. We will not backport fixes for older Sentry CLI versions, even if they should be compatible with your self-hosted version.
|
|
56
56
|
|
|
@@ -33,7 +33,7 @@ Users who are using Sentry Self-Hosted versions older than 24.11.1 are encourage
|
|
|
33
33
|
| **Sentry Self-Hosted Version** | **Newest Compatible Sentry CLI Version** |
|
|
34
34
|
| ------------------------------ | --------------------------------------------------------------------- |
|
|
35
35
|
| ≥ 24.11.1 | [latest](https://github.com/getsentry/sentry-cli/releases/latest) |
|
|
36
|
-
| < 24.11.1 | [2.58.
|
|
36
|
+
| < 24.11.1 | [2.58.5](https://github.com/getsentry/sentry-cli/releases/tag/2.58.5) |
|
|
37
37
|
|
|
38
38
|
Note that we can only provide support for officially-supported Sentry Self-Hosted versions. We will not backport fixes for older Sentry CLI versions, even if they should be compatible with your self-hosted version.
|
|
39
39
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sentry_cli
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.1
|
|
4
4
|
Summary: A command line utility to work with Sentry.
|
|
5
5
|
Home-page: https://github.com/getsentry/sentry-cli
|
|
6
6
|
Author: Sentry
|
|
@@ -50,7 +50,7 @@ Users who are using Sentry Self-Hosted versions older than 24.11.1 are encourage
|
|
|
50
50
|
| **Sentry Self-Hosted Version** | **Newest Compatible Sentry CLI Version** |
|
|
51
51
|
| ------------------------------ | --------------------------------------------------------------------- |
|
|
52
52
|
| ≥ 24.11.1 | [latest](https://github.com/getsentry/sentry-cli/releases/latest) |
|
|
53
|
-
| < 24.11.1 | [2.58.
|
|
53
|
+
| < 24.11.1 | [2.58.5](https://github.com/getsentry/sentry-cli/releases/tag/2.58.5) |
|
|
54
54
|
|
|
55
55
|
Note that we can only provide support for officially-supported Sentry Self-Hosted versions. We will not backport fixes for older Sentry CLI versions, even if they should be compatible with your self-hosted version.
|
|
56
56
|
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
//! Data types for the snapshots API.
|
|
2
|
+
|
|
3
|
+
use std::collections::HashMap;
|
|
4
|
+
|
|
5
|
+
use serde::{Deserialize, Serialize};
|
|
6
|
+
use serde_json::Value;
|
|
7
|
+
|
|
8
|
+
const IMAGE_FILE_NAME_FIELD: &str = "image_file_name";
|
|
9
|
+
const WIDTH_FIELD: &str = "width";
|
|
10
|
+
const HEIGHT_FIELD: &str = "height";
|
|
11
|
+
|
|
12
|
+
/// Response from the create snapshot endpoint.
|
|
13
|
+
#[derive(Debug, Deserialize)]
|
|
14
|
+
#[serde(rename_all = "camelCase")]
|
|
15
|
+
pub struct CreateSnapshotResponse {
|
|
16
|
+
pub artifact_id: String,
|
|
17
|
+
pub image_count: u64,
|
|
18
|
+
pub snapshot_url: Option<String>,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Keep in sync with https://github.com/getsentry/sentry/blob/master/src/sentry/preprod/snapshots/manifest.py
|
|
22
|
+
/// Manifest describing a set of snapshot images for an app.
|
|
23
|
+
#[derive(Debug, Serialize)]
|
|
24
|
+
pub struct SnapshotsManifest {
|
|
25
|
+
pub app_id: String,
|
|
26
|
+
pub images: HashMap<String, ImageMetadata>,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Keep in sync with https://github.com/getsentry/sentry/blob/master/src/sentry/preprod/snapshots/manifest.py
|
|
30
|
+
/// Metadata for a single image in a snapshot manifest.
|
|
31
|
+
///
|
|
32
|
+
/// CLI-managed fields (`image_file_name`, `width`, `height`) override any
|
|
33
|
+
/// identically named fields provided by user sidecar metadata.
|
|
34
|
+
#[derive(Debug, Serialize)]
|
|
35
|
+
pub struct ImageMetadata {
|
|
36
|
+
#[serde(flatten)]
|
|
37
|
+
data: HashMap<String, Value>,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
impl ImageMetadata {
|
|
41
|
+
pub fn new(
|
|
42
|
+
image_file_name: String,
|
|
43
|
+
width: u32,
|
|
44
|
+
height: u32,
|
|
45
|
+
mut extra: HashMap<String, Value>,
|
|
46
|
+
) -> Self {
|
|
47
|
+
extra.insert(
|
|
48
|
+
IMAGE_FILE_NAME_FIELD.to_owned(),
|
|
49
|
+
Value::String(image_file_name),
|
|
50
|
+
);
|
|
51
|
+
extra.insert(WIDTH_FIELD.to_owned(), Value::from(width));
|
|
52
|
+
extra.insert(HEIGHT_FIELD.to_owned(), Value::from(height));
|
|
53
|
+
|
|
54
|
+
Self { data: extra }
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
#[cfg(test)]
|
|
59
|
+
mod tests {
|
|
60
|
+
use super::*;
|
|
61
|
+
|
|
62
|
+
use serde_json::json;
|
|
63
|
+
|
|
64
|
+
#[test]
|
|
65
|
+
fn cli_managed_fields_override_sidecar_fields() {
|
|
66
|
+
let extra = serde_json::from_value(json!({
|
|
67
|
+
(IMAGE_FILE_NAME_FIELD): "from-sidecar.png",
|
|
68
|
+
(WIDTH_FIELD): 1,
|
|
69
|
+
(HEIGHT_FIELD): 2,
|
|
70
|
+
"custom": "keep-me"
|
|
71
|
+
}))
|
|
72
|
+
.unwrap();
|
|
73
|
+
|
|
74
|
+
let metadata = ImageMetadata::new("from-cli.png".to_owned(), 100, 200, extra);
|
|
75
|
+
let serialized = serde_json::to_value(metadata).unwrap();
|
|
76
|
+
|
|
77
|
+
let expected = json!({
|
|
78
|
+
(IMAGE_FILE_NAME_FIELD): "from-cli.png",
|
|
79
|
+
(WIDTH_FIELD): 100,
|
|
80
|
+
(HEIGHT_FIELD): 200,
|
|
81
|
+
"custom": "keep-me"
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
assert_eq!(serialized, expected);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
use std::collections::HashMap;
|
|
2
|
-
use std::fs;
|
|
2
|
+
use std::fs::File;
|
|
3
|
+
use std::io::BufReader;
|
|
3
4
|
use std::path::{Path, PathBuf};
|
|
4
5
|
use std::str::FromStr as _;
|
|
5
6
|
|
|
6
7
|
use anyhow::{Context as _, Result};
|
|
7
8
|
use clap::{Arg, ArgMatches, Command};
|
|
8
9
|
use console::style;
|
|
10
|
+
use itertools::Itertools as _;
|
|
9
11
|
use log::{debug, info, warn};
|
|
10
12
|
use objectstore_client::{ClientBuilder, ExpirationPolicy, Usecase};
|
|
11
13
|
use secrecy::ExposeSecret as _;
|
|
14
|
+
use serde_json::Value;
|
|
12
15
|
use sha2::{Digest as _, Sha256};
|
|
13
16
|
use walkdir::WalkDir;
|
|
14
17
|
|
|
@@ -21,6 +24,7 @@ const EXPERIMENTAL_WARNING: &str =
|
|
|
21
24
|
The command is subject to breaking changes, including removal, in any Sentry CLI release.";
|
|
22
25
|
|
|
23
26
|
const IMAGE_EXTENSIONS: &[&str] = &["png", "jpg", "jpeg"];
|
|
27
|
+
const MAX_PIXELS_PER_IMAGE: u64 = 40_000_000;
|
|
24
28
|
|
|
25
29
|
pub fn make_command(command: Command) -> Command {
|
|
26
30
|
command
|
|
@@ -52,6 +56,12 @@ struct ImageInfo {
|
|
|
52
56
|
height: u32,
|
|
53
57
|
}
|
|
54
58
|
|
|
59
|
+
impl ImageInfo {
|
|
60
|
+
fn pixels(&self) -> u64 {
|
|
61
|
+
u64::from(self.width) * u64::from(self.height)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
55
65
|
pub fn execute(matches: &ArgMatches) -> Result<()> {
|
|
56
66
|
eprintln!("{EXPERIMENTAL_WARNING}");
|
|
57
67
|
|
|
@@ -88,6 +98,8 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
|
|
|
88
98
|
if images.len() == 1 { "file" } else { "files" }
|
|
89
99
|
);
|
|
90
100
|
|
|
101
|
+
validate_image_sizes(&images)?;
|
|
102
|
+
|
|
91
103
|
// Upload image files to objectstore
|
|
92
104
|
println!(
|
|
93
105
|
"{} Uploading {} image {}",
|
|
@@ -95,6 +107,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
|
|
|
95
107
|
style(images.len()).yellow(),
|
|
96
108
|
if images.len() == 1 { "file" } else { "files" }
|
|
97
109
|
);
|
|
110
|
+
|
|
98
111
|
let manifest_entries = upload_images(images, &org, &project)?;
|
|
99
112
|
|
|
100
113
|
// Build manifest from discovered images
|
|
@@ -174,11 +187,49 @@ fn collect_image_info(dir: &Path, path: &Path) -> Option<ImageInfo> {
|
|
|
174
187
|
})
|
|
175
188
|
}
|
|
176
189
|
|
|
177
|
-
fn
|
|
190
|
+
fn validate_image_sizes(images: &[ImageInfo]) -> Result<()> {
|
|
191
|
+
let mut violations = images
|
|
192
|
+
.iter()
|
|
193
|
+
.filter(|img| img.pixels() > MAX_PIXELS_PER_IMAGE)
|
|
194
|
+
.map(|img| {
|
|
195
|
+
let path = img.relative_path.display();
|
|
196
|
+
let width = img.width;
|
|
197
|
+
let height = img.height;
|
|
198
|
+
let pixels = img.pixels();
|
|
199
|
+
|
|
200
|
+
format!(" {path} ({width}x{height} = {pixels} pixels)")
|
|
201
|
+
})
|
|
202
|
+
.peekable();
|
|
203
|
+
|
|
204
|
+
if violations.peek().is_some() {
|
|
205
|
+
let violation_messages = violations.join("\n");
|
|
206
|
+
|
|
207
|
+
anyhow::bail!(
|
|
208
|
+
"The following images exceed the maximum pixel limit of {MAX_PIXELS_PER_IMAGE}:\n{violation_messages}",
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
Ok(())
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
fn compute_sha256_hash(path: &Path) -> Result<String> {
|
|
216
|
+
use std::io::Read as _;
|
|
217
|
+
|
|
218
|
+
let mut file = std::fs::File::open(path)
|
|
219
|
+
.with_context(|| format!("Failed to open image for hashing: {}", path.display()))?;
|
|
178
220
|
let mut hasher = Sha256::new();
|
|
179
|
-
|
|
221
|
+
let mut buffer = [0u8; 8192];
|
|
222
|
+
loop {
|
|
223
|
+
let bytes_read = file
|
|
224
|
+
.read(&mut buffer)
|
|
225
|
+
.with_context(|| format!("Failed to read image for hashing: {}", path.display()))?;
|
|
226
|
+
if bytes_read == 0 {
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
229
|
+
hasher.update(&buffer[..bytes_read]);
|
|
230
|
+
}
|
|
180
231
|
let result = hasher.finalize();
|
|
181
|
-
format!("{result:x}")
|
|
232
|
+
Ok(format!("{result:x}"))
|
|
182
233
|
}
|
|
183
234
|
|
|
184
235
|
fn is_hidden(root: &Path, path: &Path) -> bool {
|
|
@@ -196,6 +247,29 @@ fn is_image_file(path: &Path) -> bool {
|
|
|
196
247
|
.unwrap_or(false)
|
|
197
248
|
}
|
|
198
249
|
|
|
250
|
+
/// Reads the companion JSON sidecar for an image, if it exists.
|
|
251
|
+
///
|
|
252
|
+
/// For an image at `path/to/button.png`, looks for `path/to/button.json`.
|
|
253
|
+
/// Returns a map of all key-value pairs from the JSON file.
|
|
254
|
+
fn read_sidecar_metadata(image_path: &Path) -> Result<HashMap<String, Value>> {
|
|
255
|
+
let sidecar_path = image_path.with_extension("json");
|
|
256
|
+
if !sidecar_path.is_file() {
|
|
257
|
+
return Ok(HashMap::new());
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
debug!("Reading sidecar metadata: {}", sidecar_path.display());
|
|
261
|
+
|
|
262
|
+
let sidecar_file = File::open(&sidecar_path)
|
|
263
|
+
.with_context(|| format!("Failed to open sidecar file {}", sidecar_path.display()))?;
|
|
264
|
+
|
|
265
|
+
serde_json::from_reader(BufReader::new(sidecar_file)).with_context(|| {
|
|
266
|
+
format!(
|
|
267
|
+
"Failed to read sidecar file {} as JSON",
|
|
268
|
+
sidecar_path.display()
|
|
269
|
+
)
|
|
270
|
+
})
|
|
271
|
+
}
|
|
272
|
+
|
|
199
273
|
fn upload_images(
|
|
200
274
|
images: Vec<ImageInfo>,
|
|
201
275
|
org: &str,
|
|
@@ -219,9 +293,22 @@ fn upload_images(
|
|
|
219
293
|
.build()?;
|
|
220
294
|
|
|
221
295
|
let mut scope = Usecase::new("preprod").scope();
|
|
222
|
-
|
|
223
|
-
|
|
296
|
+
let (mut org_id, mut project_id): (Option<String>, Option<String>) = (None, None);
|
|
297
|
+
for (key, value) in options.objectstore.scopes.into_iter() {
|
|
298
|
+
scope = scope.push(&key, value.clone());
|
|
299
|
+
if key == "org" {
|
|
300
|
+
org_id = Some(value);
|
|
301
|
+
} else if key == "project" {
|
|
302
|
+
project_id = Some(value);
|
|
303
|
+
}
|
|
224
304
|
}
|
|
305
|
+
let Some(org_id) = org_id else {
|
|
306
|
+
anyhow::bail!("Missing org in UploadOptions scope");
|
|
307
|
+
};
|
|
308
|
+
let Some(project_id) = project_id else {
|
|
309
|
+
anyhow::bail!("Missing project in UploadOptions scope");
|
|
310
|
+
};
|
|
311
|
+
|
|
225
312
|
let session = scope.session(&client)?;
|
|
226
313
|
|
|
227
314
|
let runtime = tokio::runtime::Builder::new_current_thread()
|
|
@@ -236,16 +323,20 @@ fn upload_images(
|
|
|
236
323
|
for image in images {
|
|
237
324
|
debug!("Processing image: {}", image.path.display());
|
|
238
325
|
|
|
239
|
-
let
|
|
240
|
-
|
|
241
|
-
|
|
326
|
+
let hash = compute_sha256_hash(&image.path)?;
|
|
327
|
+
let file = runtime
|
|
328
|
+
.block_on(tokio::fs::File::open(&image.path))
|
|
329
|
+
.with_context(|| {
|
|
330
|
+
format!("Failed to open image for upload: {}", image.path.display())
|
|
331
|
+
})?;
|
|
242
332
|
|
|
243
|
-
|
|
333
|
+
let key = format!("{org_id}/{project_id}/{hash}");
|
|
334
|
+
info!("Queueing {} as {key}", image.relative_path.display());
|
|
244
335
|
|
|
245
336
|
many_builder = many_builder.push(
|
|
246
337
|
session
|
|
247
|
-
.
|
|
248
|
-
.key(&
|
|
338
|
+
.put_file(file)
|
|
339
|
+
.key(&key)
|
|
249
340
|
.expiration_policy(expiration),
|
|
250
341
|
);
|
|
251
342
|
|
|
@@ -255,13 +346,15 @@ fn upload_images(
|
|
|
255
346
|
.unwrap_or_default()
|
|
256
347
|
.to_string_lossy()
|
|
257
348
|
.into_owned();
|
|
349
|
+
|
|
350
|
+
let extra = read_sidecar_metadata(&image.path).unwrap_or_else(|err| {
|
|
351
|
+
warn!("Error reading sidecar metadata, ignoring it instead: {err:#}");
|
|
352
|
+
HashMap::new()
|
|
353
|
+
});
|
|
354
|
+
|
|
258
355
|
manifest_entries.insert(
|
|
259
356
|
hash,
|
|
260
|
-
ImageMetadata
|
|
261
|
-
image_file_name,
|
|
262
|
-
width: image.width,
|
|
263
|
-
height: image.height,
|
|
264
|
-
},
|
|
357
|
+
ImageMetadata::new(image_file_name, image.width, image.height, extra),
|
|
265
358
|
);
|
|
266
359
|
}
|
|
267
360
|
|
|
@@ -288,3 +381,28 @@ fn upload_images(
|
|
|
288
381
|
}
|
|
289
382
|
}
|
|
290
383
|
}
|
|
384
|
+
|
|
385
|
+
#[cfg(test)]
|
|
386
|
+
mod tests {
|
|
387
|
+
use super::*;
|
|
388
|
+
|
|
389
|
+
fn make_image(width: u32, height: u32) -> ImageInfo {
|
|
390
|
+
ImageInfo {
|
|
391
|
+
path: PathBuf::from("img.png"),
|
|
392
|
+
relative_path: PathBuf::from("img.png"),
|
|
393
|
+
width,
|
|
394
|
+
height,
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
#[test]
|
|
399
|
+
fn test_validate_image_sizes_at_limit_passes() {
|
|
400
|
+
assert!(validate_image_sizes(&[make_image(8000, 5000)]).is_ok());
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
#[test]
|
|
404
|
+
fn test_validate_image_sizes_over_limit_fails() {
|
|
405
|
+
let err = validate_image_sizes(&[make_image(8001, 5000)]).unwrap_err();
|
|
406
|
+
assert!(err.to_string().contains("exceed the maximum pixel limit"));
|
|
407
|
+
}
|
|
408
|
+
}
|
|
@@ -95,10 +95,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
|
|
|
95
95
|
// them all up.
|
|
96
96
|
for path in &paths {
|
|
97
97
|
match ByteView::open(path) {
|
|
98
|
-
Ok(byteview) =>
|
|
99
|
-
Ok(mapping) => mappings.push(mapping),
|
|
100
|
-
Err(e) => eprintln!("warning: ignoring proguard mapping '{path}': {e}"),
|
|
101
|
-
},
|
|
98
|
+
Ok(byteview) => mappings.push(ProguardMapping::from(byteview)),
|
|
102
99
|
Err(ref err) if err.kind() == io::ErrorKind::NotFound => {
|
|
103
100
|
eprintln!(
|
|
104
101
|
"warning: proguard mapping '{path}' does not exist. This \
|
|
@@ -29,8 +29,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
|
|
|
29
29
|
|
|
30
30
|
let byteview = ByteView::open(path)
|
|
31
31
|
.with_context(|| format!("failed to open proguard mapping '{path}'"))?;
|
|
32
|
-
let mapping = ProguardMapping::
|
|
33
|
-
.with_context(|| format!("failed to parse proguard mapping '{path}'"))?;
|
|
32
|
+
let mapping = ProguardMapping::from(byteview);
|
|
34
33
|
|
|
35
34
|
println!("{}", mapping.uuid());
|
|
36
35
|
Ok(())
|
|
@@ -380,24 +380,22 @@ impl<'a> DifFile<'a> {
|
|
|
380
380
|
pub fn is_usable(&self) -> bool {
|
|
381
381
|
match self {
|
|
382
382
|
DifFile::Archive(_) => self.has_ids() && self.features().has_some(),
|
|
383
|
-
DifFile::Proguard(
|
|
383
|
+
DifFile::Proguard(..) => true,
|
|
384
384
|
}
|
|
385
385
|
}
|
|
386
386
|
|
|
387
387
|
pub fn get_problem(&self) -> Option<&'static str> {
|
|
388
388
|
if self.is_usable() {
|
|
389
|
-
None
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
DifFile::Proguard(..) => "missing line information",
|
|
400
|
-
})
|
|
389
|
+
return None;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
match self {
|
|
393
|
+
DifFile::Archive(..) => Some(if !self.has_ids() {
|
|
394
|
+
"missing debug identifier, likely stripped"
|
|
395
|
+
} else {
|
|
396
|
+
"missing debug or unwind information"
|
|
397
|
+
}),
|
|
398
|
+
DifFile::Proguard(..) => None,
|
|
401
399
|
}
|
|
402
400
|
}
|
|
403
401
|
|
|
@@ -2,23 +2,16 @@ use std::borrow::Cow;
|
|
|
2
2
|
use std::fmt::{Display, Formatter, Result as FmtResult};
|
|
3
3
|
|
|
4
4
|
use symbolic::common::{ByteView, DebugId};
|
|
5
|
-
use thiserror::Error;
|
|
6
5
|
use uuid::Uuid;
|
|
7
6
|
|
|
8
7
|
use crate::utils::chunks::Assemblable;
|
|
9
8
|
|
|
10
|
-
#[derive(Debug, Error)]
|
|
11
|
-
pub enum ProguardMappingError {
|
|
12
|
-
#[error("Proguard mapping does not contain line information")]
|
|
13
|
-
MissingLineInfo,
|
|
14
|
-
}
|
|
15
|
-
|
|
16
9
|
pub struct ProguardMapping<'a> {
|
|
17
10
|
bytes: ByteView<'a>,
|
|
18
11
|
uuid: Uuid,
|
|
19
12
|
}
|
|
20
13
|
|
|
21
|
-
impl
|
|
14
|
+
impl ProguardMapping<'_> {
|
|
22
15
|
/// Get the UUID of the mapping.
|
|
23
16
|
pub fn uuid(&self) -> Uuid {
|
|
24
17
|
self.uuid
|
|
@@ -29,31 +22,13 @@ impl<'a> ProguardMapping<'a> {
|
|
|
29
22
|
pub fn force_uuid(&mut self, uuid: Uuid) {
|
|
30
23
|
self.uuid = uuid;
|
|
31
24
|
}
|
|
32
|
-
|
|
33
|
-
/// Create a new `ProguardMapping` from a `ByteView`.
|
|
34
|
-
/// Not public because we want to ensure that the `ByteView` contains line
|
|
35
|
-
/// information, and this method does not check for that. To create a
|
|
36
|
-
/// `ProguardMapping` externally, use the `TryFrom<ByteView>` implementation.
|
|
37
|
-
fn new(bytes: ByteView<'a>, uuid: Uuid) -> Self {
|
|
38
|
-
Self { bytes, uuid }
|
|
39
|
-
}
|
|
40
25
|
}
|
|
41
26
|
|
|
42
|
-
impl<'a>
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
/// Try to create a `ProguardMapping` from a `ByteView`.
|
|
46
|
-
/// The method returns an error if the mapping does not contain
|
|
47
|
-
/// line information.
|
|
48
|
-
fn try_from(value: ByteView<'a>) -> Result<Self, Self::Error> {
|
|
27
|
+
impl<'a> From<ByteView<'a>> for ProguardMapping<'a> {
|
|
28
|
+
fn from(value: ByteView<'a>) -> Self {
|
|
49
29
|
let mapping = ::proguard::ProguardMapping::new(&value);
|
|
50
|
-
|
|
51
|
-
if !mapping.has_line_info() {
|
|
52
|
-
return Err(ProguardMappingError::MissingLineInfo);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
30
|
let uuid = mapping.uuid();
|
|
56
|
-
|
|
31
|
+
Self { bytes: value, uuid }
|
|
57
32
|
}
|
|
58
33
|
}
|
|
59
34
|
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
//! Data types for the snapshots API.
|
|
2
|
-
|
|
3
|
-
use std::collections::HashMap;
|
|
4
|
-
|
|
5
|
-
use serde::{Deserialize, Serialize};
|
|
6
|
-
|
|
7
|
-
/// Response from the create snapshot endpoint.
|
|
8
|
-
#[derive(Debug, Deserialize)]
|
|
9
|
-
#[serde(rename_all = "camelCase")]
|
|
10
|
-
pub struct CreateSnapshotResponse {
|
|
11
|
-
pub artifact_id: String,
|
|
12
|
-
pub image_count: u64,
|
|
13
|
-
pub snapshot_url: Option<String>,
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Keep in sync with https://github.com/getsentry/sentry/blob/master/src/sentry/preprod/snapshots/manifest.py
|
|
17
|
-
/// Manifest describing a set of snapshot images for an app.
|
|
18
|
-
#[derive(Debug, Serialize)]
|
|
19
|
-
pub struct SnapshotsManifest {
|
|
20
|
-
pub app_id: String,
|
|
21
|
-
pub images: HashMap<String, ImageMetadata>,
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Keep in sync with https://github.com/getsentry/sentry/blob/master/src/sentry/preprod/snapshots/manifest.py
|
|
25
|
-
/// Metadata for a single image in a snapshot manifest.
|
|
26
|
-
#[derive(Debug, Serialize)]
|
|
27
|
-
pub struct ImageMetadata {
|
|
28
|
-
pub image_file_name: String,
|
|
29
|
-
pub width: u32,
|
|
30
|
-
pub height: u32,
|
|
31
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|