From d922b96d4b46c0330ae92c0ef37dfda820d9d3b4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2026 21:39:27 +0000 Subject: [PATCH 1/4] refactor: reduce complexity of execute_safe_output in src/execute.rs Extract generic dispatch_tool helper to replace 17 near-identical match arms, each of which repeated the same parse-then-execute pattern. Also collapse three trivially-equivalent informational arms (noop, missing-tool, missing-data) into one. Before: cognitive complexity 58/25 After: below threshold (not flagged by Clippy) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/execute.rs | 216 ++++++++++--------------------------------------- 1 file changed, 44 insertions(+), 172 deletions(-) diff --git a/src/execute.rs b/src/execute.rs index 177cb4e..b5a2c7f 100644 --- a/src/execute.rs +++ b/src/execute.rs @@ -5,6 +5,7 @@ use anyhow::{Result, bail}; use log::{debug, error, info, warn}; +use serde::de::DeserializeOwned; use serde_json::Value; use std::collections::HashMap; use std::path::Path; @@ -213,6 +214,24 @@ pub async fn execute_safe_outputs( Ok(results) } +/// Parse a JSON entry as `T` and run it through `execute_sanitized`. +/// +/// This is the common path for all tools that implement `Executor`. The tool name +/// is used only for the error message so callers don't have to repeat it. +async fn dispatch_tool( + tool_name: &str, + entry: &Value, + ctx: &ExecutionContext, +) -> Result +where + T: DeserializeOwned + Executor, +{ + debug!("Parsing {} payload", tool_name); + let mut output: T = serde_json::from_value(entry.clone()) + .map_err(|e| anyhow::anyhow!("Failed to parse {}: {}", tool_name, e))?; + output.execute_sanitized(ctx).await +} + /// Execute a single safe output entry, returning the tool name and result pub async fn execute_safe_output( entry: &Value, @@ -226,172 +245,33 @@ pub async fn execute_safe_output( debug!("Dispatching tool: {}", tool_name); - // Dispatch based on tool name + // Dispatch based on tool name. All standard tools go through `dispatch_tool` which + // handles deserialization and sanitized execution uniformly. Special cases (informational + // outputs and report-incomplete) are handled inline. let result = match tool_name { - "create-work-item" => { - debug!("Parsing create-work-item payload"); - let mut output: CreateWorkItemResult = serde_json::from_value(entry.clone()) - .map_err(|e| anyhow::anyhow!("Failed to parse create-work-item: {}", e))?; - debug!( - "create-work-item: title='{}', description length={}", - output.title, - output.description.len() - ); - output.execute_sanitized(ctx).await? - } - "comment-on-work-item" => { - debug!("Parsing comment-on-work-item payload"); - let mut output: CommentOnWorkItemResult = serde_json::from_value(entry.clone()) - .map_err(|e| anyhow::anyhow!("Failed to parse comment-on-work-item: {}", e))?; - debug!( - "comment-on-work-item: work_item_id={}, body length={}", - output.work_item_id, - output.body.len() - ); - output.execute_sanitized(ctx).await? - } - "update-work-item" => { - debug!("Parsing update-work-item payload"); - let mut output: UpdateWorkItemResult = serde_json::from_value(entry.clone()) - .map_err(|e| anyhow::anyhow!("Failed to parse update-work-item: {}", e))?; - debug!("update-work-item: id={}", output.id); - output.execute_sanitized(ctx).await? - } - "create-pull-request" => { - debug!("Parsing create-pull-request payload"); - let mut output: CreatePrResult = serde_json::from_value(entry.clone()) - .map_err(|e| anyhow::anyhow!("Failed to parse create-pull-request: {}", e))?; - debug!( - "create-pull-request: title='{}', repo='{}', branch='{}', patch='{}'", - output.title, output.repository, output.source_branch, output.patch_file - ); - output.execute_sanitized(ctx).await? - } - "update-wiki-page" => { - debug!("Parsing update-wiki-page payload"); - let mut output: UpdateWikiPageResult = serde_json::from_value(entry.clone()) - .map_err(|e| anyhow::anyhow!("Failed to parse update-wiki-page: {}", e))?; - debug!( - "update-wiki-page: path='{}', content length={}", - output.path, - output.content.len() - ); - output.execute_sanitized(ctx).await? - } - "create-wiki-page" => { - debug!("Parsing create-wiki-page payload"); - let mut output: CreateWikiPageResult = serde_json::from_value(entry.clone()) - .map_err(|e| anyhow::anyhow!("Failed to parse create-wiki-page: {}", e))?; - debug!( - "create-wiki-page: path='{}', content length={}", - output.path, - output.content.len() - ); - output.execute_sanitized(ctx).await? - } - "add-pr-comment" => { - debug!("Parsing add-pr-comment payload"); - let mut output: AddPrCommentResult = serde_json::from_value(entry.clone()) - .map_err(|e| anyhow::anyhow!("Failed to parse add-pr-comment: {}", e))?; - debug!( - "add-pr-comment: pr_id={}, content length={}", - output.pull_request_id, - output.content.len() - ); - output.execute_sanitized(ctx).await? - } - "link-work-items" => { - debug!("Parsing link-work-items payload"); - let mut output: LinkWorkItemsResult = serde_json::from_value(entry.clone()) - .map_err(|e| anyhow::anyhow!("Failed to parse link-work-items: {}", e))?; - debug!( - "link-work-items: source={}, target={}, type={}", - output.source_id, output.target_id, output.link_type - ); - output.execute_sanitized(ctx).await? - } - "queue-build" => { - debug!("Parsing queue-build payload"); - let mut output: QueueBuildResult = serde_json::from_value(entry.clone()) - .map_err(|e| anyhow::anyhow!("Failed to parse queue-build: {}", e))?; - debug!("queue-build: pipeline_id={}", output.pipeline_id); - output.execute_sanitized(ctx).await? - } - "create-git-tag" => { - debug!("Parsing create-git-tag payload"); - let mut output: CreateGitTagResult = serde_json::from_value(entry.clone()) - .map_err(|e| anyhow::anyhow!("Failed to parse create-git-tag: {}", e))?; - debug!("create-git-tag: tag_name='{}'", output.tag_name); - output.execute_sanitized(ctx).await? - } - "add-build-tag" => { - debug!("Parsing add-build-tag payload"); - let mut output: AddBuildTagResult = serde_json::from_value(entry.clone()) - .map_err(|e| anyhow::anyhow!("Failed to parse add-build-tag: {}", e))?; - debug!("add-build-tag: build_id={}, tag='{}'", output.build_id, output.tag); - output.execute_sanitized(ctx).await? - } - "create-branch" => { - debug!("Parsing create-branch payload"); - let mut output: CreateBranchResult = serde_json::from_value(entry.clone()) - .map_err(|e| anyhow::anyhow!("Failed to parse create-branch: {}", e))?; - debug!("create-branch: branch_name='{}'", output.branch_name); - output.execute_sanitized(ctx).await? - } - "update-pr" => { - debug!("Parsing update-pr payload"); - let mut output: UpdatePrResult = serde_json::from_value(entry.clone()) - .map_err(|e| anyhow::anyhow!("Failed to parse update-pr: {}", e))?; - debug!( - "update-pr: pr_id={}, operation='{}'", - output.pull_request_id, output.operation - ); - output.execute_sanitized(ctx).await? - } - "upload-attachment" => { - debug!("Parsing upload-attachment payload"); - let mut output: UploadAttachmentResult = serde_json::from_value(entry.clone()) - .map_err(|e| anyhow::anyhow!("Failed to parse upload-attachment: {}", e))?; - debug!( - "upload-attachment: work_item_id={}, file_path='{}'", - output.work_item_id, output.file_path - ); - output.execute_sanitized(ctx).await? - } - "submit-pr-review" => { - debug!("Parsing submit-pr-review payload"); - let mut output: SubmitPrReviewResult = serde_json::from_value(entry.clone()) - .map_err(|e| anyhow::anyhow!("Failed to parse submit-pr-review: {}", e))?; - debug!( - "submit-pr-review: pr_id={}, event='{}'", - output.pull_request_id, output.event - ); - output.execute_sanitized(ctx).await? - } - "reply-to-pr-review-comment" => { - debug!("Parsing reply-to-pr-review-comment payload"); - let mut output: ReplyToPrCommentResult = serde_json::from_value(entry.clone()) - .map_err(|e| anyhow::anyhow!("Failed to parse reply-to-pr-review-comment: {}", e))?; - debug!( - "reply-to-pr-review-comment: pr_id={}, thread_id={}", - output.pull_request_id, output.thread_id - ); - output.execute_sanitized(ctx).await? - } - "resolve-pr-thread" => { - debug!("Parsing resolve-pr-thread payload"); - let mut output: ResolvePrThreadResult = serde_json::from_value(entry.clone()) - .map_err(|e| anyhow::anyhow!("Failed to parse resolve-pr-thread: {}", e))?; - debug!( - "resolve-pr-thread: pr_id={}, thread_id={}, status='{}'", - output.pull_request_id, output.thread_id, output.status - ); - output.execute_sanitized(ctx).await? - } - "noop" => { - debug!("Skipping noop entry"); - ExecutionResult::success("Skipped informational output: noop") + "create-work-item" => dispatch_tool::(tool_name, entry, ctx).await?, + "comment-on-work-item" => dispatch_tool::(tool_name, entry, ctx).await?, + "update-work-item" => dispatch_tool::(tool_name, entry, ctx).await?, + "create-pull-request" => dispatch_tool::(tool_name, entry, ctx).await?, + "update-wiki-page" => dispatch_tool::(tool_name, entry, ctx).await?, + "create-wiki-page" => dispatch_tool::(tool_name, entry, ctx).await?, + "add-pr-comment" => dispatch_tool::(tool_name, entry, ctx).await?, + "link-work-items" => dispatch_tool::(tool_name, entry, ctx).await?, + "queue-build" => dispatch_tool::(tool_name, entry, ctx).await?, + "create-git-tag" => dispatch_tool::(tool_name, entry, ctx).await?, + "add-build-tag" => dispatch_tool::(tool_name, entry, ctx).await?, + "create-branch" => dispatch_tool::(tool_name, entry, ctx).await?, + "update-pr" => dispatch_tool::(tool_name, entry, ctx).await?, + "upload-attachment" => dispatch_tool::(tool_name, entry, ctx).await?, + "submit-pr-review" => dispatch_tool::(tool_name, entry, ctx).await?, + "reply-to-pr-review-comment" => dispatch_tool::(tool_name, entry, ctx).await?, + "resolve-pr-thread" => dispatch_tool::(tool_name, entry, ctx).await?, + // Informational outputs — no side effects, always succeed + "noop" | "missing-tool" | "missing-data" => { + debug!("Skipping informational entry: {}", tool_name); + ExecutionResult::success(format!("Skipped informational output: {}", tool_name)) } + // report-incomplete does not implement Executor; Stage 3 surfaces its reason as a failure "report-incomplete" => { let mut output: ReportIncompleteResult = serde_json::from_value(entry.clone()) .map_err(|e| anyhow::anyhow!("Failed to parse report-incomplete: {}", e))?; @@ -399,14 +279,6 @@ pub async fn execute_safe_output( debug!("report-incomplete: {}", output.reason); ExecutionResult::failure(format!("Agent reported task incomplete: {}", output.reason)) } - "missing-tool" => { - debug!("Skipping missing-tool entry"); - ExecutionResult::success("Skipped informational output: missing-tool") - } - "missing-data" => { - debug!("Skipping missing-data entry"); - ExecutionResult::success("Skipped informational output: missing-data") - } other => { error!("Unknown tool type: {}", other); bail!("Unknown tool type: {}. No executor registered.", other) From c110347a902fcc4a5c6e7932364da34f889b23b4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 23 Apr 2026 06:31:37 +0000 Subject: [PATCH 2/4] refactor: use macro table for execute tool dispatch Agent-Logs-Url: https://github.com/githubnext/ado-aw/sessions/58f1afb6-0295-4593-9ad7-fce1005c1ac7 Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com> --- src/execute.rs | 52 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/src/execute.rs b/src/execute.rs index b5a2c7f..999c693 100644 --- a/src/execute.rs +++ b/src/execute.rs @@ -232,6 +232,17 @@ where output.execute_sanitized(ctx).await } +macro_rules! dispatch_executor_tools { + ($tool_name:expr, $entry:expr, $ctx:expr, { $($name:literal => $ty:ty),+ $(,)? }) => { + match $tool_name { + $( + $name => Some(dispatch_tool::<$ty>($tool_name, $entry, $ctx).await?), + )+ + _ => None, + } + }; +} + /// Execute a single safe output entry, returning the tool name and result pub async fn execute_safe_output( entry: &Value, @@ -248,24 +259,28 @@ pub async fn execute_safe_output( // Dispatch based on tool name. All standard tools go through `dispatch_tool` which // handles deserialization and sanitized execution uniformly. Special cases (informational // outputs and report-incomplete) are handled inline. - let result = match tool_name { - "create-work-item" => dispatch_tool::(tool_name, entry, ctx).await?, - "comment-on-work-item" => dispatch_tool::(tool_name, entry, ctx).await?, - "update-work-item" => dispatch_tool::(tool_name, entry, ctx).await?, - "create-pull-request" => dispatch_tool::(tool_name, entry, ctx).await?, - "update-wiki-page" => dispatch_tool::(tool_name, entry, ctx).await?, - "create-wiki-page" => dispatch_tool::(tool_name, entry, ctx).await?, - "add-pr-comment" => dispatch_tool::(tool_name, entry, ctx).await?, - "link-work-items" => dispatch_tool::(tool_name, entry, ctx).await?, - "queue-build" => dispatch_tool::(tool_name, entry, ctx).await?, - "create-git-tag" => dispatch_tool::(tool_name, entry, ctx).await?, - "add-build-tag" => dispatch_tool::(tool_name, entry, ctx).await?, - "create-branch" => dispatch_tool::(tool_name, entry, ctx).await?, - "update-pr" => dispatch_tool::(tool_name, entry, ctx).await?, - "upload-attachment" => dispatch_tool::(tool_name, entry, ctx).await?, - "submit-pr-review" => dispatch_tool::(tool_name, entry, ctx).await?, - "reply-to-pr-review-comment" => dispatch_tool::(tool_name, entry, ctx).await?, - "resolve-pr-thread" => dispatch_tool::(tool_name, entry, ctx).await?, + let result = if let Some(result) = dispatch_executor_tools!(tool_name, entry, ctx, { + "create-work-item" => CreateWorkItemResult, + "comment-on-work-item" => CommentOnWorkItemResult, + "update-work-item" => UpdateWorkItemResult, + "create-pull-request" => CreatePrResult, + "update-wiki-page" => UpdateWikiPageResult, + "create-wiki-page" => CreateWikiPageResult, + "add-pr-comment" => AddPrCommentResult, + "link-work-items" => LinkWorkItemsResult, + "queue-build" => QueueBuildResult, + "create-git-tag" => CreateGitTagResult, + "add-build-tag" => AddBuildTagResult, + "create-branch" => CreateBranchResult, + "update-pr" => UpdatePrResult, + "upload-attachment" => UploadAttachmentResult, + "submit-pr-review" => SubmitPrReviewResult, + "reply-to-pr-review-comment" => ReplyToPrCommentResult, + "resolve-pr-thread" => ResolvePrThreadResult, + }) { + result + } else { + match tool_name { // Informational outputs — no side effects, always succeed "noop" | "missing-tool" | "missing-data" => { debug!("Skipping informational entry: {}", tool_name); @@ -283,6 +298,7 @@ pub async fn execute_safe_output( error!("Unknown tool type: {}", other); bail!("Unknown tool type: {}. No executor registered.", other) } + } }; Ok((tool_name.to_string(), result)) From 6f8c02ff69202e4d881f5ce2c08c96f30fb85e79 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 23 Apr 2026 06:36:33 +0000 Subject: [PATCH 3/4] refactor: simplify macro error flow in execute dispatch Agent-Logs-Url: https://github.com/githubnext/ado-aw/sessions/58f1afb6-0295-4593-9ad7-fce1005c1ac7 Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com> --- src/execute.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/execute.rs b/src/execute.rs index 999c693..9700316 100644 --- a/src/execute.rs +++ b/src/execute.rs @@ -236,9 +236,9 @@ macro_rules! dispatch_executor_tools { ($tool_name:expr, $entry:expr, $ctx:expr, { $($name:literal => $ty:ty),+ $(,)? }) => { match $tool_name { $( - $name => Some(dispatch_tool::<$ty>($tool_name, $entry, $ctx).await?), + $name => dispatch_tool::<$ty>($tool_name, $entry, $ctx).await.map(Some), )+ - _ => None, + _ => Ok(None), } }; } @@ -259,7 +259,7 @@ pub async fn execute_safe_output( // Dispatch based on tool name. All standard tools go through `dispatch_tool` which // handles deserialization and sanitized execution uniformly. Special cases (informational // outputs and report-incomplete) are handled inline. - let result = if let Some(result) = dispatch_executor_tools!(tool_name, entry, ctx, { + let result = if let Some(dispatched_result) = dispatch_executor_tools!(tool_name, entry, ctx, { "create-work-item" => CreateWorkItemResult, "comment-on-work-item" => CommentOnWorkItemResult, "update-work-item" => UpdateWorkItemResult, @@ -277,8 +277,8 @@ pub async fn execute_safe_output( "submit-pr-review" => SubmitPrReviewResult, "reply-to-pr-review-comment" => ReplyToPrCommentResult, "resolve-pr-thread" => ResolvePrThreadResult, - }) { - result + })? { + dispatched_result } else { match tool_name { // Informational outputs — no side effects, always succeed From 02e0e09f63fea90e00cbfb44a569e0a5fef8d320 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 23 Apr 2026 06:50:12 +0000 Subject: [PATCH 4/4] fix: restore field-level executor debug logs Agent-Logs-Url: https://github.com/githubnext/ado-aw/sessions/0cb82419-b049-4b08-9430-6d959a95135e Co-authored-by: jamesadevine <4742697+jamesadevine@users.noreply.github.com> --- src/safeoutputs/add_build_tag.rs | 1 + src/safeoutputs/add_pr_comment.rs | 6 +++++- src/safeoutputs/comment_on_work_item.rs | 21 +++++++++++++-------- src/safeoutputs/create_branch.rs | 1 + src/safeoutputs/create_git_tag.rs | 1 + src/safeoutputs/create_pr.rs | 4 ++++ src/safeoutputs/create_wiki_page.rs | 6 +++++- src/safeoutputs/create_work_item.rs | 6 +++++- src/safeoutputs/link_work_items.rs | 4 ++++ src/safeoutputs/queue_build.rs | 1 + src/safeoutputs/reply_to_pr_comment.rs | 4 ++++ src/safeoutputs/resolve_pr_thread.rs | 4 ++++ src/safeoutputs/submit_pr_review.rs | 4 ++++ src/safeoutputs/update_pr.rs | 4 ++++ src/safeoutputs/update_wiki_page.rs | 6 +++++- src/safeoutputs/update_work_item.rs | 1 + src/safeoutputs/upload_attachment.rs | 4 ++++ 17 files changed, 66 insertions(+), 12 deletions(-) diff --git a/src/safeoutputs/add_build_tag.rs b/src/safeoutputs/add_build_tag.rs index c73bf4a..8e4711b 100644 --- a/src/safeoutputs/add_build_tag.rs +++ b/src/safeoutputs/add_build_tag.rs @@ -112,6 +112,7 @@ impl Executor for AddBuildTagResult { async fn execute_impl(&self, ctx: &ExecutionContext) -> anyhow::Result { info!("Adding tag '{}' to build #{}", self.tag, self.build_id); + debug!("add-build-tag: build_id={}, tag='{}'", self.build_id, self.tag); // 1. Extract required context let org_url = ctx diff --git a/src/safeoutputs/add_pr_comment.rs b/src/safeoutputs/add_pr_comment.rs index 0576465..2c72ad8 100644 --- a/src/safeoutputs/add_pr_comment.rs +++ b/src/safeoutputs/add_pr_comment.rs @@ -208,6 +208,11 @@ impl Executor for AddPrCommentResult { self.pull_request_id, self.content.len() ); + debug!( + "add-pr-comment: pr_id={}, content length={}", + self.pull_request_id, + self.content.len() + ); let org_url = ctx .ado_org_url @@ -625,4 +630,3 @@ allowed-statuses: ); } } - diff --git a/src/safeoutputs/comment_on_work_item.rs b/src/safeoutputs/comment_on_work_item.rs index a0d6fe2..24fc9f6 100644 --- a/src/safeoutputs/comment_on_work_item.rs +++ b/src/safeoutputs/comment_on_work_item.rs @@ -170,14 +170,19 @@ impl Executor for CommentOnWorkItemResult { format!("comment on work item #{}", self.work_item_id) } - async fn execute_impl(&self, ctx: &ExecutionContext) -> anyhow::Result { - info!( - "Commenting on work item #{}: {} chars", - self.work_item_id, - self.body.len() - ); - - let org_url = ctx + async fn execute_impl(&self, ctx: &ExecutionContext) -> anyhow::Result { + info!( + "Commenting on work item #{}: {} chars", + self.work_item_id, + self.body.len() + ); + debug!( + "comment-on-work-item: work_item_id={}, body length={}", + self.work_item_id, + self.body.len() + ); + + let org_url = ctx .ado_org_url .as_ref() .context("AZURE_DEVOPS_ORG_URL not set")?; diff --git a/src/safeoutputs/create_branch.rs b/src/safeoutputs/create_branch.rs index 614b0dd..59e4bf8 100644 --- a/src/safeoutputs/create_branch.rs +++ b/src/safeoutputs/create_branch.rs @@ -201,6 +201,7 @@ impl Executor for CreateBranchResult { async fn execute_impl(&self, ctx: &ExecutionContext) -> anyhow::Result { info!("Creating branch: '{}'", self.branch_name); + debug!("create-branch: branch_name='{}'", self.branch_name); let org_url = ctx .ado_org_url diff --git a/src/safeoutputs/create_git_tag.rs b/src/safeoutputs/create_git_tag.rs index 1c04481..be9d1ec 100644 --- a/src/safeoutputs/create_git_tag.rs +++ b/src/safeoutputs/create_git_tag.rs @@ -244,6 +244,7 @@ impl Executor for CreateGitTagResult { async fn execute_impl(&self, ctx: &ExecutionContext) -> anyhow::Result { info!("Creating git tag: '{}'", self.tag_name); + debug!("create-git-tag: tag_name='{}'", self.tag_name); let org_url = ctx .ado_org_url diff --git a/src/safeoutputs/create_pr.rs b/src/safeoutputs/create_pr.rs index bde8b03..ea246f8 100644 --- a/src/safeoutputs/create_pr.rs +++ b/src/safeoutputs/create_pr.rs @@ -541,6 +541,10 @@ impl Executor for CreatePrResult { "Creating PR: '{}' in repository '{}'", self.title, self.repository ); + debug!( + "create-pull-request: title='{}', repo='{}', branch='{}', patch='{}'", + self.title, self.repository, self.source_branch, self.patch_file + ); debug!("PR description length: {} chars", self.description.len()); debug!("Source branch: {}", self.source_branch); debug!("Patch file: {}", self.patch_file); diff --git a/src/safeoutputs/create_wiki_page.rs b/src/safeoutputs/create_wiki_page.rs index 29d2188..2b49c15 100644 --- a/src/safeoutputs/create_wiki_page.rs +++ b/src/safeoutputs/create_wiki_page.rs @@ -192,6 +192,11 @@ impl Executor for CreateWikiPageResult { async fn execute_impl(&self, ctx: &ExecutionContext) -> anyhow::Result { info!("Creating wiki page: '{}'", self.path); + debug!( + "create-wiki-page: path='{}', content length={}", + self.path, + self.content.len() + ); debug!("Content length: {} chars", self.content.len()); let org_url = ctx @@ -922,4 +927,3 @@ wiki-name: "MyProject.wiki" assert_eq!(encoded, "MyProject.wiki"); } } - diff --git a/src/safeoutputs/create_work_item.rs b/src/safeoutputs/create_work_item.rs index 65e01a4..6cb7ab5 100644 --- a/src/safeoutputs/create_work_item.rs +++ b/src/safeoutputs/create_work_item.rs @@ -243,6 +243,11 @@ impl Executor for CreateWorkItemResult { async fn execute_impl(&self, ctx: &ExecutionContext) -> anyhow::Result { info!("Creating work item: '{}'", self.title); + debug!( + "create-work-item: title='{}', description length={}", + self.title, + self.description.len() + ); debug!("Description length: {} chars", self.description.len()); let org_url = ctx @@ -538,4 +543,3 @@ tags: assert_eq!(config.tags, vec!["my-tag"]); } } - diff --git a/src/safeoutputs/link_work_items.rs b/src/safeoutputs/link_work_items.rs index 5ae3746..d49dfef 100644 --- a/src/safeoutputs/link_work_items.rs +++ b/src/safeoutputs/link_work_items.rs @@ -145,6 +145,10 @@ impl Executor for LinkWorkItemsResult { "Linking work item #{} -> #{} ({})", self.source_id, self.target_id, self.link_type ); + debug!( + "link-work-items: source={}, target={}, type={}", + self.source_id, self.target_id, self.link_type + ); let org_url = ctx .ado_org_url diff --git a/src/safeoutputs/queue_build.rs b/src/safeoutputs/queue_build.rs index 9c9998e..3c7abb1 100644 --- a/src/safeoutputs/queue_build.rs +++ b/src/safeoutputs/queue_build.rs @@ -139,6 +139,7 @@ impl Executor for QueueBuildResult { async fn execute_impl(&self, ctx: &ExecutionContext) -> anyhow::Result { info!("Queuing build for pipeline definition {}", self.pipeline_id); + debug!("queue-build: pipeline_id={}", self.pipeline_id); let org_url = ctx .ado_org_url diff --git a/src/safeoutputs/reply_to_pr_comment.rs b/src/safeoutputs/reply_to_pr_comment.rs index af09292..87e0595 100644 --- a/src/safeoutputs/reply_to_pr_comment.rs +++ b/src/safeoutputs/reply_to_pr_comment.rs @@ -110,6 +110,10 @@ impl Executor for ReplyToPrCommentResult { self.thread_id, self.content.len() ); + debug!( + "reply-to-pr-review-comment: pr_id={}, thread_id={}", + self.pull_request_id, self.thread_id + ); let org_url = ctx .ado_org_url diff --git a/src/safeoutputs/resolve_pr_thread.rs b/src/safeoutputs/resolve_pr_thread.rs index 8c089b9..3cd68c1 100644 --- a/src/safeoutputs/resolve_pr_thread.rs +++ b/src/safeoutputs/resolve_pr_thread.rs @@ -142,6 +142,10 @@ impl Executor for ResolvePrThreadResult { "Resolving thread #{} on PR #{} with status '{}'", self.thread_id, self.pull_request_id, self.status ); + debug!( + "resolve-pr-thread: pr_id={}, thread_id={}, status='{}'", + self.pull_request_id, self.thread_id, self.status + ); let org_url = ctx .ado_org_url diff --git a/src/safeoutputs/submit_pr_review.rs b/src/safeoutputs/submit_pr_review.rs index 46f92fd..b184eeb 100644 --- a/src/safeoutputs/submit_pr_review.rs +++ b/src/safeoutputs/submit_pr_review.rs @@ -142,6 +142,10 @@ impl Executor for SubmitPrReviewResult { "Submitting review on PR #{} — event: {}", self.pull_request_id, self.event ); + debug!( + "submit-pr-review: pr_id={}, event='{}'", + self.pull_request_id, self.event + ); let org_url = ctx .ado_org_url diff --git a/src/safeoutputs/update_pr.rs b/src/safeoutputs/update_pr.rs index 85470e1..e22e608 100644 --- a/src/safeoutputs/update_pr.rs +++ b/src/safeoutputs/update_pr.rs @@ -240,6 +240,10 @@ impl Executor for UpdatePrResult { "Updating PR #{} — operation: {}", self.pull_request_id, self.operation ); + debug!( + "update-pr: pr_id={}, operation='{}'", + self.pull_request_id, self.operation + ); let org_url = ctx .ado_org_url diff --git a/src/safeoutputs/update_wiki_page.rs b/src/safeoutputs/update_wiki_page.rs index 8196247..b466994 100644 --- a/src/safeoutputs/update_wiki_page.rs +++ b/src/safeoutputs/update_wiki_page.rs @@ -190,6 +190,11 @@ impl Executor for UpdateWikiPageResult { async fn execute_impl(&self, ctx: &ExecutionContext) -> anyhow::Result { info!("Editing wiki page: '{}'", self.path); + debug!( + "update-wiki-page: path='{}', content length={}", + self.path, + self.content.len() + ); debug!("Content length: {} chars", self.content.len()); let org_url = ctx @@ -885,4 +890,3 @@ wiki-name: "MyProject.wiki" assert_eq!(encoded, "MyProject.wiki"); } } - diff --git a/src/safeoutputs/update_work_item.rs b/src/safeoutputs/update_work_item.rs index 906c827..8828f73 100644 --- a/src/safeoutputs/update_work_item.rs +++ b/src/safeoutputs/update_work_item.rs @@ -248,6 +248,7 @@ impl Executor for UpdateWorkItemResult { async fn execute_impl(&self, ctx: &ExecutionContext) -> anyhow::Result { info!("Updating work item #{}", self.id); + debug!("update-work-item: id={}", self.id); debug!( "Fields: title={:?}, body_len={:?}, state={:?}, area={:?}, iter={:?}, assignee={:?}, tags={:?}", self.title, diff --git a/src/safeoutputs/upload_attachment.rs b/src/safeoutputs/upload_attachment.rs index 6853bf7..5342fb0 100644 --- a/src/safeoutputs/upload_attachment.rs +++ b/src/safeoutputs/upload_attachment.rs @@ -137,6 +137,10 @@ impl Executor for UploadAttachmentResult { "Uploading attachment '{}' to work item #{}", self.file_path, self.work_item_id ); + debug!( + "upload-attachment: work_item_id={}, file_path='{}'", + self.work_item_id, self.file_path + ); let org_url = ctx .ado_org_url