sentry-cli 3.3.1__tar.gz → 3.3.2__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.
Files changed (175) hide show
  1. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/Cargo.lock +1 -1
  2. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/Cargo.toml +1 -1
  3. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/PKG-INFO +1 -1
  4. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/sentry_cli.egg-info/PKG-INFO +1 -1
  5. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/sentry_cli.egg-info/SOURCES.txt +1 -0
  6. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/data_types/snapshots.rs +5 -1
  7. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/build/snapshots.rs +11 -0
  8. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/build/upload.rs +2 -259
  9. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/args.rs +67 -0
  10. sentry_cli-3.3.2/src/utils/build_vcs.rs +205 -0
  11. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/mod.rs +1 -0
  12. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/LICENSE +0 -0
  13. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/MANIFEST.in +0 -0
  14. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/README.md +0 -0
  15. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/apple-catalog-parsing/AGENTS.md +0 -0
  16. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/apple-catalog-parsing/CLAUDE.md +0 -0
  17. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/apple-catalog-parsing/Cargo.toml +0 -0
  18. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/apple-catalog-parsing/build.rs +0 -0
  19. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Package.swift +0 -0
  20. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/AssetCatalogParser/AssetCatalogReader.swift +0 -0
  21. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/include/safeValueForKey.h +0 -0
  22. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Sources/ObjcSupport/safeValueForKey.m +0 -0
  23. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/AssetCatalogParserTests.swift +0 -0
  24. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/Resources/test.xcarchive/Info.plist +0 -0
  25. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/apple-catalog-parsing/native/swift/AssetCatalogParser/Tests/AssetCatalogParserTests/Resources/test.xcarchive/Products/Applications/DemoApp.app/Assets.car +0 -0
  26. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/apple-catalog-parsing/src/asset_catalog.rs +0 -0
  27. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/apple-catalog-parsing/src/lib.rs +0 -0
  28. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/build.rs +0 -0
  29. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/pyproject.toml +0 -0
  30. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/sentry_cli.egg-info/dependency_links.txt +0 -0
  31. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/sentry_cli.egg-info/top_level.txt +0 -0
  32. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/setup.cfg +0 -0
  33. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/setup.py +0 -0
  34. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/AGENTS.md +0 -0
  35. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/CLAUDE.md +0 -0
  36. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/connection_manager.rs +0 -0
  37. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/data_types/chunking/artifact.rs +0 -0
  38. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/data_types/chunking/build.rs +0 -0
  39. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/data_types/chunking/compression.rs +0 -0
  40. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/data_types/chunking/dif.rs +0 -0
  41. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/data_types/chunking/file_state.rs +0 -0
  42. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/data_types/chunking/hash_algorithm.rs +0 -0
  43. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/data_types/chunking/mod.rs +0 -0
  44. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/data_types/chunking/upload/mod.rs +0 -0
  45. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/data_types/chunking/upload/options.rs +0 -0
  46. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/data_types/deploy.rs +0 -0
  47. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/data_types/mod.rs +0 -0
  48. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/encoding.rs +0 -0
  49. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/envelopes_api.rs +0 -0
  50. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/errors/api_error.rs +0 -0
  51. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/errors/mod.rs +0 -0
  52. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/errors/sentry_error.rs +0 -0
  53. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/mod.rs +0 -0
  54. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/pagination.rs +0 -0
  55. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/api/serialization.rs +0 -0
  56. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/bashsupport.sh +0 -0
  57. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/bash_hook.rs +0 -0
  58. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/build/mod.rs +0 -0
  59. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/dart_symbol_map/mod.rs +0 -0
  60. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/dart_symbol_map/upload.rs +0 -0
  61. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/debug_files/bundle_jvm.rs +0 -0
  62. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/debug_files/bundle_sources.rs +0 -0
  63. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/debug_files/check.rs +0 -0
  64. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/debug_files/find.rs +0 -0
  65. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/debug_files/mod.rs +0 -0
  66. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/debug_files/print_sources.rs +0 -0
  67. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/debug_files/upload.rs +0 -0
  68. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/deploys/list.rs +0 -0
  69. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/deploys/mod.rs +0 -0
  70. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/deploys/new.rs +0 -0
  71. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/derive_parser.rs +0 -0
  72. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/events/list.rs +0 -0
  73. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/events/mod.rs +0 -0
  74. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/info.rs +0 -0
  75. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/issues/list.rs +0 -0
  76. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/issues/mod.rs +0 -0
  77. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/issues/mute.rs +0 -0
  78. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/issues/resolve.rs +0 -0
  79. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/issues/unresolve.rs +0 -0
  80. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/login.rs +0 -0
  81. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/logs/list.rs +0 -0
  82. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/logs/mod.rs +0 -0
  83. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/mod.rs +0 -0
  84. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/monitors/list.rs +0 -0
  85. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/monitors/mod.rs +0 -0
  86. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/monitors/run.rs +0 -0
  87. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/organizations/list.rs +0 -0
  88. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/organizations/mod.rs +0 -0
  89. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/proguard/mod.rs +0 -0
  90. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/proguard/upload.rs +0 -0
  91. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/proguard/uuid.rs +0 -0
  92. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/projects/list.rs +0 -0
  93. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/projects/mod.rs +0 -0
  94. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/react_native/gradle.rs +0 -0
  95. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/react_native/mod.rs +0 -0
  96. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/react_native/xcode.rs +0 -0
  97. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/releases/archive.rs +0 -0
  98. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/releases/delete.rs +0 -0
  99. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/releases/finalize.rs +0 -0
  100. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/releases/info.rs +0 -0
  101. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/releases/list.rs +0 -0
  102. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/releases/mod.rs +0 -0
  103. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/releases/new.rs +0 -0
  104. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/releases/propose_version.rs +0 -0
  105. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/releases/restore.rs +0 -0
  106. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/releases/set_commits.rs +0 -0
  107. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/repos/list.rs +0 -0
  108. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/repos/mod.rs +0 -0
  109. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/send_envelope.rs +0 -0
  110. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/send_event.rs +0 -0
  111. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/send_metric/common_args.rs +0 -0
  112. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/send_metric/increment.rs +0 -0
  113. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/send_metric/mod.rs +0 -0
  114. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/send_metric/set.rs +0 -0
  115. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/sourcemaps/inject.rs +0 -0
  116. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/sourcemaps/mod.rs +0 -0
  117. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/sourcemaps/resolve.rs +0 -0
  118. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/sourcemaps/upload.rs +0 -0
  119. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/uninstall.rs +0 -0
  120. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/update.rs +0 -0
  121. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/upload_dif.rs +0 -0
  122. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/upload_dsym.rs +0 -0
  123. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/commands/upload_proguard.rs +0 -0
  124. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/config.rs +0 -0
  125. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/constants.rs +0 -0
  126. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/main.rs +0 -0
  127. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/android.rs +0 -0
  128. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/auth_token/auth_token_impl.rs +0 -0
  129. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/auth_token/error.rs +0 -0
  130. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/auth_token/mod.rs +0 -0
  131. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/auth_token/org_auth_token.rs +0 -0
  132. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/auth_token/redacting.rs +0 -0
  133. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/auth_token/test.rs +0 -0
  134. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/auth_token/user_auth_token.rs +0 -0
  135. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/build/apple.rs +0 -0
  136. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/build/mod.rs +0 -0
  137. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/build/normalize.rs +0 -0
  138. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/build/validation.rs +0 -0
  139. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/chunks/mod.rs +0 -0
  140. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/chunks/options.rs +0 -0
  141. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/chunks/types.rs +0 -0
  142. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/chunks/upload.rs +0 -0
  143. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/ci.rs +0 -0
  144. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/cordova.rs +0 -0
  145. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/dif.rs +0 -0
  146. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/dif_upload/error.rs +0 -0
  147. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/dif_upload/mod.rs +0 -0
  148. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/event.rs +0 -0
  149. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/file_search.rs +0 -0
  150. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/file_upload.rs +0 -0
  151. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/formatting.rs +0 -0
  152. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/fs.rs +0 -0
  153. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/http.rs +0 -0
  154. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/logging.rs +0 -0
  155. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/non_empty.rs +0 -0
  156. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/progress.rs +0 -0
  157. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/proguard/mapping.rs +0 -0
  158. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/proguard/mod.rs +0 -0
  159. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/proguard/upload.rs +0 -0
  160. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/releases.rs +0 -0
  161. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/retry.rs +0 -0
  162. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_default_twenty.snap +0 -0
  163. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_ignore_missing.snap +0 -0
  164. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_set_base.snap +0 -0
  165. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/snapshots/sentry_cli__utils__vcs__tests__generate_patch_set_previous_commit.snap +0 -0
  166. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/snapshots/sentry_cli__utils__vcs__tests__get_commits_from_git.snap +0 -0
  167. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/source_bundle.rs +0 -0
  168. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/sourcemaps/inject.rs +0 -0
  169. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/sourcemaps.rs +0 -0
  170. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/system.rs +0 -0
  171. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/ui.rs +0 -0
  172. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/update.rs +0 -0
  173. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/value_parsers.rs +0 -0
  174. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/vcs.rs +0 -0
  175. {sentry_cli-3.3.1 → sentry_cli-3.3.2}/src/utils/xcode.rs +0 -0
@@ -3414,7 +3414,7 @@ dependencies = [
3414
3414
 
3415
3415
  [[package]]
3416
3416
  name = "sentry-cli"
3417
- version = "3.3.1"
3417
+ version = "3.3.2"
3418
3418
  dependencies = [
3419
3419
  "anyhow",
3420
3420
  "anylog",
@@ -1,7 +1,7 @@
1
1
  [package]
2
2
  build = "build.rs"
3
3
  name = "sentry-cli"
4
- version = "3.3.1"
4
+ version = "3.3.2"
5
5
  edition = "2021"
6
6
  rust-version = "1.91"
7
7
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry_cli
3
- Version: 3.3.1
3
+ Version: 3.3.2
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry_cli
3
- Version: 3.3.1
3
+ Version: 3.3.2
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
@@ -122,6 +122,7 @@ src/commands/sourcemaps/resolve.rs
122
122
  src/commands/sourcemaps/upload.rs
123
123
  src/utils/android.rs
124
124
  src/utils/args.rs
125
+ src/utils/build_vcs.rs
125
126
  src/utils/ci.rs
126
127
  src/utils/cordova.rs
127
128
  src/utils/dif.rs
@@ -5,6 +5,8 @@ use std::collections::HashMap;
5
5
  use serde::{Deserialize, Serialize};
6
6
  use serde_json::Value;
7
7
 
8
+ use super::VcsInfo;
9
+
8
10
  const IMAGE_FILE_NAME_FIELD: &str = "image_file_name";
9
11
  const WIDTH_FIELD: &str = "width";
10
12
  const HEIGHT_FIELD: &str = "height";
@@ -21,9 +23,11 @@ pub struct CreateSnapshotResponse {
21
23
  // Keep in sync with https://github.com/getsentry/sentry/blob/master/src/sentry/preprod/snapshots/manifest.py
22
24
  /// Manifest describing a set of snapshot images for an app.
23
25
  #[derive(Debug, Serialize)]
24
- pub struct SnapshotsManifest {
26
+ pub struct SnapshotsManifest<'a> {
25
27
  pub app_id: String,
26
28
  pub images: HashMap<String, ImageMetadata>,
29
+ #[serde(flatten)]
30
+ pub vcs_info: VcsInfo<'a>,
27
31
  }
28
32
 
29
33
  // Keep in sync with https://github.com/getsentry/sentry/blob/master/src/sentry/preprod/snapshots/manifest.py
@@ -18,6 +18,8 @@ use walkdir::WalkDir;
18
18
  use crate::api::{Api, CreateSnapshotResponse, ImageMetadata, SnapshotsManifest};
19
19
  use crate::config::{Auth, Config};
20
20
  use crate::utils::args::ArgExt as _;
21
+ use crate::utils::build_vcs::collect_git_metadata;
22
+ use crate::utils::ci::is_ci;
21
23
 
22
24
  const EXPERIMENTAL_WARNING: &str =
23
25
  "[EXPERIMENTAL] The \"build snapshots\" command is experimental. \
@@ -47,6 +49,7 @@ pub fn make_command(command: Command) -> Command {
47
49
  .help("The application identifier.")
48
50
  .required(true),
49
51
  )
52
+ .git_metadata_args()
50
53
  }
51
54
 
52
55
  struct ImageInfo {
@@ -80,6 +83,13 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
80
83
  anyhow::bail!("Path is not a directory: {}", dir_path.display());
81
84
  }
82
85
 
86
+ // Collect git metadata if running in CI, unless explicitly enabled or disabled.
87
+ let should_collect_git_metadata =
88
+ matches.get_flag("force_git_metadata") || (!matches.get_flag("no_git_metadata") && is_ci());
89
+
90
+ // Always collect git metadata, but only perform automatic inference when enabled
91
+ let vcs_info = collect_git_metadata(matches, &config, should_collect_git_metadata);
92
+
83
93
  debug!("Scanning for images in: {}", dir_path.display());
84
94
  debug!("Organization: {org}");
85
95
  debug!("Project: {project}");
@@ -114,6 +124,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
114
124
  let manifest = SnapshotsManifest {
115
125
  app_id: app_id.clone(),
116
126
  images: manifest_entries,
127
+ vcs_info,
117
128
  };
118
129
 
119
130
  // POST manifest to API
@@ -1,4 +1,3 @@
1
- use std::borrow::Cow;
2
1
  use std::io::Write as _;
3
2
  use std::path::Path;
4
3
  use std::thread;
@@ -8,7 +7,6 @@ use anyhow::{anyhow, bail, Context as _, Result};
8
7
  use clap::{Arg, ArgAction, ArgMatches, Command};
9
8
  use indicatif::ProgressStyle;
10
9
  use log::{debug, info, warn};
11
- use sha1_smol::Digest;
12
10
  use symbolic::common::ByteView;
13
11
  use zip::write::SimpleFileOptions;
14
12
  use zip::{DateTime, ZipWriter};
@@ -22,17 +20,13 @@ use crate::utils::build::{handle_asset_catalogs, ipa_to_xcarchive, is_apple_app,
22
20
  use crate::utils::build::{
23
21
  is_aab_file, is_apk_file, is_zip_file, normalize_directory, write_version_metadata,
24
22
  };
23
+ use crate::utils::build_vcs::collect_git_metadata;
25
24
  use crate::utils::chunks::{upload_chunks, Chunk, ASSEMBLE_POLL_INTERVAL};
26
25
  use crate::utils::ci::is_ci;
27
26
  use crate::utils::fs::get_sha1_checksums;
28
27
  use crate::utils::fs::TempDir;
29
28
  use crate::utils::fs::TempFile;
30
29
  use crate::utils::progress::ProgressBar;
31
- use crate::utils::vcs::{
32
- self, get_github_base_ref, get_github_head_ref, get_github_pr_number, get_provider_from_remote,
33
- get_repo_from_remote_preserve_case, git_repo_base_ref, git_repo_base_repo_name_preserve_case,
34
- git_repo_head_ref, git_repo_remote_url,
35
- };
36
30
 
37
31
  pub fn make_command(command: Command) -> Command {
38
32
  #[cfg(all(target_os = "macos", target_arch = "aarch64"))]
@@ -54,51 +48,7 @@ pub fn make_command(command: Command) -> Command {
54
48
  .action(ArgAction::Append)
55
49
  .required(true),
56
50
  )
57
- .arg(
58
- Arg::new("head_sha")
59
- .long("head-sha")
60
- .value_parser(parse_sha_allow_empty)
61
- .help("The VCS commit sha to use for the upload. If not provided, the current commit sha will be used.")
62
- )
63
- .arg(
64
- Arg::new("base_sha")
65
- .long("base-sha")
66
- .value_parser(parse_sha_allow_empty)
67
- .help("The VCS commit's base sha to use for the upload. If not provided, the merge-base of the current and remote branch will be used.")
68
- )
69
- .arg(
70
- Arg::new("vcs_provider")
71
- .long("vcs-provider")
72
- .help("The VCS provider to use for the upload. If not provided, the current provider will be used.")
73
- )
74
- .arg(
75
- Arg::new("head_repo_name")
76
- .long("head-repo-name")
77
- .help("The name of the git repository to use for the upload (e.g. organization/repository). If not provided, the current repository will be used.")
78
- )
79
- .arg(
80
- Arg::new("base_repo_name")
81
- .long("base-repo-name")
82
- .help("The name of the git repository to use for the upload (e.g. organization/repository). If not provided, the current repository will be used.")
83
- )
84
- .arg(
85
- Arg::new("head_ref")
86
- .long("head-ref")
87
- .help("The reference (branch) to use for the upload. If not provided, the current reference will be used.")
88
- )
89
- .arg(
90
- Arg::new("base_ref")
91
- .long("base-ref")
92
- .help("The base reference (branch) to use for the upload. If not provided, the merge-base with the remote tracking branch will be used.")
93
- )
94
- .arg(
95
- Arg::new("pr_number")
96
- .long("pr-number")
97
- .value_parser(clap::value_parser!(u32))
98
- .help("The pull request number to use for the upload. If not provided and running \
99
- in a pull_request-triggered GitHub Actions workflow, the PR number will be automatically \
100
- detected from GitHub Actions environment variables.")
101
- )
51
+ .git_metadata_args()
102
52
  .arg(
103
53
  Arg::new("build_configuration")
104
54
  .long("build-configuration")
@@ -119,22 +69,6 @@ pub fn make_command(command: Command) -> Command {
119
69
  for each other.",
120
70
  )
121
71
  )
122
- .arg(
123
- Arg::new("force_git_metadata")
124
- .long("force-git-metadata")
125
- .action(ArgAction::SetTrue)
126
- .conflicts_with("no_git_metadata")
127
- .help("Force collection and sending of git metadata (branch, commit, etc.). \
128
- If neither this nor --no-git-metadata is specified, git metadata is \
129
- automatically collected when running in most CI environments.")
130
- )
131
- .arg(
132
- Arg::new("no_git_metadata")
133
- .long("no-git-metadata")
134
- .action(ArgAction::SetTrue)
135
- .conflicts_with("force_git_metadata")
136
- .help("Disable collection and sending of git metadata.")
137
- )
138
72
  }
139
73
 
140
74
  /// Parse plugin info from SENTRY_PIPELINE environment variable.
@@ -309,181 +243,6 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
309
243
  Ok(())
310
244
  }
311
245
 
312
- /// Collects git metadata from arguments and VCS introspection.
313
- ///
314
- /// When `auto_collect` is false, only explicitly provided values are collected;
315
- /// automatic inference from git repository and CI environment is skipped.
316
- fn collect_git_metadata(
317
- matches: &ArgMatches,
318
- config: &Config,
319
- auto_collect: bool,
320
- ) -> VcsInfo<'static> {
321
- let head_sha = matches
322
- .get_one::<Option<Digest>>("head_sha")
323
- .map(|d| d.as_ref().cloned())
324
- .or_else(|| auto_collect.then(|| vcs::find_head_sha().ok()))
325
- .flatten();
326
-
327
- let cached_remote = config.get_cached_vcs_remote();
328
- let (vcs_provider, head_repo_name, head_ref, base_ref, base_repo_name) = {
329
- let repo = if auto_collect {
330
- git2::Repository::open_from_env().ok()
331
- } else {
332
- None
333
- };
334
- let repo_ref = repo.as_ref();
335
- let remote_url = repo_ref.and_then(|repo| git_repo_remote_url(repo, &cached_remote).ok());
336
-
337
- let vcs_provider = matches
338
- .get_one("vcs_provider")
339
- .cloned()
340
- .or_else(|| {
341
- auto_collect
342
- .then(|| remote_url.as_ref().map(|url| get_provider_from_remote(url)))?
343
- })
344
- .unwrap_or_default();
345
-
346
- let head_repo_name = matches
347
- .get_one("head_repo_name")
348
- .cloned()
349
- .or_else(|| {
350
- auto_collect.then(|| {
351
- remote_url
352
- .as_ref()
353
- .map(|url| get_repo_from_remote_preserve_case(url))
354
- })?
355
- })
356
- .unwrap_or_default();
357
-
358
- let head_ref = matches
359
- .get_one("head_ref")
360
- .cloned()
361
- .or_else(|| auto_collect.then(get_github_head_ref)?)
362
- .or_else(|| {
363
- auto_collect.then(|| {
364
- repo_ref.and_then(|r| match git_repo_head_ref(r) {
365
- Ok(ref_name) => {
366
- debug!("Found current branch reference: {ref_name}");
367
- Some(ref_name)
368
- }
369
- Err(e) => {
370
- debug!("No valid branch reference found (likely detached HEAD): {e}");
371
- None
372
- }
373
- })
374
- })?
375
- })
376
- .unwrap_or_default();
377
-
378
- let base_ref = matches
379
- .get_one("base_ref")
380
- .cloned()
381
- .or_else(|| auto_collect.then(get_github_base_ref)?)
382
- .or_else(|| {
383
- auto_collect.then(|| {
384
- repo_ref.and_then(|r| match git_repo_base_ref(r, &cached_remote) {
385
- Ok(base_ref_name) => {
386
- debug!("Found base reference: {base_ref_name}");
387
- Some(base_ref_name)
388
- }
389
- Err(e) => {
390
- info!("Could not detect base branch reference: {e}");
391
- None
392
- }
393
- })
394
- })?
395
- })
396
- .unwrap_or_default();
397
-
398
- let base_repo_name = matches
399
- .get_one("base_repo_name")
400
- .cloned()
401
- .or_else(|| {
402
- auto_collect.then(|| {
403
- repo_ref.and_then(|r| match git_repo_base_repo_name_preserve_case(r) {
404
- Ok(Some(base_repo_name)) => {
405
- debug!("Found base repository name: {base_repo_name}");
406
- Some(base_repo_name)
407
- }
408
- Ok(None) => {
409
- debug!("No base repository found - not a fork");
410
- None
411
- }
412
- Err(e) => {
413
- warn!("Could not detect base repository name: {e}");
414
- None
415
- }
416
- })
417
- })?
418
- })
419
- .unwrap_or_default();
420
-
421
- (
422
- vcs_provider,
423
- head_repo_name,
424
- head_ref,
425
- base_ref,
426
- base_repo_name,
427
- )
428
- };
429
-
430
- let base_sha_from_user = matches.get_one::<Option<Digest>>("base_sha").is_some();
431
- let base_ref_from_user = matches.get_one::<String>("base_ref").is_some();
432
-
433
- let mut base_sha = matches
434
- .get_one::<Option<Digest>>("base_sha")
435
- .map(|d| d.as_ref().cloned())
436
- .or_else(|| {
437
- if auto_collect {
438
- Some(
439
- vcs::find_base_sha(&cached_remote)
440
- .inspect_err(|e| debug!("Error finding base SHA: {e}"))
441
- .ok()
442
- .flatten(),
443
- )
444
- } else {
445
- None
446
- }
447
- })
448
- .flatten();
449
-
450
- let mut base_ref = base_ref;
451
-
452
- // If base_sha equals head_sha and both were auto-inferred, skip setting base_sha and base_ref
453
- if !base_sha_from_user
454
- && !base_ref_from_user
455
- && base_sha.is_some()
456
- && head_sha.is_some()
457
- && base_sha == head_sha
458
- {
459
- debug!(
460
- "Base SHA equals head SHA ({}), and both were auto-inferred. Skipping base_sha and base_ref, but keeping head_sha.",
461
- base_sha.expect("base_sha is Some at this point")
462
- );
463
- base_sha = None;
464
- base_ref = "".into();
465
- }
466
-
467
- let pr_number = matches.get_one("pr_number").copied().or_else(|| {
468
- if auto_collect {
469
- get_github_pr_number()
470
- } else {
471
- None
472
- }
473
- });
474
-
475
- VcsInfo {
476
- head_sha,
477
- base_sha,
478
- vcs_provider: Cow::Owned(vcs_provider),
479
- head_repo_name: Cow::Owned(head_repo_name),
480
- base_repo_name: Cow::Owned(base_repo_name),
481
- head_ref: Cow::Owned(head_ref),
482
- base_ref: Cow::Owned(base_ref),
483
- pr_number,
484
- }
485
- }
486
-
487
246
  fn handle_file(
488
247
  path: &Path,
489
248
  byteview: &ByteView,
@@ -709,22 +468,6 @@ fn upload_file(
709
468
  }
710
469
  }
711
470
 
712
- /// Utility function to parse a SHA1 digest, allowing empty strings.
713
- ///
714
- /// Empty strings result in Ok(None), otherwise we return the parsed digest
715
- /// or an error if the SHA is invalid.
716
- fn parse_sha_allow_empty(sha: &str) -> Result<Option<Digest>> {
717
- if sha.is_empty() {
718
- return Ok(None);
719
- }
720
-
721
- let digest = sha
722
- .parse()
723
- .with_context(|| format!("{sha} is not a valid SHA1 digest"))?;
724
-
725
- Ok(Some(digest))
726
- }
727
-
728
471
  #[cfg(not(windows))]
729
472
  #[cfg(test)]
730
473
  mod tests {
@@ -86,6 +86,7 @@ pub trait ArgExt: Sized {
86
86
  fn project_arg(self, multiple: bool) -> Self;
87
87
  fn release_arg(self) -> Self;
88
88
  fn version_arg(self, global: bool) -> Self;
89
+ fn git_metadata_args(self) -> Self;
89
90
  }
90
91
 
91
92
  impl ArgExt for Command {
@@ -142,4 +143,70 @@ impl ArgExt for Command {
142
143
  .help("The version of the release"),
143
144
  )
144
145
  }
146
+
147
+ fn git_metadata_args(self) -> Command {
148
+ use crate::utils::build_vcs::parse_sha_allow_empty;
149
+
150
+ self.arg(
151
+ Arg::new("head_sha")
152
+ .long("head-sha")
153
+ .value_parser(parse_sha_allow_empty)
154
+ .help("The VCS commit sha to use for the upload. If not provided, the current commit sha will be used.")
155
+ )
156
+ .arg(
157
+ Arg::new("base_sha")
158
+ .long("base-sha")
159
+ .value_parser(parse_sha_allow_empty)
160
+ .help("The VCS commit's base sha to use for the upload. If not provided, the merge-base of the current and remote branch will be used.")
161
+ )
162
+ .arg(
163
+ Arg::new("vcs_provider")
164
+ .long("vcs-provider")
165
+ .help("The VCS provider to use for the upload. If not provided, the current provider will be used.")
166
+ )
167
+ .arg(
168
+ Arg::new("head_repo_name")
169
+ .long("head-repo-name")
170
+ .help("The name of the git repository to use for the upload (e.g. organization/repository). If not provided, the current repository will be used.")
171
+ )
172
+ .arg(
173
+ Arg::new("base_repo_name")
174
+ .long("base-repo-name")
175
+ .help("The name of the git repository to use for the upload (e.g. organization/repository). If not provided, the current repository will be used.")
176
+ )
177
+ .arg(
178
+ Arg::new("head_ref")
179
+ .long("head-ref")
180
+ .help("The reference (branch) to use for the upload. If not provided, the current reference will be used.")
181
+ )
182
+ .arg(
183
+ Arg::new("base_ref")
184
+ .long("base-ref")
185
+ .help("The base reference (branch) to use for the upload. If not provided, the merge-base with the remote tracking branch will be used.")
186
+ )
187
+ .arg(
188
+ Arg::new("pr_number")
189
+ .long("pr-number")
190
+ .value_parser(clap::value_parser!(u32))
191
+ .help("The pull request number to use for the upload. If not provided and running \
192
+ in a pull_request-triggered GitHub Actions workflow, the PR number will be automatically \
193
+ detected from GitHub Actions environment variables.")
194
+ )
195
+ .arg(
196
+ Arg::new("force_git_metadata")
197
+ .long("force-git-metadata")
198
+ .action(ArgAction::SetTrue)
199
+ .conflicts_with("no_git_metadata")
200
+ .help("Force collection and sending of git metadata (branch, commit, etc.). \
201
+ If neither this nor --no-git-metadata is specified, git metadata is \
202
+ automatically collected when running in most CI environments.")
203
+ )
204
+ .arg(
205
+ Arg::new("no_git_metadata")
206
+ .long("no-git-metadata")
207
+ .action(ArgAction::SetTrue)
208
+ .conflicts_with("force_git_metadata")
209
+ .help("Disable collection and sending of git metadata.")
210
+ )
211
+ }
145
212
  }