Skip to content

Add Azure DevOps work-item safe outputs - #57796

Open
pelikhan with Copilot wants to merge 9 commits into
mainfrom
copilot/add-safe-outputs-support
Open

Add Azure DevOps work-item safe outputs#57796
pelikhan with Copilot wants to merge 9 commits into
mainfrom
copilot/add-safe-outputs-support

Conversation

Copilot AI commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Adds Azure DevOps work-item operations to the safe-output pipeline using the tool names defined by ado-aw.

Changes

  • Safe-output tools

    • Adds create-work-item, update-work-item, comment-on-work-item, assign-work-item, link-work-items, and upload-workitem-attachment.
    • Extends frontmatter parsing, schemas, validation, limits, and handler registration.
  • Azure DevOps integration

    • Executes trusted REST operations through actions/github-script.
    • Authenticates with SYSTEM_ACCESSTOKEN or AZURE_DEVOPS_EXT_PAT.
    • Supports temporary IDs for same-run work-item references.
  • Policy enforcement

    • Restricts mutations by work-item ID or area path.
    • Enforces configurable fields, tags, assignees, link types, and attachment constraints.
    • Rejects untrusted organization URLs, reserved identities, unsafe paths, symlinks, and pipeline command sequences.
  • Artifact handling

    • Stages attachments through the existing safe-output artifact channel.
    • Records Azure DevOps work items and metadata in the safe-output manifest.
safe-outputs:
  create-work-item:
    work-item-type: Task
    area-path: MyProject\Platform
  update-work-item:
    target: MyProject\Platform
    title: true
    status: true

Run: https://github.com/github/gh-aw/actions/runs/33581675739

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • github.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"

See Network Configuration for more information.

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 14.5 AIC · ⌖ 8.74 AIC · ⊞ 8.9K ·
Comment /souschef to run again

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan

pelikhan commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

@copilot review the plan and continue implementation where it was not finished.

@pelikhan

pelikhan commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

@copilot mark all these safe outputs as experimental

Copilot AI and others added 3 commits September 2, 2026 00:09
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan

pelikhan commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

@copilot ensure appropriate level of logging. Run custom linters for extra code quality.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

@copilot mark all these safe outputs as experimental

Marked all six Azure DevOps safe outputs experimental in compiler warnings, schemas, tool descriptions, documentation, and the changeset, with focused warning tests in commit 3ebdd17.

@pelikhan

pelikhan commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

@copilot Mark, update all safe-outputs names and prepend ado_ as a prefix so that they read ADO, create-issue, ADO, update-issue, and so forth.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

@copilot ensure appropriate level of logging. Run custom linters for extra code quality.

Added debug-level Azure API lifecycle logs, standardized staged preview logging, and removed work-item titles and attachment paths from logs in c15fc12. Custom Go linters, custom ESLint, impacted tests, review, CodeQL applicability check, and secret scanning completed.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Mark, update all safe-outputs names and prepend ado_ as a prefix so that they read ADO, create-issue, ADO, update-issue, and so forth.

Prefixed all Azure DevOps safe-output names in 59f0c00: frontmatter keys now use ado- and public/persisted tool names use ado_. Runtime routing, schemas, docs, errors, and tests were updated consistently.

@pelikhan
pelikhan marked this pull request as ready for review September 2, 2026 01:18
Copilot AI balanced review requested due to automatic review settings September 2, 2026 01:18
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer failed during the skills-based review.

Warning

Threat Detection Engine Failure — The analysis engine could not complete. This is a tooling failure, not a security finding.

What happened

The threat detection engine failed to produce results.

Review the workflow run logs for details.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • github.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft.

Warning

Firewall blocked 2 domains

The following domains were blocked by the firewall during workflow execution:

  • github.com
  • proxy.golang.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"
    - "proxy.golang.org"

See Network Configuration for more information.

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel failed during test quality analysis.

Warning

Threat Detection Engine Failure — The analysis engine could not complete. This is a tooling failure, not a security finding.

What happened

The threat detection engine failed to produce results.

Review the workflow run logs for details.

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

⚠️ Security scanning failed for Ponytail Reviewer. Review the logs for details.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • ab.chatgpt.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"

See Network Configuration for more information.

Generated by Ponytail Reviewer for #57796

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-09-02T01:21:59Z
review_event: REQUEST_CHANGES
top_themes:
  - azure devops work-item tool argument contract mismatches
  - workflow schema rejects valid multi-target/comment-path configurations
files_reviewed:
  - actions/setup/js/azure_devops_work_items.cjs
  - actions/setup/js/safe_outputs_handlers.cjs
  - actions/setup/js/safe_outputs_tools.json
  - pkg/parser/schemas/main_workflow_schema.json
  - pkg/workflow/safe_outputs_validation_config.go
  - schemas/agent-output.json
comment_count: 3

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • github.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 48.6 AIC · ⌖ 7.51 AIC · ⊞ 23.5K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes

The Azure DevOps safe-output plumbing still has blocking contract mismatches that will break callers as soon as these tools are used.

Blocking themes
  • Several new handlers disagree on argument names between the advertised tool schema, the queueing layer, and the executor, so valid tool calls are transformed into malformed safe-output entries.
  • The workflow schema narrows some target shapes below what the runtime explicitly supports, which will reject documented configurations at compile time.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • github.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 48.6 AIC · ⌖ 7.51 AIC · ⊞ 23.5K
Comment /review to run again

Comments that could not be inline-anchored

pkg/parser/schemas/main_workflow_schema.json:1476

The workflow schema rejects valid targets for ado-update-work-item and ado-assign-work-item: the runtime accepts an area-path string for updates and an ID list for assignments, but main_workflow_schema.json narrows those configs to &quot;*&quot; or a single integer.

<details><summary>💡 Compile-time schema needs to cover every runtime-supported target form</summary>

enforceTarget and the docs explicitly support area-path strings, and comment/link tools already reuse `azure_devops_work_item_ta…

actions/setup/js/safe_outputs_tools.json:1836

The JSON schemas and runtime disagree on ado_upload_workitem_attachment: the tool definition omits staged_file, but both the validator and agent-output.json require it, so the agent can never emit a payload that passes the write-side contract.

<details><summary>💡 The advertised input shape has to match the persisted safe-output shape</summary>

safe_outputs_tools.json exposes only work_item_id, file_path, and optional comment, but ValidationConfig and `UploadWorkItemAttachment…

actions/setup/js/safe_outputs_handlers.test.cjs:1025

The public ado_comment_on_work_item and ado_assign_work_item schemas require work_item_id, but the queueing tests and handlers still send id; that drops the identifier before execution and makes same-run temporary IDs unusable for two of the new tools.

<details><summary>💡 Keep one identifier contract end to end</summary>

The executor reads message.work_item_id, while safe_outputs_handlers.test.cjs exercises commentOnWorkItemHandler({ id: &quot;#item&quot;, ... }) and `assignWorkItemHandl…

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

ADR Required

This PR adds a new architectural capability: Azure DevOps work-item mutations as first-class safe outputs (ado_create_work_item, ado_update_work_item, ado_comment_on_work_item, ado_assign_work_item, ado_link_work_items, and ado_upload_workitem_attachment). That extends gh-aw's safe-output surface beyond GitHub resources and introduces new policy, naming, threat-model, and attachment-staging behavior.

I generated a draft ADR on this branch:

  • docs/adr/57796-add-azure-devops-work-item-safe-outputs.md

Evidence used:

  • PR body describes a new Azure DevOps integration with configuration-driven policy enforcement.
  • The diff adds a shared azure_devops_work_items.cjs handler, new public namespaced tools, temporary ID support, attachment staging, and threat-policy registration.
  • The PR exceeds the default design gate threshold for implementation work in business-logic directories.

Next action:

  1. Review and refine the draft ADR.
  2. Keep or update the recorded decision, alternatives, and consequences so they match the intended long-term architecture.
  3. Once reviewed, proceed with the implementation using the ADR as the explicit design record.

Warning

Firewall blocked 2 domains

The following domains were blocked by the firewall during workflow execution:

  • github.com
  • proxy.golang.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"
    - "proxy.golang.org"

See Network Configuration for more information.

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · pi · gpt54 · 27.9 AIC · ⌖ 11.6 AIC · ⊞ 9.9K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of small abstraction layers in the new Azure DevOps safe-output helper can be cut back without changing behavior; net: -18 lines possible.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • ab.chatgpt.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"

See Network Configuration for more information.

Generated by ✂️ Ponytail Reviewer for #57796 · codex · mai10 · 8.37 AIC · ⌖ 0.443 AIC · ⊞ 13.5K
Comment /ponytail to run again

}
}

const HANDLERS = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actions/setup/js/azure_devops_work_items.cjs:515-528: yagni: generic dispatch table for six Azure DevOps actions. Export the concrete handlers directly and skip the wrapper until there is a real second consumer.

});
}

function validateAllowedTags(tags, allowedTags) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actions/setup/js/azure_devops_work_items.cjs:64-82: yagni: tag/path allowlist helpers are tiny policy shims with one call site each. Inline the checks in the create/update branches and let the module stay focused on the API work.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Attachment scoping, artifact staging, schema inconsistencies, and JSON Patch operations can cause unauthorized or failed mutations.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds experimental Azure DevOps work-item mutations to the safe-output pipeline, including policy enforcement, temporary IDs, and attachment staging.

Changes:

  • Adds six Azure DevOps work-item tools and trusted REST handlers.
  • Extends schemas, compiler wiring, validation, and documentation.
  • Adds temporary-ID, artifact-staging, and handler tests.
File summaries
File Description
schemas/agent-output.json Adds Azure DevOps output schemas.
pkg/workflow/tool_description_enhancer.go Registers tool constraints.
pkg/workflow/safe_outputs_validation_config.go Defines output validation rules.
pkg/workflow/safe_outputs_tools_computation.go Enables configured tools.
pkg/workflow/safe_outputs_state.go Detects enabled Azure outputs.
pkg/workflow/safe_outputs_max_validation.go Validates operation limits.
pkg/workflow/safe_outputs_handler_registry.go Registers Azure handlers.
pkg/workflow/safe_outputs_handler_registry_test.go Tests handler registration.
pkg/workflow/safe_outputs_config_types.go Adds frontmatter configuration fields.
pkg/workflow/safe_outputs_config_extraction.go Extracts Azure configuration.
pkg/workflow/safe_outputs_azure_devops.go Implements compiler-side Azure configuration.
pkg/workflow/safe_outputs_azure_devops_test.go Tests configuration generation.
pkg/workflow/safe_output_validation_config_test.go Extends validation consistency tests.
pkg/workflow/safe_output_handlers.go Describes Azure handler mappings.
pkg/workflow/publish_artifacts.go Enables attachment artifact transfer.
pkg/workflow/js/safe_outputs_tools.json Defines compiler tool schemas.
pkg/workflow/compiler_validators.go Emits experimental warnings.
pkg/workflow/compiler_safe_outputs_job.go Integrates handlers and downloads.
pkg/workflow/azure_devops_experimental_warning_test.go Tests warning emission.
pkg/parser/schemas/main_workflow_schema.json Defines frontmatter schemas.
docs/src/content/docs/reference/safe-outputs.md Documents Azure outputs.
actions/setup/js/upload_workitem_attachment.cjs Wraps attachment handling.
actions/setup/js/update_work_item.cjs Wraps update handling.
actions/setup/js/temporary_id.test.cjs Tests Azure temporary references.
actions/setup/js/temporary_id.cjs Recognizes Azure ID fields.
actions/setup/js/safe_outputs_tools.json Defines runtime tool schemas.
actions/setup/js/safe_outputs_tools_loader.test.cjs Tests handler attachment.
actions/setup/js/safe_outputs_tools_loader.cjs Loads normalized Azure tools.
actions/setup/js/safe_outputs_handlers.test.cjs Tests proposal collection.
actions/setup/js/safe_outputs_handlers.cjs Collects and stages proposals.
actions/setup/js/safe_output_handler_manager.cjs Dispatches handlers and IDs.
actions/setup/js/mcp_server_core.cjs Preserves public tool names.
actions/setup/js/link_work_items.cjs Wraps link handling.
actions/setup/js/generate_safe_outputs_tools.test.cjs Tests tool-name preservation.
actions/setup/js/generate_safe_outputs_tools.cjs Normalizes enabled tools.
actions/setup/js/create_work_item.cjs Wraps creation handling.
actions/setup/js/comment_on_work_item.cjs Wraps comment handling.
actions/setup/js/azure_devops_work_items.test.cjs Tests Azure REST policies.
actions/setup/js/azure_devops_work_items.cjs Implements trusted REST operations.
actions/setup/js/assign_work_item.cjs Wraps assignment handling.
.changeset/minor-azure-devops-work-item-safe-outputs.md Records the minor feature.
Review details

Suppressed comments (2)

actions/setup/js/azure_devops_work_items.cjs:360

  • The multiline-format member may not exist yet, so JSON Patch replace can reject the otherwise valid body update. Use add, which creates the member or replaces its current value.
      patch.push({ op: "replace", path: "/multilineFieldsFormat/System.Description", value: "Markdown" });

actions/setup/js/azure_devops_work_items.cjs:402

  • A previously unassigned work item commonly has no System.AssignedTo member, making this replace operation fail. Use JSON Patch add, which also updates the value when the member already exists.
    await adoRequest(ado, "PATCH", `/_apis/wit/workitems/${resolved.id}?api-version=7.0`, [fieldPatch("replace", "System.AssignedTo", assignee)], "application/json-patch+json");
  • Files reviewed: 42/42 changed files
  • Comments generated: 7
  • Review effort level: Balanced

Comment on lines +479 to +483
const resolved = resolveWorkItemReference(message.work_item_id, resolvedTemporaryIds, preview);
if (preview) return staged(`Would attach a file to Azure DevOps work item ${message.work_item_id}`);
const { bytes, filename } = readStagedAttachment(message, config);
const ado = getAzureDevOpsContext();
const upload = await adoRequest(ado, "POST", `/_apis/wit/attachments?fileName=${encodeURIComponent(filename)}&api-version=7.1`, bytes, "application/octet-stream");
}
const patch = requested.map(([name, field]) => {
const value = name === "tags" ? message.tags.join("; ") : message[name];
return fieldPatch("replace", field, value);

const uploadWorkItemAttachmentHandler = args => {
const entry = { ...(args || {}), type: "ado_upload_workitem_attachment" };
const rawPath = typeof entry.file_path === "string" ? entry.file_path.trim() : "";
const stagingRoot = path.join(process.env.RUNNER_TEMP || "/tmp", "gh-aw", "safeoutputs", "upload-artifacts");
const stagingDirectory = path.join(stagingRoot, "azure-devops-work-items");
fs.mkdirSync(stagingDirectory, { recursive: true, mode: 0o700 });
const stagedName = `${crypto.randomUUID()}-${path.basename(rawPath)}`;
Comment on lines +13214 to +13216
"target": {
"oneOf": [{ "type": "integer", "minimum": 1 }, { "const": "*" }]
},
Comment on lines +192 to +193
func usesSafeOutputsArtifactStaging(config *SafeOutputsConfig) bool {
return config != nil && (config.UploadArtifact != nil || config.UploadWorkItemAttachments != nil)
}

func parseAzureDevOpsConfig[T any](c *Compiler, outputMap map[string]any, key string, defaultMax int, postProcess func(*T)) *T {
if enabled, ok := outputMap[key].(bool); ok {
@pelikhan

pelikhan commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot Please take another pass on this PR: refresh the branch with the latest base, address any outstanding review or CI follow-up, and then continue with the pr-finisher skill before handing back to maintainers.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • github.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "github.com"

See Network Configuration for more information.

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 14.5 AIC · ⌖ 8.74 AIC · ⊞ 8.9K ·
Comment /souschef to run again

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants