Skip to content

fix: ensure safe-outputs staged mode works for all handler types#21414

Merged
pelikhan merged 10 commits intomainfrom
copilot/ensure-safe-outputs-staged-support
Mar 17, 2026
Merged

fix: ensure safe-outputs staged mode works for all handler types#21414
pelikhan merged 10 commits intomainfrom
copilot/ensure-safe-outputs-staged-support

Conversation

Copy link
Contributor

Copilot AI commented Mar 17, 2026

safe-outputs.staged: true silently broke for most handler types due to two independent bugs.

Schema — staged rejected by parser for 38/40 handlers

All handler schemas use additionalProperties: false. Only close-pull-request and push-to-pull-request-branch had staged in their properties; adding staged: true to any other handler (e.g. create-issue, add-comment, create-discussion) caused a parser validation error.

Added staged field to all 38 missing handler schemas.

Compiler — global staged env var only emitted for 7/40 handlers

addAllSafeOutputConfigEnvVars emitted GH_AW_SAFE_OUTPUTS_STAGED: "true" only when one of 7 hardcoded handlers was configured. A workflow with:

safe-outputs:
  staged: true
  create-discussion: null

would parse successfully (after the schema fix) but silently drop the staged env var, so the JS runtime never entered staged mode.

Replaced the per-handler logic with a single hasSafeOutputConfigured() helper that covers all 40 handler types. Staged mode is independent of target-repo: it activates whenever staged: true is set and at least one handler is configured, regardless of whether a cross-repo target-repo is specified.

Integration Tests

Added workflow files in pkg/cli/workflows/ and integration tests in compile_integration_test.go to cover the fixed scenarios end-to-end:

  • test-staged-create-issue.md / test-staged-add-comment.md / test-staged-create-discussion.md — previously broken by the schema bug; tests verify compilation succeeds and GH_AW_SAFE_OUTPUTS_STAGED: "true" appears in the compiled output
  • test-staged-cross-repo.md — verifies staged env var is emitted even when target-repo is configured on the handler
  • TestCompileStagedSafeOutputsMultipleHandlers — verifies staged works across multiple handler types in one workflow

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.



✨ PR Review Safe Output Test - Run 23218362372

💥 [THE END] — Illustrated by Smoke Claude ·

Copilot AI and others added 2 commits March 17, 2026 15:28
…piler

- Add `staged` field to all 38 handler schemas in main_workflow_schema.json
  (previously only close-pull-request and push-to-pull-request-branch had it;
  all schemas have `additionalProperties: false` so missing staged caused parser rejection)
- Refactor compiler_safe_outputs_env.go: replace per-handler staged flag logic
  with a single hasSafeOutputWithoutTargetRepo() helper that covers all 40 handlers,
  fixing the bug where handlers like create-discussion, autofix-code-scanning-alert,
  noop, etc. never triggered the GH_AW_SAFE_OUTPUTS_STAGED env var
- Add TestStagedFlagForAllHandlerTypes covering previously untested handler types

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

@copilot, review again and make sure all safe-outputs have the same staged behavior and test cases.

@pelikhan
Copy link
Contributor

@copilot stage is independent of target-repo, remove special handling

…l handler types

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

Copilot AI commented Mar 17, 2026

@copilot stage is independent of target-repo, remove special handling

Done in 026fc8d. Removed the target-repo gate entirely — hasSafeOutputWithoutTargetRepo() is replaced by hasSafeOutputConfigured() which returns true for any configured handler regardless of target-repo. Updated all existing tests that expected staged to be suppressed by target-repo, and added test cases covering all 39 handler types (both with and without target-repo).

Copilot AI review requested due to automatic review settings March 17, 2026 19:56
@pelikhan
Copy link
Contributor

@copilot review code and add integration tests in pkg/cli/workflows

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes safe-outputs staged mode so it validates across all handler schemas and reliably emits the global staged env var for any configured handler (rather than a hardcoded subset).

Changes:

  • Add staged support to the JSON schema for all safe-output handler config objects (previously missing for most handlers due to additionalProperties: false).
  • Update compiler env-var emission to use a centralized “any handler configured” check instead of per-handler hardcoding.
  • Expand tests and update the locked workflow output to reflect the staged env var being emitted.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
pkg/workflow/compiler_safe_outputs_env.go Replaces per-handler staged env-var logic with a single global check + helper.
pkg/workflow/compiler_safe_outputs_env_test.go Updates staged/target-repo expectations and adds broad coverage across handler types.
pkg/parser/schemas/main_workflow_schema.json Adds staged to handler schemas so staged options validate under strict schemas.
.github/workflows/daily-choice-test.lock.yml Updates locked workflow output to include GH_AW_SAFE_OUTPUTS_STAGED.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +523 to +529
// TestStagedFlagForAllHandlerTypes tests that the staged flag is emitted for all safe output handler types.
func TestStagedFlagForAllHandlerTypes(t *testing.T) {
tests := []struct {
name string
safeOutputs *SafeOutputsConfig
expectFlag bool
}{
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 17, 2026

@copilot review code and add integration tests in pkg/cli/workflows

Added in 1b120ce.

Workflow files in pkg/cli/workflows/:

  • test-staged-create-issue.md — staged + create-issue (schema fix)
  • test-staged-add-comment.md — staged + add-comment (schema fix)
  • test-staged-create-discussion.md — staged + create-discussion (schema fix)
  • test-staged-cross-repo.md — staged + target-repo (independence from target-repo)

Integration tests in compile_integration_test.go:

  • TestCompileStagedSafeOutputsCreateIssue / AddComment / CreateDiscussion — verify previously-broken handler types now compile and emit GH_AW_SAFE_OUTPUTS_STAGED: "true"
  • TestCompileStagedSafeOutputsWithTargetRepo — verifies staged env var is present even when target-repo is set
  • TestCompileStagedSafeOutputsMultipleHandlers — verifies staged works with multiple handler types

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/actions/github-script/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha INVALID,NEW -j DROP (http block)

If you need me to access, download, or install something from one of these locations, you can either:

pelikhan and others added 2 commits March 17, 2026 14:03
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@pelikhan
Copy link
Contributor

@copilot review all comments

Copy link
Contributor Author

Copilot AI commented Mar 17, 2026

@copilot review all comments

Addressed in a84b101:

  • hasSafeOutputConfigured wrapper removed — also fixed a syntax error where the old function body was left as dead code outside the function. The call site now calls hasAnySafeOutputEnabled directly, which is driven by safeOutputFieldMapping and stays in sync automatically.

  • TestStagedFlagForAllHandlerTypes refactored — replaced the 90-line hardcoded table with a reflection-driven loop over safeOutputFieldMapping. One sub-test is generated per registered handler; the test stays complete as new handlers are added to the mapping.

@github-actions
Copy link
Contributor

Contribution Check Report

Hey @Copilot 👋 — great work on this fix! Patching safe-outputs staged mode across all 40 handler types is a meaningful correctness fix and the PR is thorough and well-structured.

This PR looks ready for maintainer review. 🎉

Check Result
On-topic ✅ yes
Follows process ✅ yes (core-team Copilot agent PR)
Focused ✅ yes
New dependencies ✅ no
Has tests ✅ yes — integration + unit tests added
Has description ✅ yes — detailed two-bug breakdown
Lines changed 1,237 (+1,129 / -108)

Verdict: 🟢 Aligned — quality: lgtm

Generated by Contribution Check ·

@github-actions
Copy link
Contributor

github-actions bot commented Mar 17, 2026

🎬 THE ENDSmoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨

@github-actions
Copy link
Contributor

github-actions bot commented Mar 17, 2026

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

@github-actions
Copy link
Contributor

📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing...

@github-actions github-actions bot removed the smoke label Mar 17, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 17, 2026

✅ All tools validated successfully! Agent Container Smoke Test confirms agent container is ready.

@github-actions
Copy link
Contributor

Agent Container Tool Check

Tool Status Version
bash 5.2.21
sh available
git 2.53.0
jq 1.7
yq v4.52.4
curl 8.5.0
gh 2.87.3
node v20.20.1
python3 3.12.3
go 1.24.13
java 21.0.10 (Temurin)
dotnet 10.0.102

Result: 12/12 tools available ✅

Overall Status: PASS

🔧 Tool validation by Agent Container Smoke Test ·

@github-actions
Copy link
Contributor

Smoke test (Codex) results:

🔮 The oracle has spoken through Smoke Codex ·

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.

@github-actions
Copy link
Contributor

Commit pushed: d32bd60

Generated by Changeset Generator

@github-actions
Copy link
Contributor

@copilot-swe-agent @pelikhan — smoke test results for run §23218362365:

Test
GitHub MCP
MCP Scripts GH CLI
Serena MCP ❌ (unavailable)
Playwright
Web Fetch
File Write + Bash
Discussion
Build
PR Review

Overall: ⚠️ PARTIAL PASS (Serena not configured)

📰 BREAKING: Report filed by Smoke Copilot ·

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Smoke test review: the staged-flag centralization is a clean improvement. One minor nit on the double-nested if in the create-issues block — could be collapsed, but not blocking.

📰 BREAKING: Report filed by Smoke Copilot

stagedFlagAdded := false
// Add the global staged env var once if staged mode is enabled, not in trial mode,
// and at least one handler is configured. Staged mode is independent of target-repo.
if !c.trialMode && data.SafeOutputs.Staged && hasAnySafeOutputEnabled(data.SafeOutputs) {
Copy link
Contributor

Choose a reason for hiding this comment

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

✅ Clean refactor — centralizing the staged flag check here eliminates the duplicated per-handler stagedFlagAdded logic. The comment is also clear about the intent (Staged mode is independent of target-repo).

}
// Check if copilot is in assignees - if so, we'll output issues for assign_to_agent job
if hasCopilotAssignee(cfg.Assignees) {
if hasCopilotAssignee(data.SafeOutputs.CreateIssues.Assignees) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor nit: the double if nesting could be collapsed into a single if data.SafeOutputs.CreateIssues != nil && hasCopilotAssignee(data.SafeOutputs.CreateIssues.Assignees) for conciseness. Not a blocker though.

@github-actions
Copy link
Contributor

📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤

@github-actions
Copy link
Contributor

Smoke Test Results — Run §23218362372

Test Result
1 GitHub MCP
2 GH CLI (mcpscripts)
3 Serena MCP
4 Make Build
5 Playwright
6 Tavily Search
7 File Write
8 Bash Tool
9 Discussion Comment
10 Agentic Workflows MCP
11 Update PR
12 Review Comments
13 Submit Review
14 Resolve Thread ⚠️ skipped
15 Add Reviewer
16 Push to PR Branch
17 Close PR ⚠️ skipped

Overall: PARTIAL (2 skipped, 0 failed)

💥 [THE END] — Illustrated by Smoke Claude ·

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.

3 participants