Fix: compiler silently drops update-issue tool when target-repo: "*" is set - #17247
Conversation
…am in tools.json Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Fixes safe-outputs tool generation/config parsing so target-repo: "*" no longer causes update-issue to be silently omitted from generated tools.json, and adjusts tool schema generation to account for wildcard targeting.
Changes:
- Update
ParseTargetConfigto allowtarget-repo: "*"(wildcard) instead of treating it as invalid. - Update tool schema generation to inject a
repoparameter whentarget-repois"*"so callers can select the repository at runtime. - Add tests covering parsing and tool JSON generation for wildcard
target-repo.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| pkg/workflow/safe_output_builder.go | Allows target-repo: "*" to parse successfully via parseTargetRepoFromConfig. |
| pkg/workflow/safe_outputs_tools_generation.go | Adds repo property to tool schemas when allowed-repos is set or target-repo == "*". |
| pkg/workflow/safe_outputs_tools_generation_test.go | Adds unit tests for wildcard target-repo behavior in parsing and tools JSON generation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -512,7 +516,7 @@ func addRepoParameterIfNeeded(tool map[string]any, toolName string, safeOutputs | |||
| "description": repoDescription, | |||
| } | |||
|
|
|||
There was a problem hiding this comment.
When targetRepoSlug == "*", the generated tool schema adds a repo property but does not mark it as required. With a wildcard target repo there’s no meaningful default, so omitting repo will either cause runtime validation/parsing failures (e.g., trying to use "*") or silently target an unintended repository. Consider appending "repo" to inputSchema.required when targetRepoSlug == "*" (handling both []any and []string shapes from JSON unmarshalling).
| // When targeting any repository ("*"), there is no meaningful default repo. | |
| // Ensure that the repo parameter is marked as required in the input schema. | |
| if targetRepoSlug == "*" { | |
| if requiredRaw, ok := inputSchema["required"]; ok { | |
| switch required := requiredRaw.(type) { | |
| case []any: | |
| found := false | |
| for _, v := range required { | |
| if s, ok := v.(string); ok && s == "repo" { | |
| found = true | |
| break | |
| } | |
| } | |
| if !found { | |
| inputSchema["required"] = append(required, "repo") | |
| } | |
| case []string: | |
| found := false | |
| for _, v := range required { | |
| if v == "repo" { | |
| found = true | |
| break | |
| } | |
| } | |
| if !found { | |
| inputSchema["required"] = append(required, "repo") | |
| } | |
| } | |
| } else { | |
| inputSchema["required"] = []string{"repo"} | |
| } | |
| } |
ParseTargetConfigexplicitly rejected"*"as an invalidtarget-repovalue, causing the entire safe-output config to returnnil— silently omitting the tool fromtools.jsonwith no error.Changes
safe_output_builder.go—ParseTargetConfignow usesparseTargetRepoFromConfiginstead ofparseTargetRepoWithValidation, allowing"*"as a valid wildcard meaning "any repository." Create operations (create-issue,add-comment, etc.) are unaffected — they validate via separatevalidateTargetRepoSlugcalls.safe_outputs_tools_generation.go—addRepoParameterIfNeedednow injects arepoparameter into the tool schema whentargetRepoSlug == "*", since the caller must specify the target repository at runtime. Description reads: "Any repository can be targeted."Example
Tests
Three tests added to
safe_outputs_tools_generation_test.go:TestParseUpdateIssuesConfigWithWildcardTargetRepo— config parses to non-nilTestGenerateFilteredToolsJSONUpdateIssueWithWildcardTargetRepo—update_issueappears intools.jsonwithrepoparameterTestAddRepoParameterIfNeededWildcardTargetRepo—repoparam injected for wildcard targetWarning
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/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 GO111MODULE 64/bin/go git remo�� add origin /usr/bin/git -json GO111MODULE 64/bin/go git(http block)/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 -importcfg /usr/bin/git git rev-�� --show-toplevel git cal/bin/bash --get remote.origin.urrev-parse /usr/bin/git git(http block)/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 git cal/bin/bash git _inc�� --show-toplevel git cal/bin/bash --show-toplevel git /usr/bin/git git(http block)https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1/usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha runs/20260220-180106-27492/test-3078994281/.github/workflows GO111MODULE .cfg l GOMOD GOMODCACHE go env -json GO111MODULE ache/node/24.13.0/x64/bin/node GOINSECURE GOMOD GOMODCACHE /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet(http block)/usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha --show-toplevel ache/go/1.25.0/x64/pkg/tool/linux_amd64/compile /usr/bin/bash 6872843/b001/_pkgit GO111MODULE Name,createdAt,s--show-toplevel bash -c unset GOROOT; export PATH="$(find /opt/hostedtoolcache -maxdepth 4 -type d -name bin 2>/dev/nullgit go /usr/bin/git SOm_/qNDVCwmDySLgit GO111MODULE /opt/hostedtoolc--show-toplevel git(http block)/usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha initial.txt bash 0/x64/bin/node unset GOROOT; exgit go /usr/bin/git git rev-�� --show-toplevel git 0/x64/bin/node --show-toplevel go /usr/bin/git git(http block)https://api.github.com/repos/actions/checkout/git/ref/tags/v3/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env 0106-27492/test-1201930976/.github/workflows GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE x_amd64/compile git rev-�� --show-toplevel x_amd64/compile /usr/bin/git -json GO111MODULE ache/go/1.25.0/x--show-toplevel git(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha --show-toplevel git e/git --show-toplevel x_amd64/compile /usr/bin/git e/git rev-�� --show-toplevel git /usr/bin/git --show-toplevel go /usr/bin/git git(http block)https://api.github.com/repos/actions/checkout/git/ref/tags/v4/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq .object.sha auto-triage-issues.md GO111MODULE 0/x64/bin/node GOINSECURE GOMOD GOMODCACHE go -has�� ring3026369526/001/test1.md GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq .object.sha /ref/tags/v8 GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env 0106-27492/test-2841035171 GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq .object.sha /tmp/go-build2146872843/b433/_pkg_.a -trimpath /usr/bin/git -p main -lang=go1.25 git rev-�� --show-toplevel -dwarf=false /usr/bin/git go1.25.0 -c=4 -nolocalimports git(http block)https://api.github.com/repos/actions/checkout/git/ref/tags/v5/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha -json GO111MODULE ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -o /tmp/go-build2146872843/b410/_pkg_.a -trimpath /usr/bin/git -p main -lang=go1.25 git(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel -tests /usr/bin/git k/gh-aw/gh-aw/pkgit GOPROXY 64/bin/go git rev-�� --show-toplevel /opt/hostedtoolcache/go/1.25.0/xGO111MODULE /usr/bin/git /tmp/go-build177git -trimpath 64/bin/go /usr/bin/git(http block)https://api.github.com/repos/actions/github-script/git/ref/tags/v8/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE go env ck 'scripts/**/*GOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD erignore go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha ck 'scripts/**/*GOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/actions/setup-go/git/ref/tags/v4/usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha bot-detection.md GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env 0106-27492/test-2841035171 GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE k/_temp/ghcca-no--show-toplevel git rev-�� --show-toplevel go /usr/bin/git 56 GO111MODULE /opt/hostedtoolc--show-toplevel git(http block)/usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha source '/home/REDACTED/work/gh-aw/gh-aw/actions/setup/sh/sanitize_path.sh' '/usr/bin::/usr/local/bgit git /usr/bin/git --show-toplevel go /usr/bin/git git rev-�� --show-toplevel git 0/x64/bin/node --show-toplevel go /usr/bin/git git(http block)https://api.github.com/repos/actions/setup-node/git/ref/tags/v4/usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha blog-auditor.md GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha --show-toplevel go /usr/bin/git ithub/workflows GO111MODULE 64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel 64/pkg/tool/linux_amd64/compile /usr/bin/git g_.a GO111MODULE /opt/hostedtoolc--show-toplevel git(http block)/usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha source '/home/REDACTED/work/gh-aw/gh-aw/actions/setup/sh/sanitize_path.sh' ':::/usr/bin:/usr/localgit git /usr/bin/git --show-toplevel 64/pkg/tool/linurev-parse /usr/bin/git git rev-�� --show-toplevel git 0/x64/bin/node --show-toplevel go /usr/bin/git git(http block)https://api.github.com/repos/github/gh-aw/actions/runs/1/artifacts/usr/bin/gh gh run download 1 --dir test-logs/run-1 GO111MODULE x_amd64/link GOINSECURE GOMOD GOMODCACHE x_amd64/link env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE -j/NEbzTRrGx3Hf7l9Ai1Xn/DcrjArqgCZ0F2zfYcPZo(http block)https://api.github.com/repos/github/gh-aw/actions/runs/12345/artifacts/usr/bin/gh gh run download 12345 --dir test-logs/run-12345 GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/actions/runs/12346/artifacts/usr/bin/gh gh run download 12346 --dir test-logs/run-12346 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/actions/runs/2/artifacts/usr/bin/gh gh run download 2 --dir test-logs/run-2 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/actions/runs/3/artifacts/usr/bin/gh gh run download 3 --dir test-logs/run-3 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env ub/workflows GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/actions/runs/4/artifacts/usr/bin/gh gh run download 4 --dir test-logs/run-4 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/actions/runs/5/artifacts/usr/bin/gh gh run download 5 --dir test-logs/run-5 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env ub/workflows GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/github/gh-aw/actions/workflows/usr/bin/gh gh workflow list --json name,state,path -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE ache/go/1.25.0/xGO111MODULE env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 100 bagabas/go-udiff--norc GOMODCACHE go env aQFt/j1LVCsnYhPqGOSUMDB GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE 0814000/b382/importcfg(http block)/usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 6 GOMOD GOMODCACHE x_amd64/link env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE 3s/1zjxUpocWPETRcpKPGdz/MCDtZflFd0JXklDccsMD(http block)https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE x_amd64/vet git rev-�� --show-toplevel x_amd64/vet /usr/bin/git -json GO111MODULE 64/bin/go git(http block)/usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel x_amd64/vet /usr/bin/git git rev-�� --show-toplevel git /usr/bin/gh --show-toplevel go /usr/bin/git gh(http block)https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999/usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha ty-test.md GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env 1201930976/.github/workflows GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha --git-dir go /usr/bin/git -json GO111MODULE x_amd64/vet git rev-�� --show-toplevel x_amd64/vet /usr/bin/git -json GO111MODULE 64/bin/go git(http block)/usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha --show-toplevel git /usr/bin/git --show-toplevel x_amd64/vet /usr/bin/git git 0407�� --show-toplevel git /usr/bin/git ref/tags/v1 go /usr/bin/git git(http block)https://api.github.com/repos/nonexistent/repo/actions/runs/12345/usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/owner/repo/actions/workflows/usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go GOINSECURE GOMOD GOMODCACHE erignore env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)/usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go GOINSECURE GOMOD GOMODCACHE ache/go/1.25.0/xGO111MODULE env 0814000/b386/_pkGOINSECURE GO111MODULE 64/bin/go GOINSECURE b/gh-aw/pkg/cons--norc GOMODCACHE go(http block)https://api.github.com/repos/owner/repo/contents/file.md/tmp/go-build2146872843/b380/cli.test /tmp/go-build2146872843/b380/cli.test -test.testlogfile=/tmp/go-build2146872843/b380/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true GOINSECURE GOMOD GOMODCACHE go env ck 'scripts/**/*GOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)https://api.github.com/repos/test-owner/test-repo/actions/secrets/usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE go env e=false GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(http block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.