diff --git a/src/commands/build/upload.rs b/src/commands/build/upload.rs index 7be5a2d0a8..1406b672b2 100644 --- a/src/commands/build/upload.rs +++ b/src/commands/build/upload.rs @@ -24,8 +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_base_ref, git_repo_head_ref, - git_repo_remote_url, + self, get_github_pr_number, 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 { @@ -86,7 +86,9 @@ pub fn make_command(command: Command) -> Command { Arg::new("pr_number") .long("pr-number") .value_parser(clap::value_parser!(u32)) - .help("The pull request number to use for the upload. If not provided, the current pull request number will be used.") + .help("The pull request number to use for the upload. If not provided and running \ + in a pull_request-triggered GitHub Actions workflow, the PR number will be automatically \ + detected from GitHub Actions environment variables.") ) .arg( Arg::new("build_configuration") @@ -194,7 +196,10 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { 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 pr_number = matches.get_one::("pr_number"); + let pr_number = matches + .get_one("pr_number") + .copied() + .or_else(get_github_pr_number); let build_configuration = matches.get_one("build_configuration").map(String::as_str); let release_notes = matches.get_one("release_notes").map(String::as_str); @@ -259,7 +264,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { base_repo_name, head_ref: head_ref.as_deref(), base_ref: base_ref.as_deref(), - pr_number, + pr_number: pr_number.as_ref(), }; match upload_file( &authenticated_api, diff --git a/src/utils/vcs.rs b/src/utils/vcs.rs index 5e84a10a36..9fb1d1da89 100644 --- a/src/utils/vcs.rs +++ b/src/utils/vcs.rs @@ -283,6 +283,28 @@ fn find_merge_base_ref( Ok(merge_base_sha) } +/// Attempts to get the PR number from GitHub Actions environment variables. +/// Returns the PR number if running in a GitHub Actions pull request environment. +pub fn get_github_pr_number() -> Option { + let github_ref = std::env::var("GITHUB_REF").ok()?; + let event_name = std::env::var("GITHUB_EVENT_NAME").ok()?; + + if event_name != "pull_request" { + debug!("Not running in pull_request event, got: {}", event_name); + return None; + } + + let pr_number_str = github_ref.strip_prefix("refs/pull/")?; + debug!("Extracted PR reference: {}", pr_number_str); + + let pr_number_str = pr_number_str.split('/').next()?; + debug!("Parsing PR number from: {}", pr_number_str); + + let pr_number = pr_number_str.parse().ok()?; + debug!("Auto-detected PR number from GitHub Actions: {}", pr_number); + Some(pr_number) +} + fn find_reference_url(repo: &str, repos: &[Repo]) -> Result> { let mut non_git = false; for configured_repo in repos { @@ -1278,3 +1300,25 @@ fn test_git_repo_head_ref() { "HEAD is detached - no branch reference available" ); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_get_github_pr_number() { + std::env::set_var("GITHUB_EVENT_NAME", "pull_request"); + std::env::set_var("GITHUB_REF", "refs/pull/123/merge"); + let pr_number = get_github_pr_number(); + assert_eq!(pr_number, Some(123)); + std::env::set_var("GITHUB_EVENT_NAME", "push"); + let pr_number = get_github_pr_number(); + assert_eq!(pr_number, None); + std::env::set_var("GITHUB_EVENT_NAME", "pull_request"); + std::env::set_var("GITHUB_REF", "refs/heads/main"); + let pr_number = get_github_pr_number(); + assert_eq!(pr_number, None); + std::env::remove_var("GITHUB_EVENT_NAME"); + std::env::remove_var("GITHUB_REF"); + } +} diff --git a/tests/integration/_cases/build/build-upload-help-macos.trycmd b/tests/integration/_cases/build/build-upload-help-macos.trycmd index 42bd371b76..77f4086934 100644 --- a/tests/integration/_cases/build/build-upload-help-macos.trycmd +++ b/tests/integration/_cases/build/build-upload-help-macos.trycmd @@ -45,8 +45,9 @@ Options: 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 - The pull request number to use for the upload. If not provided, the current pull request - number will be used. + The pull request number to use for the upload. If not provided and running in a + pull_request-triggered GitHub Actions workflow, the PR number will be automatically + detected from GitHub Actions environment variables. --build-configuration The build configuration to use for the upload. If not provided, the current version will be used. diff --git a/tests/integration/_cases/build/build-upload-help-not-macos.trycmd b/tests/integration/_cases/build/build-upload-help-not-macos.trycmd index 25518253d5..177c314edf 100644 --- a/tests/integration/_cases/build/build-upload-help-not-macos.trycmd +++ b/tests/integration/_cases/build/build-upload-help-not-macos.trycmd @@ -44,8 +44,9 @@ Options: 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 - The pull request number to use for the upload. If not provided, the current pull request - number will be used. + The pull request number to use for the upload. If not provided and running in a + pull_request-triggered GitHub Actions workflow, the PR number will be automatically + detected from GitHub Actions environment variables. --build-configuration The build configuration to use for the upload. If not provided, the current version will be used.