Skip to content
Merged
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
12 changes: 10 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,16 @@ async fn build_execution_context(
.collect();

let mut ctx = crate::safeoutputs::ExecutionContext::default();
ctx.ado_org_url = ado_org_url;
ctx.ado_project = ado_project;
// Only override env-derived values when CLI args are explicitly provided;
// otherwise keep the defaults from SYSTEM_TEAMFOUNDATIONCOLLECTIONURI /
// SYSTEM_TEAMPROJECT that ExecutionContext::default() already resolved.
if let Some(url) = ado_org_url {
ctx.ado_organization = crate::safeoutputs::org_from_url(&url);
ctx.ado_org_url = Some(url);
}
if let Some(project) = ado_project {
ctx.ado_project = Some(project);
}
ctx.working_directory = safe_output_dir.clone();
ctx.tool_configs = front_matter.safe_outputs.clone();
ctx.allowed_repositories = allowed_repositories;
Expand Down
1 change: 1 addition & 0 deletions src/safeoutputs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ pub use report_incomplete::*;
pub use resolve_pr_thread::*;
pub use result::{
ExecutionContext, ExecutionResult, Executor, ToolResult, Validate, anyhow_to_mcp_error,
org_from_url,
};
pub use submit_pr_review::*;
pub use update_pr::*;
Expand Down
22 changes: 15 additions & 7 deletions src/safeoutputs/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,20 @@ impl ExecutionContext {
}
}

/// Extract the organization name from an Azure DevOps org URL.
///
/// Handles both hosted (`https://dev.azure.com/myorg`) and on-prem
/// (`https://server/tfs/myorg`) URLs, with or without a trailing slash.
///
/// Returns `None` if the URL is empty or has no meaningful last segment.
pub fn org_from_url(url: &str) -> Option<String> {
url.trim_end_matches('/')
.rsplit('/')
.next()
.filter(|s| !s.is_empty())
.map(|s| s.to_string())
}

impl ExecutionContext {
/// Build an `ExecutionContext` from an arbitrary env-var lookup function.
///
Expand All @@ -144,13 +158,7 @@ impl ExecutionContext {
.or_else(|| env("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"));

// Extract organization name from URL (e.g., "https://dev.azure.com/myorg/" -> "myorg")
let ado_organization = ado_org_url.as_ref().and_then(|url| {
url.trim_end_matches('/')
.rsplit('/')
.next()
.filter(|s| !s.is_empty())
.map(|s| s.to_string())
});
let ado_organization = ado_org_url.as_ref().and_then(|url| org_from_url(url));

// Source directory is where git repos are checked out (BUILD_SOURCESDIRECTORY)
let source_directory = env("BUILD_SOURCESDIRECTORY")
Expand Down