Skip to content

Compile reviewers field into create-pull-request handler config#16122

Merged
pelikhan merged 2 commits intomainfrom
copilot/fix-reviewers-config-handler
Feb 16, 2026
Merged

Compile reviewers field into create-pull-request handler config#16122
pelikhan merged 2 commits intomainfrom
copilot/fix-reviewers-config-handler

Conversation

Copy link
Contributor

Copilot AI commented Feb 16, 2026

The reviewers field under safe-outputs.create-pull-request was parsed from frontmatter and included in MCP tool descriptions, but never passed to GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG.

Changes

  • Handler config builder: Added reviewers to the builder chain in compiler_safe_outputs_config.go using AddStringSlice() (same pattern as labels)
  • Tests: Added TestHandlerConfigReviewers and table-driven test case to verify reviewers compile into handler config JSON

Example

Frontmatter:

safe-outputs:
  create-pull-request:
    reviewers: [alice, bob]
    labels: [automated]

Before:

{
  "create_pull_request": {
    "labels": ["automated"],
    "max": 1
  }
}

After:

{
  "create_pull_request": {
    "reviewers": ["alice", "bob"],
    "labels": ["automated"],
    "max": 1
  }
}

The handler config now matches what the tool description advertises. Reviewers are assigned via post-steps using gh CLI; this change makes the configuration available for potential future handler enhancements.

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 gh repo view --json owner,name --jq .owner.login + "/" + .name x_amd64/link g mpt_step_helper.rev-parse rep x_amd64/link -l PostSteps.*string pkg/workflow/gh_cli_mount_test.g-c=4 ode g ing.go cal/bin/grep bR/LHCTN74xI8q78test@example.com (http block)
    • Triggering command: /usr/bin/gh gh repo view --json owner,name --jq .owner.login + "/" + .name tions/setup/js/node_modules/.bin-lang=go1.25 g _generation.go rep grep -l 903831579/.github/workflows pkg/workflow/package_extraction_-nolocalimports nfig/composer/vendor/bin/git g (http block)
    • Triggering command: /usr/bin/gh gh repo view --json owner,name --jq .owner.login + "/" + .name bin/sh g _default_test.gorev-parse (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 --write scripts/**/*.js ache/node/24.13.0/x64/bin/node .prettierignore p_types_test.go grep tail t-33�� sistency_GoAndJavaScript1035568869/001/test-comptest-logs/run-2 grep /tmp/go-build4018436941/b392/logger.test g afety_test.go ep /tmp/go-build4018436941/b392/logger.test (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 3331577525 grep .cfg g or_tools_test.gorev-parse /home/REDACTED/.lo--show-toplevel git comm�� rite '../../../**/*.json' '!../../../pkg/workflo-s Add reviewers field to create-pull-request handl-w ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet g est.go ep ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq .object.sha 8436941/b397/_pkg_.a grep ache/go/1.25.0/x64/pkg/tool/linux_amd64/compile g b/gh-aw/pkg/mathrev-parse ache/node/24.13.--show-toplevel ache/go/1.25.0/x64/pkg/tool/linux_amd64/compile -c 8436941/b401/_pkg_.a grep 8436941/b401=> ettierignore b/gh-aw/pkg/parsrev-parse tnet/tools/grep 8436941/b397/importcfg (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq .object.sha --noprofile grep /opt/hostedtoolcache/go/1.25.0/x64/bin/sh g _token_test.go grep sh -c "prettier" --write 'scripts/**/*.js' --ignore-path .prettierigno-test.timeout=10m0s grep /node_modules/.bin/node g kdown_code_regiorev-parse /usr/local/sbin/--show-toplevel node (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v4 --jq .object.sha user.email test@example.com 8436941/b426/scripts.test g t.go /usr/local/sbin/--show-toplevel 8436941/b426/scripts.test e=/t�� t0 grep (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 celain --ignore-submodules | head -n 10 pkg/workflow/claude_engine_test.go x_amd64/vet g tegration_test.grun grep x_amd64/vet -l PostSteps.*strintest-logs/run-4 pkg/workflow/compile_outputs_label_test.go hutil.test g n_test.go ode-gyp-bin/sh hutil.test (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha : ${{ github.repository }} grep /usr/bin/git g s.go /snap/bin/grep git rev-�� --show-toplevel grep ache/node/24.13.0/x64/bin/node g ch_test.go rgo/bin/grep git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha user.email test@example.com /usr/bin/git -c=4 -nolocalimports -importcfg git conf�� tup/sh/sanitize_path.sh' ':::/usr/bin:/usr/local/bin' && echo "$PATH" remote.origin.url /usr/bin/git th .prettierignogit _helpers_test.gorev-parse /opt/pipx_bin/gr--show-toplevel /usr/bin/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 l % st.go /usr/local/.ghcu--ignore-path g (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha go1.25.0 -c=4 -nolocalimports -importcfg /tmp/go-build4018436941/b383/importcfg -pack /tmp/go-build4018436941/b383/_testmain.go er d -n 10 go /sh g bels_test.go 64/bin/grep grep (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha ath ../../../.pr--ignore-path ckout_runtime_or.prettierignore k/_temp/ghcca-node/node/bin/grep g go grep acBMv-3pd88c -l g go grep g mand.go /usr/local/sbin/-test.paniconexit0 grep (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 /home/REDACTED/node_modules/.bin/sh g _token_test.go 64/bin/grep sh -c "prettier" --write 'scripts/**/*.js' --ignore-path .prettierignore l /home/REDACTED/work/gh-aw/gh-aw/node_modules/.bin/node ettierignore kdown_code_regiorev-parse /opt/pipx_bin/gr--show-toplevel 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 stmain.go 0/x64/bin/node g _token_test.go /usr/local/sbin/--show-toplevel sh t-ha�� ithub/workflows/ai-moderator.md grep /home/REDACTED/work/gh-aw/gh-aw/actions/setup/node_modules/.bin/no-nilfunc ettierignore der_test.go rep node (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/1/artifacts
    • Triggering command: /usr/bin/gh gh run download 1 --dir test-logs/run-1 pile_outputs_label_test.go ash g _warning_test.go/tmp/js-hash-test-2529214586/test-hash.js rep grep -l '**/*.ts' '**/*.json' --ignore-path ../../../.pr**/*.json pkg/workflow/skip_bots_test.go 0/x64/bin/node g _test.go cal/bin/grep grep (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12345/artifacts
    • Triggering command: `/usr/bin/gh gh run download 12345 --dir test-logs/run-12345 pile_outputs_label_test.go x_amd64/link g ringSlice()
  • Adrev-parse` (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12346/artifacts
    • Triggering command: `/usr/bin/gh gh run download 12346 --dir test-logs/run-12346 pile_outputs_label_test.go 0/x64/bin/node g ringSlice()
  • Adrev-parse ache/go/1.25.0/x--show-toplevel grep 0/x6�� PostSteps.*string pkg/workflow/skip_bots_test.go 8d519d9/node_modules/.bin/prettier g o 0/x64/bin/grep grep` (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/2/artifacts
    • Triggering command: /usr/bin/gh gh run download 2 --dir test-logs/run-2 pile_outputs_label_test.go tnet/tools/bash g _warning_test.gorev-parse de/node/bin/grep--show-toplevel grep estl�� '**/*.ts' '**/*.json' --ignore-path ../../../.pr**/*.json pkg/workflow/skip_bots_test.go nfig/composer/vendor/bin/sh g _test.go k/_temp/ghcca-no--show-toplevel grep (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/3/artifacts
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 pile_outputs_label_test.go x_amd64/compile g _warning_test.gorev-parse /home/REDACTED/.lo--show-toplevel x_amd64/compile -l '**/*.ts' '**/*.json' --ignore-p-c=4 pkg/workflow/skip_bots_test.go sh g _test.go ep grep (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/4/artifacts
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 pile_outputs_label_test.go 0/x64/lib/node_modules/npm/node_-buildmode=exe g _warning_test.gorev-parse grep grep estl�� '**/*.ts' '**/*.json' --ignore-path ../../../.pr**/*.json pkg/workflow/skip_bots_test.go 64/bin/node g _test.go /usr/local/sbin/--show-toplevel grep (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/5/artifacts
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 pile_outputs_label_test.go x_amd64/compile g _warning_test.gorev-parse /opt/pipx_bin/gr--show-toplevel x_amd64/compile -l '**/*.ts' '**/*.json' --ignore-pgo1.25.0 pkg/workflow/skip_bots_test.go h g .go rgo/bin/grep grep (http block)
  • https://api.github.com/repos/github/gh-aw/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path g _test.go rgo/bin/grep higher."; \ echnode edule_preprocess/home/REDACTED/.npm/_npx/b388654678d519d9/node_modules/.bin/prettier ndor/bin/grep grep -l h ../../../.pret.prettierignore st.go /node g o 64/bin/grep grep (http block)
    • Triggering command: /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 missions_factory-atomic /home/REDACTED/.lo-bool grep -l js/**/*.json' ---errorsas webhooks.go /home/REDACTED/.lo-nilfunc g z_test.go ep grep (http block)
    • Triggering command: /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 _test.go cal/bin/grep x_amd64/compile -l PostSteps.*string pkg/workflow/pip_test.go k/_temp/ghcca-node/node/bin/git g ing.go /home/REDACTED/.local/bin/grep grep (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 903831579/.github/workflows pkg/workflow/package_extraction_-nolocalimports nfig/composer/vendor/bin/git g (http block)
  • https://api.github.com/repos/nonexistent/repo/actions/runs/12345
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion g _generation.go de/node/bin/grep--show-toplevel grep 0/x6�� PostSteps.*string pkg/workflow/package_extraction_test.go t g (http block)
  • https://api.github.com/repos/owner/repo/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo ache/go/1.25.0/x64/bin/grep g go 0/x64/bin/grep grep -l h ../../../.pret.prettierignore st.go modules/@npmcli/run-script/lib/node-gyp-bin/node g go (http block)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 0/x64/bin/grep g go (http block)
    • Triggering command: /usr/bin/gh gh workflow list --repo owner/repo --json name,path,state tions/node_modules/.bin/node g ing.go ache/go/1.25.0/x--git-dir grep tion�� plorer.md pkg/workflow/shell.go /home/REDACTED/.config/composer/vendor/bin/grep g go 0/x64/bin/grep grep (http block)
  • https://api.github.com/repos/test-owner/test-repo/actions/secrets
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name g _test.go /sh g dation_integrati-c de/node/bin/grep"prettier" --write 'scripts/**/*.js' --ignore-path .prettierignore grep -l h ../../../.prettierignore test.go de/node/bin/grep g o k/_temp/ghcca-no--noprofile grep (http block)
  • https://api.github.com/user
    • Triggering command: /usr/bin/gh gh api user --jq .login reviewers: adog.md 0/x64/bin/grep create_pull_requ/opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet .md /usr/sbin/bash grep -l reviewers: threat-scan.md ache/node/24.13.-nilfunc --noprofile md rgo/bin/grep grep (http block)
    • Triggering command: /usr/bin/gh gh api user --jq .login reviewers: gies.md k/_temp/ghcca-node/node/bin/grep create_pull_requ/opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet ssue-to-user.md 64/bin/grep grep -l reviewers: (http block)
    • Triggering command: /usr/bin/gh gh api user --jq .login reviewers: data-fetch.md rep create_pull_requ/opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet puts-conformance-atomic (http block)

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

Original prompt

This section details on the original issue you should resolve

<issue_title>create-pull-request: reviewers config not compiled into handler config</issue_title>
<issue_description>## Bug Description

The reviewers field under safe-outputs.create-pull-request is read by the compiler and included in the MCP tool description, but it is not passed to GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG where the handler would actually assign reviewers to the created PR.

As a result, PRs created by the workflow have no reviewers assigned despite the frontmatter configuration.

Steps to Reproduce

  1. Create a workflow with the following frontmatter:
safe-outputs:
  create-pull-request:
    reviewers: [user1, user2]
  1. Run gh aw compile
  2. Inspect the compiled .lock.yml

Expected Behavior

GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG should include "reviewers":["user1","user2"] in the create_pull_request object, and the handler should assign those reviewers to the PR after creation.

Actual Behavior

The compiled lock file shows:

  • Tool description (correct): includes "Reviewers [user1 user2] will be assigned."
  • config.json (missing): {"create_pull_request":{},...} — empty object, no reviewers
  • Handler config (missing): {"create_pull_request":{"base_branch":"...","max":1,"max_patch_size":1024},...} — no reviewers field

The reviewers are recognized by the compiler (tool description mentions them) but never passed to the handler that actually creates the PR.

Workaround

Use a separate add-reviewer safe output and instruct the agent to call it after creating the PR:

safe-outputs:
  create-pull-request:
    draft: false
  add-reviewer:
    reviewers: [user1, user2]
    target: "*"

Environment

  • gh-aw version: v0.45.0
  • OS: macOS (compilation), ubuntu-slim (runtime)

Additional Notes

The draft field under create-pull-request does compile correctly into the handler config. Only reviewers appears to be missing from the handler config compilation.</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 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.

- Add reviewers to handler config builder using AddStringSlice()
- Add test case to verify reviewers in handler config JSON
- Update existing test to include reviewers scenario
- All tests passing

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan pelikhan marked this pull request as ready for review February 16, 2026 15:22
Copilot AI review requested due to automatic review settings February 16, 2026 15:22
Copilot AI changed the title [WIP] Fix reviewers config not compiled into handler config Compile reviewers field into create-pull-request handler config Feb 16, 2026
Copilot AI requested a review from pelikhan February 16, 2026 15:24
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

This PR fixes a gap in the safe-outputs compiler where safe-outputs.create-pull-request.reviewers was parsed/used for tool description but not included in GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG, preventing handlers (and future enhancements) from accessing reviewers via the unified handler-config path.

Changes:

  • Add reviewers to the create_pull_request handler config builder (via AddStringSlice).
  • Add a new table-driven unit test scenario for create-pull-request with reviewers.
  • Add a dedicated unit test validating reviewers appears in the handler config JSON.

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.go Includes reviewers in the generated handler manager config for create_pull_request.
pkg/workflow/compiler_safe_outputs_config_test.go Adds unit coverage for reviewers being present in GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG.
Comments suppressed due to low confidence (1)

pkg/workflow/compiler_safe_outputs_config_test.go:410

  • TestHandlerConfigReviewers can pass without asserting anything if the GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG line isn’t found or if the Split() doesn’t yield 2 parts (the test just falls through). Add a require/assert that the env var line was found and parsed (e.g., track a found flag and fail if it remains false) so this test can’t silently succeed on formatting changes or regressions.
	// Extract and validate JSON
	for _, step := range steps {
		if strings.Contains(step, "GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG") {
			parts := strings.Split(step, "GH_AW_SAFE_OUTPUTS_HANDLER_CONFIG: ")
			if len(parts) == 2 {
				jsonStr := strings.TrimSpace(parts[1])
				jsonStr = strings.Trim(jsonStr, "\"")
				jsonStr = strings.ReplaceAll(jsonStr, "\\\"", "\"")

				var config map[string]map[string]any
				err := json.Unmarshal([]byte(jsonStr), &config)
				require.NoError(t, err, "Handler config JSON should be valid")

				prConfig, ok := config["create_pull_request"]
				require.True(t, ok, "Should have create_pull_request handler")

				reviewers, ok := prConfig["reviewers"]
				require.True(t, ok, "Should have reviewers field")

				reviewerSlice, ok := reviewers.([]any)
				require.True(t, ok, "Reviewers should be an array")
				assert.Len(t, reviewerSlice, 3, "Should have 3 reviewers")
				assert.Equal(t, "user1", reviewerSlice[0])
				assert.Equal(t, "user2", reviewerSlice[1])
				assert.Equal(t, "copilot", reviewerSlice[2])
			}
		}

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

@pelikhan pelikhan merged commit cd9f347 into main Feb 16, 2026
126 checks passed
@pelikhan pelikhan deleted the copilot/fix-reviewers-config-handler branch February 16, 2026 15:27
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.

create-pull-request: reviewers config not compiled into handler config

2 participants