Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 31 additions & 6 deletions src/commands/build/upload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ use crate::utils::fs::TempDir;
use crate::utils::fs::TempFile;
use crate::utils::progress::ProgressBar;
use crate::utils::vcs::{
self, get_provider_from_remote, get_repo_from_remote, git_repo_head_ref, git_repo_remote_url,
self, get_provider_from_remote, get_repo_from_remote, git_repo_base_ref, git_repo_head_ref,
git_repo_remote_url,
};

pub fn make_command(command: Command) -> Command {
Expand Down Expand Up @@ -79,7 +80,7 @@ pub fn make_command(command: Command) -> Command {
.arg(
Arg::new("base_ref")
.long("base-ref")
.help("The reference (branch) to use for the upload. If not provided, the current reference will be used.")
.help("The base reference (branch) to use for the upload. If not provided, the merge-base with the remote tracking branch will be used.")
)
.arg(
Arg::new("pr_number")
Expand Down Expand Up @@ -113,7 +114,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {

let cached_remote = config.get_cached_vcs_remote();
// Try to open the git repository and find the remote, but handle errors gracefully.
let (vcs_provider, head_repo_name, head_ref) = {
let (vcs_provider, head_repo_name, head_ref, base_ref) = {
// Try to open the repo and get the remote URL, but don't fail if not in a repo.
let repo = git2::Repository::open_from_env().ok();
let repo_ref = repo.as_ref();
Expand Down Expand Up @@ -167,12 +168,36 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
.map(Cow::Owned)
});

(vcs_provider, head_repo_name, head_ref)
let base_ref = matches
.get_one("base_ref")
.map(String::as_str)
.map(Cow::Borrowed)
.or_else(|| {
// Try to get the base ref from the VCS if not provided
// This attempts to find the merge-base with the remote tracking branch
repo_ref
.and_then(|r| match git_repo_base_ref(r, &cached_remote) {
Ok(Some(base_ref_name)) => {
debug!("Found base reference: {}", base_ref_name);
Some(base_ref_name)
}
Ok(None) => {
warn!("No base reference found (could not determine merge-base)");
None
}
Err(e) => {
warn!("Could not detect base branch reference: {}", e);
None
}
})
.map(Cow::Owned)
});

(vcs_provider, head_repo_name, head_ref, base_ref)
};

let base_repo_name = matches.get_one("base_repo_name").map(String::as_str);
let base_sha = matches.get_one("base_sha").map(String::as_str);
let base_ref = matches.get_one("base_ref").map(String::as_str);
let pr_number = matches.get_one::<u32>("pr_number");

let build_configuration = matches.get_one("build_configuration").map(String::as_str);
Expand Down Expand Up @@ -237,7 +262,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> {
head_repo_name: head_repo_name.as_deref(),
base_repo_name,
head_ref: head_ref.as_deref(),
base_ref,
base_ref: base_ref.as_deref(),
pr_number,
};
match upload_file(
Expand Down
52 changes: 52 additions & 0 deletions src/utils/vcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,58 @@ pub fn git_repo_head_ref(repo: &git2::Repository) -> Result<String> {
}
}

pub fn git_repo_base_ref(repo: &git2::Repository, remote_name: &str) -> Result<Option<String>> {
// Get the current HEAD commit
let head_commit = repo.head()?.peel_to_commit()?;

// Try to find the remote tracking branch
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> {
// If remote/HEAD doesn't exist, try to query the remote for its actual default branch
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()
.ok_or_else(|| anyhow::anyhow!("Default branch contains invalid UTF-8"))?;

// Convert "refs/heads/main" to "refs/remotes/origin/main"
let branch_name = default_branch
.strip_prefix("refs/heads/")
.unwrap_or(default_branch);
let remote_branch = format!("refs/remotes/{remote_name}/{branch_name}");
Ok(repo.find_reference(&remote_branch)?)
})
.map_err(|e: anyhow::Error| {
anyhow::anyhow!(
"Could not find remote tracking branch for {}: {}",
remote_name,
e
)
})?;

find_merge_base_ref(repo, &head_commit, &remote_ref)
}

fn find_merge_base_ref(
repo: &git2::Repository,
head_commit: &git2::Commit,
remote_ref: &git2::Reference,
) -> Result<Option<String>> {
let remote_commit = remote_ref.peel_to_commit()?;
let merge_base_oid = repo.merge_base(head_commit.id(), remote_commit.id())?;

// Return the merge-base commit SHA as the base reference
let merge_base_sha = merge_base_oid.to_string();
debug!(
"Found merge-base commit as base reference: {}",
merge_base_sha
);
Ok(Some(merge_base_sha))
}

fn find_reference_url(repo: &str, repos: &[Repo]) -> Result<Option<String>> {
let mut non_git = false;
for configured_repo in repos {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
$ sentry-cli build upload tests/integration/_fixtures/build/apk.apk
? success
[..]WARN[..]EXPERIMENTAL: The build subcommand is experimental. The command is subject to breaking changes and may be removed without notice in any release.
WARN [..] Could not detect base branch reference: [..]
Successfully uploaded 1 file to Sentry
- tests/integration/_fixtures/build/apk.apk (http[..]/wat-org/preprod/wat-project/42)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
$ sentry-cli build upload tests/integration/_fixtures/build/apk.apk
? failed
[..]WARN[..]EXPERIMENTAL: The build subcommand is experimental. The command is subject to breaking changes and may be removed without notice in any release.
WARN [..] Could not detect base branch reference: [..]
error: Auth token is required for this request. Please run `sentry-cli login` and try again!

Add --log-level=[info|debug] or export SENTRY_LOG_LEVEL=[info|debug] to see more output.
Expand Down
1 change: 1 addition & 0 deletions tests/integration/_cases/build/build-upload-apk.trycmd
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
$ sentry-cli build upload tests/integration/_fixtures/build/apk.apk --head-sha test_head_sha
? success
[..]WARN[..]EXPERIMENTAL: The build subcommand is experimental. The command is subject to breaking changes and may be removed without notice in any release.
WARN [..] Could not detect base branch reference: [..]
Successfully uploaded 1 file to Sentry
- tests/integration/_fixtures/build/apk.apk (http[..]/wat-org/preprod/wat-project/42)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ Options:
The reference (branch) to use for the upload. If not provided, the current reference will
be used.
--base-ref <base_ref>
The reference (branch) to use for the upload. If not provided, the current reference will
be used.
The base reference (branch) to use for the upload. If not provided, the merge-base with
the remote tracking branch will be used.
--pr-number <pr_number>
The pull request number to use for the upload. If not provided, the current pull request
number will be used.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ Options:
The reference (branch) to use for the upload. If not provided, the current reference will
be used.
--base-ref <base_ref>
The reference (branch) to use for the upload. If not provided, the current reference will
be used.
The base reference (branch) to use for the upload. If not provided, the merge-base with
the remote tracking branch will be used.
--pr-number <pr_number>
The pull request number to use for the upload. If not provided, the current pull request
number will be used.
Expand Down
1 change: 1 addition & 0 deletions tests/integration/_cases/build/build-upload-ipa.trycmd
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
$ sentry-cli build upload tests/integration/_fixtures/build/ipa.ipa --head-sha test_head_sha
? success
[..]WARN[..]EXPERIMENTAL: The build subcommand is experimental. The command is subject to breaking changes and may be removed without notice in any release.
WARN [..] Could not detect base branch reference: [..]
Successfully uploaded 1 file to Sentry
- tests/integration/_fixtures/build/ipa.ipa (http[..]/wat-org/preprod/wat-project/some-text-id)

Expand Down