Skip to content

refactor: extract shared MCP renderer helpers across engine implementations#21336

Merged
pelikhan merged 2 commits intomainfrom
copilot/fix-duplicate-code-engine-mcp
Mar 17, 2026
Merged

refactor: extract shared MCP renderer helpers across engine implementations#21336
pelikhan merged 2 commits intomainfrom
copilot/fix-duplicate-code-engine-mcp

Conversation

Copy link
Contributor

Copilot AI commented Mar 17, 2026

Four engines (claude, gemini, copilot, codex) each duplicated the same createRenderer closure and MCPToolRenderers struct literal in their RenderMCPConfig bodies — 4 occurrences of ~30 lines of structurally identical code differing only in a handful of option flags.

Changes

New: pkg/workflow/mcp_renderer_helpers.go

  • buildMCPRendererFactory(workflowData, format, includeCopilotFields, inlineArgs) — replaces the repeated createRenderer closure; returns a func(bool) *MCPConfigRendererUnified with engine-specific MCPRendererOptions baked in
  • buildStandardJSONMCPRenderers(workflowData, createRenderer, webFetchIncludeTools, renderCustom) — replaces the repeated 8-callback MCPToolRenderers literal; only engine-specific inputs are webFetchIncludeTools (true for Copilot) and the custom tool handler
// Before (repeated verbatim in each engine):
createRenderer := func(isLast bool) *MCPConfigRendererUnified {
    return NewMCPConfigRenderer(MCPRendererOptions{
        IncludeCopilotFields:   false,
        InlineArgs:             false,
        Format:                 "json",
        IsLast:                 isLast,
        ActionMode:             GetActionModeFromWorkflowData(workflowData),
        WriteSinkGuardPolicies: deriveWriteSinkGuardPolicyFromWorkflow(workflowData),
    })
}
// ... followed by 30 lines of MCPToolRenderers callbacks

// After:
createRenderer := buildMCPRendererFactory(workflowData, "json", false, false)
return RenderJSONMCPConfig(yaml, tools, mcpTools, workflowData, JSONMCPConfigOptions{
    ConfigPath:    "/tmp/gh-aw/mcp-config/mcp-servers.json",
    GatewayConfig: buildMCPGatewayConfig(workflowData),
    Renderers:     buildStandardJSONMCPRenderers(workflowData, createRenderer, false, customHandler),
})

Engine refactoring

  • claude_mcp.go, gemini_mcp.go, copilot_mcp.go, codex_mcp.go — each RenderMCPConfig body reduced to ~5–10 lines of engine-specific logic
  • Codex's JSON gateway section also fixes an inconsistency where ActionMode was computed inline with a manual nil-check instead of GetActionModeFromWorkflowData()

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 ommon.go x_amd64/compile git rev-�� --show-toplevel x_amd64/compile /usr/bin/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 GO111MODULE 64/bin/go git rev-�� --show-toplevel go /usr/bin/git 789752063 GO111MODULE 64/bin/go 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 GO111MODULE 0/x64/bin/node git rev-�� --show-toplevel go /usr/bin/git SameOutput233865git GO111MODULE cfg git (http block)
  • https://api.github.com/orgs/test-owner/actions/secrets
    • Triggering command: /usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE ache/go/1.25.0/xGO111MODULE env 5344117/b392/_pkGOINSECURE GO111MODULE 64/bin/go GOINSECURE b/gh-aw/pkg/envuenv GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name --write **/*.cjs 64/bin/go **/*.json --ignore-path ../../../.prettinpx prettier --check '**/*.cjs' '**/*.ts' '**/*.json' --ignore-path ../../../.pr**/*.json sh -c "prettier" --wriGOSUMDB git /sh rror ache/go/1.25.0/x-c /usr/bin/git go (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 -unreachable=false /tmp/go-build4053424329/b217/vet.cfg /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha /tmp/TestHashStability_SameInputSameOutput3651112024/001/stability-test.md sh /usr/bin/git npx prettier --cgit GOPROXY 64/bin/go git rev-�� --show-toplevel sh /usr/bin/git "prettier" --chegit node 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha test/race-image:v1.0.0 go /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -json GO111MODULE 64/bin/go /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -uns�� /tmp/go-build3126110159/b102/vet.cfg go /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -json GO111MODULE 64/bin/go /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet (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 se 3424329/b005/vet.cfg e-mcp (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha -aw/git/ref/tags/v2.0.0 0568007/b001/_testmain.go /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -ato�� -bool -buildtags /usr/bin/git -errorsas -ifaceassert -nilfunc git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha .cfg ^remote\..*\.gh-resolved$ 64/pkg/tool/linux_amd64/vet "prettier" --wrigit git 64/bin/go 64/pkg/tool/linux_amd64/vet .cfg�� /tmp/shared-actions-test4184061698 rev-parse ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet h ../../../.pretgit GO111MODULE 64/bin/go ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet (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 (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha -v origin /opt/pipx_bin/bash (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel x_amd64/vet /usr/bin/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 celain --ignore-submodules | head -n 10 -buildtags ache/node/24.14.0/x64/bin/bash -errorsas -ifaceassert -nilfunc /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -uns�� -unreachable=false /tmp/go-build4053424329/b202/vet.cfg /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha -unreachable=false /tmp/go-build4053424329/b050/vet.cfg bash (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha --show-toplevel x_amd64/vet /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 celain --ignore-submodules | head -n 10 /tmp/go-build4053424329/b161/vet.cfg p/bin/bash (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha -unreachable=false /tmp/go-build4053424329/b038/vet.cfg nfig/composer/vendor/bin/bash (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha -unreachable=false /tmp/go-build4053424329/b049/vet.cfg icate-code-engine-mcp (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 -unreachable=false /tmp/go-build4053424329/b046/vet.cfg sh (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha k/gh-aw/gh-aw/.github/workflows/ai-moderator.md go ache/node/24.14.0/x64/bin/node -json GO111MODULE 64/bin/go ache/node/24.14.0/x64/bin/node 6486�� /tmp/file-tracker-test2715609851/existing.md go /usr/bin/git -json GO111MODULE 64/bin/go git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha 6110159/b189/vet.cfg test@example.com ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -json GO111MODULE 64/bin/go ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet 6110�� --get-regexp ^remote\..*\.gh-resolved$ /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet on' --ignore-patgit GO111MODULE 64/bin/go /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet (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 -bool -buildtags /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -errorsas -ifaceassert -nilfunc /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -uns�� -unreachable=false /tmp/go-build4053424329/b206/vet.cfg /opt/hostedtoolcache/go/1.25.0/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha --show-toplevel (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha 6110159/b195/vet.cfg origin ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet -json GO111MODULE 64/bin/go ache/go/1.25.0/x64/pkg/tool/linux_amd64/vet (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 g/testutil/tempdir.go --local .cfg http.https://gitgit (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha -json GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha -bool -buildtags 64/pkg/tool/linux_amd64/vet -errorsas -ifaceassert -nilfunc 64/pkg/tool/linux_amd64/vet .cfg�� --show-toplevel -tests 64/pkg/tool/linux_amd64/vet npx prettier --wgit git 64/bin/go 64/pkg/tool/linux_amd64/vet (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 --get-regexp --local de/node/bin/git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env runs/20260317-041741-33230/test-376235568/.github/workflows GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go l GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha .cfg sh 64/pkg/tool/linux_amd64/vet "prettier" --wrigit git 64/bin/go 64/pkg/tool/linux_amd64/vet .cfg�� --get remote.origin.url 64/pkg/tool/linux_amd64/vet (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 --get-regexp --local 64/bin/git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha 0568007/b402/_pkg_.a GO111MODULE .cfg GOINSECURE GOMOD GOMODCACHE go env NtQl/xhVqh7QChbBs18WVNtQl GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha .cfg (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 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 1 --dir test-logs/run-1 GO111MODULE x_amd64/asm GOINSECURE GOMOD GOMODCACHE x_amd64/asm env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (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 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/12346/artifacts
    • Triggering command: /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)
    • Triggering command: /usr/bin/gh gh run download 12346 --dir test-logs/run-12346 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -dirty" -o gh-aw ./cmd/gh-aw GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (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 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
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 GO111MODULE x_amd64/link GOINSECURE GOMOD GOMODCACHE x_amd64/link env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE 3W/cnjHJRsC75-1TI1_m0Vn/eAbLlA6anXiDePRSysAn (http block)
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 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/4/artifacts
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env ub/workflows GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 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/5/artifacts
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 GO111MODULE x_amd64/cgo GOINSECURE GOMOD GOMODCACHE x_amd64/cgo env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (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/mathutil/mathuGOINSECURE g/mathutil/mathuGOMOD 64/bin/go GOINSECURE GOMOD GOMODCACHE ache/go/1.25.0/xGO111MODULE env 5344117/b400/_pkGOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (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 GOMOD GOMODCACHE go env _XzG/dtubQUltdMFGOSUMDB GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE 5344117/b409/importcfg (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 GOMOD GOMODCACHE dx8vjli/h6bNdPCf-extld=gcc env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (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 (http block)
    • Triggering command: /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)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env 1904-46004/test-125009887/.github/workflows GO111MODULE k/gh-aw/gh-aw/actions/node_modules/.bin/sh GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE node (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq .object.sha --write ../../../**/*.jsGOWORK 64/bin/go --ignore-path ../../../.pretti-c /usr/bin/git go /pre�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v2.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE node (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE npx (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE /bin/sh -c cd actions/setup-errorsas GOPROXY 64/bin/go GOSUMDB GOWORK 64/bin/go sh (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v3.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE node (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq .object.sha --write ../../../**/*.jsGOWORK modules/@npmcli/run-script/lib/node-gyp-bin/node --ignore-path ../../../.prettidescribe /usr/bin/git go /pre�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (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 logs/command.sh (http block)
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env 4259643853/.github/workflows GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE ns-lock.json does not exist yet"/tmp/go-build1550568007/b413/_testmain.go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE k/gh-aw/node_modules/.bin/sh GOINSECURE GOMOD GOMODCACHE go (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 GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion GOINSECURE GOMOD GOMODCACHE x_amd64/vet env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (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 64/bin/go GOINSECURE GOMOD GOMODCACHE ache/go/1.25.0/xGO111MODULE env 5344117/b409/_pkGOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go GOINSECURE GOMOD erignore ache/go/1.25.0/xGO111MODULE env 5344117/b413/_pkGOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go **/*.json --ignore-path ../../../.prettinpx prettier --check '**/*.cjs' '**/*.ts' '**/*.json' --ignore-path ../../../.pr**/*.json sh -c "prettier" --wriGOSUMDB git 64/bin/go rror 0568007/b392/con-c /usr/bin/git go (http block)
  • https://api.github.com/repos/owner/repo/contents/file.md
    • Triggering command: /tmp/go-build1550568007/b383/cli.test /tmp/go-build1550568007/b383/cli.test -test.testlogfile=/tmp/go-build1550568007/b383/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true GOINSECURE GOMOD GOMODCACHE go m/_n�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /tmp/go-build584338333/b383/cli.test /tmp/go-build584338333/b383/cli.test -test.testlogfile=/tmp/go-build584338333/b383/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true --show-toplevel 64/pkg/tool/linuenv otOrdering373290-json sh -c npx prettier --wGOINSECURE git 64/bin/go --show-toplevel 64/pkg/tool/linu/home/REDACTED/work/gh-aw/gh-aw/actions/setup/js/node_modules/.bin/prettier run-script/lib/n--check go (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 GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE ache/go/1.25.0/xGO111MODULE env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name **/*.cjs **/*.ts CgoFiles,CXXFiles,MFiles,HFiles,FFiles,SFiles,SwigFiles,SwigCXXFiles,SysoFiles,TestGoFiles,XTestGoFiles,CompiledGoFiles,Export,DepOnly,Imports,ImportMap,TestImports,XTestImpor --ignore-path ../../../.pretti/opt/hostedtoolcache/node/24.14.0/x64/bin/npm /usr/bin/git node /opt�� prettier --write 64/bin/go !../../../pkg/wosh --ignore-path ../../../.pretti"prettier" --check 'scripts/**/*.js' --ignore-path .prettierignore go (http block)

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


📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.

… duplication

- Add buildMCPRendererFactory() and buildStandardJSONMCPRenderers() helpers
- Refactor Claude, Gemini, Copilot, Codex MCP config rendering to use helpers
- Fix Codex inconsistent ActionMode (now uses GetActionModeFromWorkflowData consistently)

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] [ISSUE-123] Fix duplicate code in engine MCP config rendering refactor: extract shared MCP renderer helpers across engine implementations Mar 17, 2026
Copilot AI requested a review from pelikhan March 17, 2026 04:22
@pelikhan pelikhan marked this pull request as ready for review March 17, 2026 04:30
Copilot AI review requested due to automatic review settings March 17, 2026 04:30
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

Refactors MCP config rendering across engines by extracting shared renderer factory and standard JSON renderer callback wiring into a common helper, reducing duplicated logic in each engine implementation.

Changes:

  • Added shared helpers to build an engine-configured MCP renderer factory and a standard JSON MCPToolRenderers bundle.
  • Updated Claude, Gemini, Copilot, and Codex (gateway JSON) engines to use the shared helpers, shrinking each RenderMCPConfig implementation.
  • Standardized Codex gateway JSON ActionMode derivation via GetActionModeFromWorkflowData().

Reviewed changes

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

Show a summary per file
File Description
pkg/workflow/mcp_renderer_helpers.go New shared helpers for renderer factory creation and standard JSON MCP tool renderer wiring.
pkg/workflow/claude_mcp.go Replaced duplicated renderer closure + MCPToolRenderers literal with shared helpers.
pkg/workflow/gemini_mcp.go Replaced duplicated renderer closure + MCPToolRenderers literal with shared helpers.
pkg/workflow/copilot_mcp.go Replaced duplicated renderer closure + MCPToolRenderers literal with shared helpers (Copilot flags baked into factory).
pkg/workflow/codex_mcp.go Updated gateway JSON config rendering to use shared helpers and standardized ActionMode derivation.
Comments suppressed due to low confidence (1)

pkg/workflow/mcp_renderer_helpers.go:54

  • This callback parameter name (workflowData) shadows the outer workflowData from buildStandardJSONMCPRenderers. Renaming it (e.g., wfData) would avoid shadowing and reduce the chance of accidentally mixing the two.
		RenderSafeOutputs: func(yaml *strings.Builder, isLast bool, workflowData *WorkflowData) {
			createRenderer(isLast).RenderSafeOutputsMCP(yaml, workflowData)
		},

💡 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 +58 to +60
RenderWebFetch: func(yaml *strings.Builder, isLast bool) {
renderMCPFetchServerConfig(yaml, "json", " ", isLast, webFetchIncludeTools, deriveWriteSinkGuardPolicyFromWorkflow(workflowData))
},
Comment on lines +39 to +41
RenderGitHub: func(yaml *strings.Builder, githubTool any, isLast bool, workflowData *WorkflowData) {
createRenderer(isLast).RenderGitHubMCP(yaml, githubTool, workflowData)
},
@pelikhan pelikhan merged commit 8c0a5d0 into main Mar 17, 2026
115 checks passed
@pelikhan pelikhan deleted the copilot/fix-duplicate-code-engine-mcp branch March 17, 2026 04:38
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.

Duplicate Code: Engine MCP Config Rendering Pattern in pkg/workflow

3 participants