Skip to content

Commit aa8a09f

Browse files
jamesadevineCopilotCopilot
authored
fix(execute): don't overwrite env-derived ADO context with None CLI args (#413)
* fix(execute): don't overwrite env-derived ADO context with None CLI args build_execution_context unconditionally replaced ado_org_url and ado_project (resolved by ExecutionContext::default() from SYSTEM_TEAMFOUNDATIONCOLLECTIONURI / SYSTEM_TEAMPROJECT) with the CLI argument values — which are None when the flags are omitted. This caused 'AZURE_DEVOPS_ORG_URL not set' errors for every safe output that needs an org URL during pipeline execution. Only override the env-derived values when the CLI flags are explicitly provided, and re-derive ado_organization when the URL is overridden. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * refactor(safeoutputs): extract org_from_url helper to eliminate duplication Agent-Logs-Url: https://github.com/githubnext/ado-aw/sessions/d1969572-fd31-4c6f-85f0-cf5878796285 Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
1 parent 16d4861 commit aa8a09f

3 files changed

Lines changed: 26 additions & 9 deletions

File tree

src/main.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,16 @@ async fn build_execution_context(
245245
.collect();
246246

247247
let mut ctx = crate::safeoutputs::ExecutionContext::default();
248-
ctx.ado_org_url = ado_org_url;
249-
ctx.ado_project = ado_project;
248+
// Only override env-derived values when CLI args are explicitly provided;
249+
// otherwise keep the defaults from SYSTEM_TEAMFOUNDATIONCOLLECTIONURI /
250+
// SYSTEM_TEAMPROJECT that ExecutionContext::default() already resolved.
251+
if let Some(url) = ado_org_url {
252+
ctx.ado_organization = crate::safeoutputs::org_from_url(&url);
253+
ctx.ado_org_url = Some(url);
254+
}
255+
if let Some(project) = ado_project {
256+
ctx.ado_project = Some(project);
257+
}
250258
ctx.working_directory = safe_output_dir.clone();
251259
ctx.tool_configs = front_matter.safe_outputs.clone();
252260
ctx.allowed_repositories = allowed_repositories;

src/safeoutputs/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ pub use report_incomplete::*;
288288
pub use resolve_pr_thread::*;
289289
pub use result::{
290290
ExecutionContext, ExecutionResult, Executor, ToolResult, Validate, anyhow_to_mcp_error,
291+
org_from_url,
291292
};
292293
pub use submit_pr_review::*;
293294
pub use update_pr::*;

src/safeoutputs/result.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,20 @@ impl ExecutionContext {
129129
}
130130
}
131131

132+
/// Extract the organization name from an Azure DevOps org URL.
133+
///
134+
/// Handles both hosted (`https://dev.azure.com/myorg`) and on-prem
135+
/// (`https://server/tfs/myorg`) URLs, with or without a trailing slash.
136+
///
137+
/// Returns `None` if the URL is empty or has no meaningful last segment.
138+
pub fn org_from_url(url: &str) -> Option<String> {
139+
url.trim_end_matches('/')
140+
.rsplit('/')
141+
.next()
142+
.filter(|s| !s.is_empty())
143+
.map(|s| s.to_string())
144+
}
145+
132146
impl ExecutionContext {
133147
/// Build an `ExecutionContext` from an arbitrary env-var lookup function.
134148
///
@@ -144,13 +158,7 @@ impl ExecutionContext {
144158
.or_else(|| env("SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"));
145159

146160
// Extract organization name from URL (e.g., "https://dev.azure.com/myorg/" -> "myorg")
147-
let ado_organization = ado_org_url.as_ref().and_then(|url| {
148-
url.trim_end_matches('/')
149-
.rsplit('/')
150-
.next()
151-
.filter(|s| !s.is_empty())
152-
.map(|s| s.to_string())
153-
});
161+
let ado_organization = ado_org_url.as_ref().and_then(|url| org_from_url(url));
154162

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

0 commit comments

Comments
 (0)