Skip to content

Conversation

runningcode
Copy link
Contributor

@runningcode runningcode commented Aug 28, 2025

Auto-detect base reference for build uploads using git merge-base.

Finds the merge-base commit SHA between HEAD and the remote tracking branch (refs/remotes/{remote}/HEAD), eliminating the need to manually specify --base-sha for most workflows.

In the future, we will add more checks for common CI providers to automatically get this value as well.

@runningcode runningcode force-pushed the feat/build-upload-auto-base-ref branch 2 times, most recently from cca503f to 1a0e73b Compare August 28, 2025 17:23
@runningcode runningcode requested a review from rbro112 August 28, 2025 17:25
@runningcode runningcode marked this pull request as ready for review August 29, 2025 10:15
@runningcode runningcode requested review from a team and szokeasaurusrex as code owners August 29, 2025 10:15
Comment on lines 189 to 186
debug!("Error getting base branch reference: {}", e);
None
Copy link
Member

Choose a reason for hiding this comment

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

Why do we swallow this error without propagating it to the user? Seems like potentially undesired behavior, as if something is broken, the user will not be made aware, unless they have debug logging turned on (which is unlikely in most use cases).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a good question. I would expect this to fail if the user isn't using git or has some non default branching strategy.
The question is how do we want to handle this.

  1. Throw an error at the CLI level.
  2. Show some error message after they've uploaded in the UI if the git information is missing.

I don't have a strong preference for 1 or 2, it just how we want the user experience to be. Throwing an error here might be frustrating if trying to get this working initially but once the integration is working throwing an error would be the easiest way to know that a change broke the integration.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually I found a better way to do this without iterating through the branches. Just updated the logic.

Copy link
Member

@szokeasaurusrex szokeasaurusrex left a comment

Choose a reason for hiding this comment

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

I have a couple questions about the implementation, plus a suggestion for how to simplify the code a bit

cursor[bot]

This comment was marked as outdated.

@runningcode runningcode force-pushed the feat/build-upload-auto-base-ref branch from 357b35f to 1f1d297 Compare August 29, 2025 12:07
cursor[bot]

This comment was marked as outdated.

src/utils/vcs.rs Outdated
let mut remote = repo.find_remote(remote_name)?;
remote.connect(git2::Direction::Fetch)?;
let default_branch_buf = remote.default_branch()?;
let default_branch = default_branch_buf.as_str().unwrap();
Copy link
Member

Choose a reason for hiding this comment

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

ChatGPT seems to think not, but the fact that the value returned by the git2 library (which is just Rust bindings for libgit2) is not a string and only performs a fallible conversion to str makes me think that we should perhaps be cautious. There is probably a reason why git2 is implemented this way; perhaps in some cases on some platforms a non-UTF-8 value is possible. It does not really cost anything to handle the error gracefully, without panicking, so let's do that!

@runningcode runningcode force-pushed the feat/build-upload-auto-base-ref branch from 2ae2a01 to f94f14b Compare September 3, 2025 09:12
cursor[bot]

This comment was marked as outdated.

@runningcode
Copy link
Contributor Author

Thanks for the suggestions @szokeasaurusrex ! I applied them.

Copy link
Member

@szokeasaurusrex szokeasaurusrex left a comment

Choose a reason for hiding this comment

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

Please see my reply to the Cursor comment

@runningcode
Copy link
Contributor Author

@szokeasaurusrex I couldn’t reply directly to your comment but that’s a good catch. I’m mostly relying on AI here.
It seems that git2/libgit2 doesn't provide a direct way to query "which branches point to this specific commit”.

Alternatively: we could call out to a shell with git branch --points-at?

@runningcode runningcode force-pushed the feat/build-upload-auto-base-ref branch from 8e14d16 to b03a325 Compare September 3, 2025 15:47
@szokeasaurusrex
Copy link
Member

szokeasaurusrex commented Sep 3, 2025

Let's avoid calling git directly, as adding a dependency on git is potentially a breaking change.

Idk how git works internally, but maybe it's possible that git itself only links from branches to commits, and not the other way around. In which case, it would make no difference that we are manually iterating.

So I'd say let's stick with how we have the code now. It would likely be preferable to write as an iterator chain instead of a loop though (I can also perform the rewrite for you)

@runningcode
Copy link
Contributor Author

Sounds good! I’ve fixed the tests and used an iterator chain.

cursor[bot]

This comment was marked as outdated.

@runningcode runningcode force-pushed the feat/build-upload-auto-base-ref branch from c2c1405 to 6830caf Compare September 8, 2025 07:10
cursor[bot]

This comment was marked as outdated.

@runningcode
Copy link
Contributor Author

@szokeasaurusrex I’ve simplified the code here. It just tries to get the remote tracking branch as origin/HEADand then finds the merge base with HEAD. This is what we previously did at Emerge tools.

Cursor correctly comments that this won’t work in all cases. We will log a warning when it doesn’t work.
In future PRs, I will add support for common CI providers to calculate the merge base using environment variables on CI, for example GITHUB_BASE_REF on github.

Copy link
Member

@szokeasaurusrex szokeasaurusrex left a comment

Choose a reason for hiding this comment

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

This is looking much better! After these changes, though, it looks like we can make some small simplifications of the function signatures

src/utils/vcs.rs Outdated
let remote_branch_name = format!("refs/remotes/{remote_name}/HEAD");
let remote_ref = repo
.find_reference(&remote_branch_name)
.or_else(|_| -> Result<git2::Reference, anyhow::Error> {
Copy link
Member

Choose a reason for hiding this comment

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

Result here is anyhow::Result (imported above), as it is in most parts of Sentry CLI. With anyhow::Result, the error value is implicitly anyhow::Error when not provided. Using Result<git2::Reference> is therefore simpler here.

However, in this case, the entire type annotation is unnecessary, as the compiler can infer it:

Suggested change
.or_else(|_| -> Result<git2::Reference, anyhow::Error> {
.or_else(|_| {

src/utils/vcs.rs Outdated
let remote_branch = format!("refs/remotes/{remote_name}/{branch_name}");
Ok(repo.find_reference(&remote_branch)?)
})
.map_err(|e: anyhow::Error| {
Copy link
Member

Choose a reason for hiding this comment

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

Seems we don't need this annotation anymore, either 😅

Suggested change
.map_err(|e: anyhow::Error| {
.map_err(|e| {

src/utils/vcs.rs Outdated
repo: &git2::Repository,
head_commit: &git2::Commit,
remote_ref: &git2::Reference,
) -> Result<Option<String>> {
Copy link
Member

Choose a reason for hiding this comment

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

From what I can tell, we are never returning Ok(None), so I think we can make this function return Result<String> instead

Copy link
Member

Choose a reason for hiding this comment

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

Assuming I am correct, we should also be able to make git_repo_base_ref return a Result<String>

@szokeasaurusrex
Copy link
Member

@runningcode please update the PR description to reflect the new behavior, e.g. that we are now no longer looking for the default_branch. I think this may be why Cursor is complaining (or at least, one of the reasons why)

Add automatic detection of base reference for build uploads by finding
the merge-base between current HEAD and remote tracking branch.

This works by:

- Finding the remote tracking branch (origin/HEAD, main, master, develop)
- Calculating git merge-base between HEAD and remote branch
- Returning the branch name pointing to merge-base or commit SHA

This mirrors the existing head_ref auto-detection behavior.
runningcode and others added 12 commits September 8, 2025 13:24
- Add debug logging when base_ref is found
- Use info level logging when base_ref cannot be detected for CI visibility

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
- Fix UTF-8 error handling with proper anyhow::Error conversion
- Add explicit type annotations for closure error handling
- Use anyhow::Error consistently instead of git2::Error for better error messages
- Implement cleaner error propagation as suggested in review

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Updated logging for base ref detection failures from info to warning level
to make these important failure cases more visible to users.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
The new base ref auto-detection feature logs warnings when it cannot
find a local branch that points to the merge-base. Updated integration
tests to expect these warning messages in their output.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
The CI environment gets SSL/TLS errors when trying to connect to git
remotes, resulting in "Could not detect base branch reference: ..."
messages instead of the simpler local messages. Updated test expectations
to use flexible patterns that match both local and CI error scenarios.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
… loop

Replace the explicit for loop with a more idiomatic iterator chain using
find_map(). This addresses the PR review comment about simplifying the
branching code with method chaining.

The new implementation:
- Uses find_map() to search and transform in one step
- Eliminates the explicit for loop and early returns
- Maintains the same functionality with cleaner, more idiomatic Rust

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
…anch name

Previously the base ref detection would only work if a local branch pointed
to the exact merge-base commit. This implementation now returns the
merge-base commit SHA directly, enabling automatic base reference detection
in all cases where a merge-base can be determined.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Remove the network fallback that queries remote default branch when
origin/HEAD is not set locally. This eliminates SSL/TLS errors that
occur when libgit2 lacks proper SSL support.

Users without origin/HEAD set up will get a clear error message and
can fix it with: git remote set-head origin --auto

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
The git_repo_base_ref and find_merge_base_ref functions never return Ok(None),
so simplified return types and removed unreachable code paths.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@runningcode runningcode force-pushed the feat/build-upload-auto-base-ref branch from ea59dba to 8b6f5df Compare September 8, 2025 11:24
@runningcode
Copy link
Contributor Author

Updated PR description!

Copy link
Member

@szokeasaurusrex szokeasaurusrex left a comment

Choose a reason for hiding this comment

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

Much simpler now, thank you 🚀

@runningcode runningcode merged commit c8009c5 into master Sep 9, 2025
23 checks passed
@runningcode runningcode deleted the feat/build-upload-auto-base-ref branch September 9, 2025 11:46
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