feat: wildcard support for allowed-repos and standardize target-repo helpers#17280
Conversation
…usage Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This pull request adds wildcard pattern support to the allowed-repos configuration for safe-output handlers and standardizes repository resolution logic across all handlers that support target-repo.
Changes:
- Added
isRepoAllowed()function with wildcard pattern support (using glob syntax) torepo_helpers.cjs - Refactored
create_issue.cjsandcreate_discussion.cjsto useresolveAndValidateRepo()instead of manually duplicating repository resolution logic - Added comprehensive test coverage for wildcard patterns including
*,org/*,*/repo, andorg/repo-*patterns
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| actions/setup/js/repo_helpers.cjs | Added isRepoAllowed() function with glob pattern matching; updated validateRepo() to use it; added new function to exports |
| actions/setup/js/repo_helpers.test.cjs | Added comprehensive test suite for isRepoAllowed() and wildcard pattern matching in validateRepo() |
| actions/setup/js/create_issue.cjs | Refactored to use resolveTargetRepoConfig() and resolveAndValidateRepo() helpers, removing duplicated repo resolution logic |
| actions/setup/js/create_discussion.cjs | Refactored to use resolveTargetRepoConfig() and resolveAndValidateRepo() helpers, removing duplicated repo resolution logic |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (pattern === "*") { | ||
| return true; | ||
| } | ||
| if (pattern.includes("*") && globPatternToRegex(pattern, { pathMode: true, caseSensitive: true }).test(qualifiedRepo)) { |
There was a problem hiding this comment.
The regex pattern is being compiled on every iteration of the loop. While the performance impact is likely minimal given the small size of typical allowedRepos sets and the fast-path exact match on line 64, this could be optimized by caching compiled patterns. Consider precompiling patterns when parseAllowedRepos is called, storing both the original pattern string and its compiled regex in a Map or similar structure.
| * Supports exact matches and wildcard patterns using glob syntax: | ||
| * - "*" matches any repository | ||
| * - "github/*" matches any repository in the "github" org | ||
| * - "STAR/gh-aw" (where STAR is *) matches "gh-aw" in any org |
There was a problem hiding this comment.
The documentation comment uses "STAR" as a placeholder instead of the actual asterisk character. This is unnecessarily confusing. The comment should directly show the pattern as "*/gh-aw" to match how the other patterns are documented on lines 55-56.
| * - "STAR/gh-aw" (where STAR is *) matches "gh-aw" in any org | |
| * - "*/gh-aw" matches "gh-aw" in any org |
Two inconsistencies in safe-tool handlers that support
target-repo:create_issueandcreate_discussionduplicated low-level repo resolution logic instead of using the shared helpers, and no handler supported wildcard patterns inallowed-repos.Wildcard support in
repo_helpers.cjsNew
isRepoAllowed()function backed byglob_pattern_helpers.cjs, replacing the plainSet.has()check invalidateRepo:"*""github/*"githuborg"*/gh-aw"gh-awin any org"github/gh-*"Standardized helper usage
create_issue.cjsandcreate_discussion.cjswere manually duplicating the repo resolution/validation/parsing sequence already encapsulated inresolveAndValidateRepo. Both now useresolveTargetRepoConfig+resolveAndValidateRepo, consistent with all other target-repo–aware handlers (add_labels,remove_labels,assign_to_user,unassign_from_user,add_comment,close_issue,create_pull_request,create_pr_review_comment,reply_to_pr_review_comment).assign_to_agentreads from env vars rather than a config object, so it continues using the lower-levelvalidateRepodirectly — it also benefits from wildcard support automatically.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/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 om/github/gh-aw 0/x64/lib/node_m--verify git conf�� --get remote.origin.url /usr/bin/git re /home/REDACTED/worrev-parse modules/@npmcli/--show-toplevel 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 e6CV/wrk5BTFT3u3x9SULe6CV x_amd64/vet /home/REDACTED/work/node_modules/.bin/sh set-url origin 64/pkg/tool/linu--show-toplevel 100883/b367/importcfg -c k/gh-aw/gh-aw/internal/tools/actions-build/main.go 64/pkg/tool/linux_amd64/vet 100883/b421/testutil.test tierignore .cfg 64/pkg/tool/linu--show-toplevel 100883/b421/testutil.test(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 3651/001/stability-test.md(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 /ref/tags/v8 x_amd64/vet /opt/hostedtoolcache/node/24.13./tmp/gh-aw-git-clone-657037574 /../../.prettiergit --local x_amd64/vet npm run format:cjs x_amd64/vet /usr/local/bin/sh --local user.name x_amd64/link sh(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq .object.sha npm run typecheck && vitest run -errorsas x_amd64/vet /home/REDACTED/work/node_modules/.-nilfunc get --local x_amd64/vet sh -c runs/20260220-205243-12670/test-2916745602/.github/workflows x_amd64/vet /home/node_modules/.bin/node --local pull.rebase 64/pkg/tool/linu--show-toplevel node(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq .object.sha -unreachable=false /tmp/go-build115100883/b109/vet.cfg /usr/bin/git 346(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 -bool -buildtags es/.bin/node -errorsas -ifaceassert -nilfunc sh ache�� .js' --ignore-path .prettierignore -tests ache/node/24.13.0/x64/bin/sh(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha ons-test2385788428 ../../../**/*.json /usr/bin/git --ignore-path ../../../.prettirev-parse 64/pkg/tool/linu--show-toplevel /usr/bin/git remo�� -v(http block)/usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha /tmp/gh-aw-test-runs/20260220-205243-12670/test-3466306819 status /usr/bin/git .github/workflowgit 5167271/b264/vetrev-parse es/.bin/sh git rev-�� --show-toplevel /opt/hostedtoolcache/go/1.25.0/xscripts/**/*.js /opt/hostedtoolcache/node/24.13.0/x64/bin/node on' --ignore-patgit -trimpath ules/.bin/node /opt/hostedtoolcache/node/24.13.0/x64/bin/node(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 =verbose create_discussion_fallback.test.cjs create_discussion_labels.test.cjs(http block)/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha elism --reporter=verbose create_issue.test.cjs create_discussion.test.cjs .cfg de(http block)/usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha -c=4 -nolocalimports -importcfg /tmp/go-build115100883/b394/importcfg -pack /home/REDACTED/work/gh-aw/gh-aw/pkg/fileutil/fileutil.go /home/REDACTED/work/gh-aw/gh-aw/pkg/fileutil/fileutil_test.go /pre�� elism --reporter!../../../pkg/workflow/js/**/*.json 5167271/b065/vet--ignore-path .cfg(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 npm run typecheck && vitest run --no-file-parallelism --reporter-p x_amd64/vet /home/REDACTED/work/gh-aw/gh-aw/actions/setup/js/node_modules/.bin-lang=go1.25 /../../.prettiergit --local run-script/lib/n--show-toplevel sh -c 5243-12670/test-3466306819 x_amd64/vet cfg l user.name de node(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 npm run typecheck && vitest run --no-file-parallelism --reporter-p QpCwol0/TWQKRhp4nTO5iBDk1HS9 /opt/hostedtoolcache/go/1.25.0/x64/bin/node /../../.prettiergit --local x_amd64/vet node /opt�� runs/20260220-205243-12670/test-3861691635/.github/workflows format:cjs /usr/bin/sh l user.name modules/@npmcli/--show-toplevel sh(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 -buildtags ules/.bin/node -errorsas -ifaceassert -nilfunc /opt/hostedtoolctest@example.com tion�� k && vitest run --no-file-parallelism --reporter=verbose create_issue.test.cjs create_discussiongit /tmp/go-build2025167271/b285/vet.cfg tions/setup/node_modules/.bin/node cjs s ****** sh(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 -buildtags x_amd64/vet -errorsas -ifaceassert -nilfunc x_amd64/vet tion�� -bool -buildtags de_modules/.bin/node ate_discussion_lgit -ifaceassert -nilfunc sh(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 -buildtags x_amd64/compile -errorsas -ifaceassert -nilfunc x_amd64/compile tion�� -bool se ules/.bin/node ate_discussion_lgit -ifaceassert -nilfunc sh(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 -buildtags bin/node -errorsas -ifaceassert -nilfunc /opt/hostedtoolcache/go/1.25.0/x-goversion tion�� hub/workflows/test.md hub/workflows/test.lock.yml attributes cjs s -nilfunc sh(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 -buildtags ode -errorsas -ifaceassert -nilfunc /opt/hostedtoolc-tests tion�� k && vitest run --no-file-parallgo1.25.0 /tmp/go-build2025167271/b306/vet-c=4 de_modules/.bin/node cjs s ode-gyp-bin/sh sh(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 -buildtags e_modules/.bin/sh -errorsas -ifaceassert -nilfunc /opt/hostedtoolcache/go/1.25.0/x-extld=gcc tion�� k && vitest run --no-file-parallelism --reporter=verbose create_issue.test.cjs create_discussion/opt/hostedtoolcache/node/24.13.0/x64/bin/node -buildtags ules/.bin/node cjs s -nilfunc sh(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 tions/setup/js/create_discussion-ifaceassert tions/setup/js/create_discussion-nilfunc -errorsas -ifaceassert -nilfunc /opt/hostedtoolcache/go/1.25.0/xtest@example.com tion�� k && vitest run --no-file-parallelism --reporter=verbose create_issue.test.cjs create_discussion/opt/hostedtoolcache/node/24.13.0/x64/bin/node /tmp/go-build2025167271/b216/vet.cfg x_amd64/compile cjs s ******"; }; f x_amd64/compile(http block)https://api.github.com/repos/github/gh-aw/actions/workflows/usr/bin/gh gh workflow list --json name,state,path --noprofile .cfg 64/pkg/tool/linux_amd64/vet(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(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(http block)https://api.github.com/repos/github/gh-aw/contents/.github%2Fworkflows%2Faudit-workflows.md/opt/hostedtoolcache/node/24.13.0/x64/bin/node /opt/hostedtoolcache/node/24.13.0/x64/bin/node --conditions node --conditions development --experimental-import-meta-resolve --require /home/REDACTED/work/gh-aw/gh-aw/actions/setup/js/node_modules/vitest/suppress-warnings.cjs /home/REDACTED/work/gh-aw/gh-aw/actions/setup/js/node_modules/vitest/dist/workers/forks.js GOMOD GOMODCACHE go env elism GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go(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 -unreachable=false /tmp/go-build2025167271/b222/vet.cfg de_modules/.bin/node(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 -unreachable=falgo1.25.0 /tmp/go-build202-c=4 bin/node(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 -errorsas -ifaceassert -nilfunc /opt/hostedtoolcache/go/1.25.0/x-goversion ache�� -bool -buildtags k/gh-aw/gh-aw/actions/setup/node-importcfg -errorsas -ifaceassert -nilfunc sh(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/pkg/tool/linux_amd64/vet k/gh-aw/gh-aw/acsh k/gh-aw/gh-aw/ac-c k/gh-aw/gh-aw/ac"prettier" --write 'scripts/**/*.js' --ignore-path .prettierignore 64/pkg/tool/linux_amd64/vet k/gh�� ath ../../../.prettierignore k/gh-aw/gh-aw/actions/setup/js/assign_copilot_to_created_issues.cjs ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet(http block)/usr/bin/gh gh workflow list --json name,state,path --repo owner/repo /node(http block)https://api.github.com/repos/owner/repo/contents/file.md/tmp/go-build115100883/b380/cli.test /tmp/go-build115100883/b380/cli.test -test.testlogfile=/tmp/go-build115100883/b380/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true(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 --noprofile .cfg 64/pkg/tool/linux_amd64/vet(http block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.