From 5ce459a4fd4ea8c1a0b38cc741e6506760f60c96 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Jun 2026 17:02:40 +0000 Subject: [PATCH 1/2] Initial plan From d04258d931248e63ee56da8ca79be2991b6cae88 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 22 Jun 2026 17:17:39 +0000 Subject: [PATCH 2/2] fix(rust-guard): hoist commit sha extraction and add commit-context tests --- .../rust-guard/src/labels/helpers.rs | 73 ++++++++++++++++--- 1 file changed, 63 insertions(+), 10 deletions(-) diff --git a/guards/github-guard/rust-guard/src/labels/helpers.rs b/guards/github-guard/rust-guard/src/labels/helpers.rs index 4b2f4739..5821c218 100644 --- a/guards/github-guard/rust-guard/src/labels/helpers.rs +++ b/guards/github-guard/rust-guard/src/labels/helpers.rs @@ -1986,14 +1986,15 @@ pub fn commit_integrity( is_default_branch: bool, ctx: &PolicyContext, ) -> Vec { + let sha = item + .get("sha") + .and_then(|v| v.as_str()) + .unwrap_or("unknown"); + let short_sha = short_sha(sha); + // Step 1: Check if author is in blocked_users — takes precedence over all other rules. let author_login = extract_author_login(item); if !author_login.is_empty() && is_blocked_user(author_login, ctx) { - let sha = item - .get("sha") - .and_then(|v| v.as_str()) - .unwrap_or("unknown"); - let short_sha = short_sha(sha); crate::log_info(&format!( "[integrity] commit:{}@{} → blocked (author '{}' in blocked-users)", repo_full_name, short_sha, author_login @@ -2021,11 +2022,6 @@ pub fn commit_integrity( // Collaborator permission fallback for public repos (handles owners/admins // whose author_association is missing or "NONE"). if !repo_private { - let sha = item - .get("sha") - .and_then(|v| v.as_str()) - .unwrap_or("unknown"); - let short_sha = short_sha(sha); integrity = elevate_via_collaborator_permission( author_login, repo_full_name, @@ -2400,6 +2396,63 @@ mod tests { } } + // ========================================================================= + // Tests for is_default_branch_commit_context / looks_like_commit_sha + // ========================================================================= + + #[test] + fn test_is_default_branch_commit_context_empty_ref_is_default() { + assert!(is_default_branch_commit_context("get_commit", "")); + assert!(is_default_branch_commit_context("list_commits", "")); + } + + #[test] + fn test_is_default_branch_commit_context_main_master_head_are_default() { + for branch in &["main", "master", "HEAD", "Main", "MASTER"] { + assert!( + is_default_branch_commit_context("list_commits", branch), + "{branch} should be default-branch context" + ); + } + } + + #[test] + fn test_is_default_branch_commit_context_get_commit_with_sha_is_default() { + let sha40 = "a590b228c2e258907f503759c31c75bbfcd78a36"; + assert!(is_default_branch_commit_context("get_commit", sha40)); + assert!(is_default_branch_commit_context("get_commit", "abc1234")); + } + + #[test] + fn test_is_default_branch_commit_context_list_commits_with_sha_is_not_default() { + let sha40 = "a590b228c2e258907f503759c31c75bbfcd78a36"; + assert!(!is_default_branch_commit_context("list_commits", sha40)); + } + + #[test] + fn test_is_default_branch_commit_context_non_hex_sha_not_treated_as_commit() { + assert!(!is_default_branch_commit_context( + "get_commit", + "feature/my-branch" + )); + assert!(!is_default_branch_commit_context( + "get_commit", + "v1.0.0-release" + )); + } + + #[test] + fn test_is_default_branch_commit_context_too_short_sha_not_treated_as_commit() { + assert!(!is_default_branch_commit_context("get_commit", "abc12")); + assert!(!is_default_branch_commit_context("get_commit", "abc123")); + } + + #[test] + fn test_is_default_branch_commit_context_too_long_sha_not_treated_as_commit() { + let long_sha = "a590b228c2e258907f503759c31c75bbfcd78a361"; + assert!(!is_default_branch_commit_context("get_commit", long_sha)); + } + // ========================================================================= // Tests for commit_integrity // =========================================================================