|
3 | 3 | use std::fmt; |
4 | 4 | use std::path::PathBuf; |
5 | 5 |
|
6 | | -use anyhow::{bail, format_err, Context as _, Error, Result}; |
| 6 | +use anyhow::{bail, format_err, Error, Result}; |
7 | 7 | use chrono::{DateTime, FixedOffset, TimeZone as _}; |
8 | 8 | use git2::{Commit, Repository, Time}; |
9 | 9 | use if_chain::if_chain; |
@@ -569,13 +569,30 @@ pub fn find_head_sha() -> Result<String> { |
569 | 569 | Ok(head.id().to_string()) |
570 | 570 | } |
571 | 571 |
|
572 | | -pub fn find_base_sha() -> Result<Option<String>> { |
573 | | - let github_event = std::env::var("GITHUB_EVENT_PATH") |
574 | | - .map_err(Error::from) |
575 | | - .and_then(|event_path| std::fs::read_to_string(event_path).map_err(Error::from)) |
576 | | - .context("Failed to read GitHub event path")?; |
| 572 | +pub fn find_base_sha(remote_name: &str) -> Result<Option<String>> { |
| 573 | + if let Some(pr_base_sha) = std::env::var("GITHUB_EVENT_PATH") |
| 574 | + .ok() |
| 575 | + .and_then(|event_path| std::fs::read_to_string(event_path).ok()) |
| 576 | + .and_then(|content| extract_pr_base_sha_from_event(&content)) |
| 577 | + { |
| 578 | + debug!("Using GitHub Actions PR base SHA from event payload: {pr_base_sha}"); |
| 579 | + return Ok(Some(pr_base_sha)); |
| 580 | + } |
| 581 | + |
| 582 | + let repo = git2::Repository::open_from_env()?; |
| 583 | + |
| 584 | + let head_commit = repo.head()?.peel_to_commit()?; |
| 585 | + |
| 586 | + let remote_branch_name = format!("refs/remotes/{remote_name}/HEAD"); |
| 587 | + let remote_ref = repo |
| 588 | + .find_reference(&remote_branch_name) |
| 589 | + .map_err(|e| anyhow::anyhow!("Could default branch for {remote_name}: {e}"))?; |
577 | 590 |
|
578 | | - Ok(extract_pr_base_sha_from_event(&github_event)) |
| 591 | + let remote_commit = remote_ref.peel_to_commit()?; |
| 592 | + let merge_base_oid = repo.merge_base(head_commit.id(), remote_commit.id())?; |
| 593 | + let merge_base_sha = merge_base_oid.to_string(); |
| 594 | + debug!("Found merge-base commit as base reference: {merge_base_sha}"); |
| 595 | + Ok(Some(merge_base_sha)) |
579 | 596 | } |
580 | 597 |
|
581 | 598 | /// Extracts the PR head SHA from GitHub Actions event payload JSON. |
@@ -1773,15 +1790,15 @@ mod tests { |
1773 | 1790 | fs::write(&event_file, pr_json).expect("Failed to write event file"); |
1774 | 1791 | std::env::set_var("GITHUB_EVENT_PATH", event_file.to_str().unwrap()); |
1775 | 1792 |
|
1776 | | - let result = find_base_sha(); |
| 1793 | + let result = find_base_sha("origin"); |
1777 | 1794 | assert_eq!( |
1778 | 1795 | result.unwrap().unwrap(), |
1779 | 1796 | "55e6bc8c264ce95164314275d805f477650c440d" |
1780 | 1797 | ); |
1781 | 1798 |
|
1782 | 1799 | // Test without GITHUB_EVENT_PATH |
1783 | 1800 | std::env::remove_var("GITHUB_EVENT_PATH"); |
1784 | | - let result = find_base_sha(); |
| 1801 | + let result = find_base_sha("origin"); |
1785 | 1802 | assert!(result.is_err()); |
1786 | 1803 | } |
1787 | 1804 | } |
0 commit comments