Skip to content

feat(code-mappings): Add git inference for repo and default branch#3208

Merged
romtsn merged 15 commits intomasterfrom
rz/feat/code-mappings-git-inference
Mar 24, 2026
Merged

feat(code-mappings): Add git inference for repo and default branch#3208
romtsn merged 15 commits intomasterfrom
rz/feat/code-mappings-git-inference

Conversation

@romtsn
Copy link
Copy Markdown
Member

@romtsn romtsn commented Mar 12, 2026

#skip-changelog

When --repo or --default-branch are not provided, infer them from the
local git repository. Uses the configured VCS remote (SENTRY_VCS_REMOTE / ini)
first, then falls back to best-effort remote detection (upstream > origin > first).

Also extracts find_best_remote() as a shared utility in src/utils/vcs.rs,
replacing the inline logic that was duplicated in git_repo_base_repo_name_preserve_case.

Stack: #3207#3208#3209#3210

Backend PRs: getsentry/sentry#109783, getsentry/sentry#109785, getsentry/sentry#109786

Closes GRADLE-79

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 12, 2026

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 7836ab1

@szokeasaurusrex
Copy link
Copy Markdown
Member

Please check and resolve the open comments from the AI reviewers, before I do a full review. If any comments are inaccurate or non-actionable, please indicate that with a 👎 and mark the comment as resolved. Thanks! 🙏

@romtsn romtsn force-pushed the rz/feat/code-mappings-git-inference branch from e405066 to 8f9babe Compare March 18, 2026 17:15
@linear-code
Copy link
Copy Markdown

linear-code bot commented Mar 19, 2026

romtsn added a commit that referenced this pull request Mar 20, 2026
_#skip-changelog_

Add the `sentry-cli code-mappings upload` subcommand group and the
`upload`
subcommand with file parsing and validation.

This is the first in a stack of 4 PRs to support bulk uploading code
mappings
from a JSON file — useful for Java/Android multi-module projects that
need
dozens of mappings.

This PR adds:
- Command scaffold following the `repos`/`deploys` pattern
- JSON file reading and validation (empty arrays, empty
stackRoot/sourceRoot)
- CLI args: positional `PATH`, `--repo`, `--default-branch`
- Help and no-subcommand trycmd integration tests

Stack: **#3207** → #3208#3209#3210

Backend PRs: getsentry/sentry#109783, getsentry/sentry#109785,
getsentry/sentry#109786

Closes getsentry/sentry-android-gradle-plugin#1076
Closes getsentry/sentry-android-gradle-plugin#1077

---------

Co-authored-by: Claude Opus 4.6 <[email protected]>
Base automatically changed from rz/feat/code-mappings-scaffold to master March 20, 2026 21:26
romtsn and others added 6 commits March 20, 2026 22:34
Add a new `code-mappings` subcommand group with an `upload` subcommand
that reads and validates a JSON file of code mappings. This is the first
step toward CLI support for bulk code mapping uploads to Sentry.
Add descriptive help text explaining what code mappings are and how they
work. Replace unwrap with expect for the required path argument.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Automatically detect repository name and default branch from the local
git repo when --repo or --default-branch are not provided. Respects
SENTRY_VCS_REMOTE config, falling back to best-effort remote detection.

Extract find_best_remote() into vcs.rs to deduplicate remote selection
logic shared with git_repo_base_repo_name_preserve_case().
When --repo is provided but --default-branch is not, the code no longer
requires a git remote to be present. Branch inference gracefully falls
back to 'main' when no git repo or remote is available.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Use get_repo_from_remote_preserve_case instead of get_repo_from_remote
to avoid lowercasing the repository name, which would cause mismatches
with Sentry's case-sensitive API.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@romtsn romtsn force-pushed the rz/feat/code-mappings-git-inference branch from 70ddd86 to 6dae115 Compare March 20, 2026 21:35
romtsn and others added 2 commits March 20, 2026 22:49
Replace the deeply nested match with two independent lookups for
repo_name and default_branch. Extract resolve_git_remote,
infer_repo_name, and infer_default_branch as utility functions.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Duplicate output when values are inferred from git
    • Removed println! calls from inference helpers so only the summary lines are printed once.

Create PR

Or push these changes by commenting:

@cursor push 7a276a79c2
Preview (7a276a79c2)
diff --git a/src/commands/code_mappings/upload.rs b/src/commands/code_mappings/upload.rs
--- a/src/commands/code_mappings/upload.rs
+++ b/src/commands/code_mappings/upload.rs
@@ -123,7 +123,6 @@
     if inferred.is_empty() {
         bail!("Could not parse repository name from remote URL: {remote_url}");
     }
-    println!("Inferred repository: {inferred}");
     Ok(inferred)
 }
 
@@ -143,6 +142,5 @@
             debug!("No git repo or remote available, falling back to 'main'");
             "main".to_owned()
         });
-    println!("Inferred default branch: {inferred}");
     inferred
 }

This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

Comment on lines +72 to +82
let repo_name = if let Some(r) = explicit_repo {
r.to_owned()
} else {
infer_repo_name(git_repo.as_ref(), remote_name.as_deref())?
};

let default_branch = if let Some(b) = explicit_branch {
b.to_owned()
} else {
infer_default_branch(git_repo.as_ref(), remote_name.as_deref())
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic strikes me as a bit weird. If e.g. explicit_repo is Some("repo_name") but explicit_branch is None, on line 81 we would call infer_default_branch with git_repo (the repo inferred by git2), despite the fact that an explicit repo was given. Is that intentional?

…po is explicit

When --repo is provided but --default-branch is omitted, find the local
remote whose URL matches the given repo name and infer the branch from
that remote's HEAD. This avoids using an unrelated remote (e.g. a fork)
for branch inference.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Refactor resolve_repo_and_branch to accept a pre-opened Repository
instead of opening one internally. This allows tests to pass a repo
directly without setting GIT_DIR, which was causing flaky failures
in unrelated vcs tests running concurrently on Windows CI.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
romtsn and others added 2 commits March 23, 2026 15:10
The tests no longer mutate shared env vars, and the Config binding is
mutex-protected, so serial execution is not needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

@romtsn romtsn merged commit bee85dc into master Mar 24, 2026
26 checks passed
@romtsn romtsn deleted the rz/feat/code-mappings-git-inference branch March 24, 2026 10:20
romtsn added a commit that referenced this pull request Mar 24, 2026
…#3209)

_#skip-changelog_

Connect the `code-mappings upload` command to the bulk code mappings API
endpoint (`POST /api/0/organizations/{org}/code-mappings/bulk/`).

Adds:
- `bulk_upload_code_mappings()` method on `AuthenticatedApi`
- Request/response data types in `src/api/data_types/code_mappings.rs`
- Summary table and error reporting in the command output
- Happy-path integration test with mock endpoint

Stack: #3207#3208 → **#3209** → #3210

Backend PRs: getsentry/sentry#109783, getsentry/sentry#109785,
getsentry/sentry#109786

Closes getsentry/sentry-android-gradle-plugin#1079

---------

Co-authored-by: Claude Opus 4.6 <[email protected]>
romtsn added a commit that referenced this pull request Mar 24, 2026
_#skip-changelog_

Split large mapping files into batches of 300 (the backend limit) per
request.
Each batch is sent sequentially with progress reporting, and results are
merged
into a single summary.

Also changes the output table to only show error rows — for large
uploads
(hundreds of mappings), printing every row would flood the terminal.
Successful
mappings are reflected in the summary counts instead.

Stack: #3207#3208#3209 → **#3210**

Backend PRs: getsentry/sentry#109783, getsentry/sentry#109785,
getsentry/sentry#109786

---------

Co-authored-by: Claude Opus 4.6 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants