From 3fe7764e1efcbed79330f3cc4323084db0c7929c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 3 Mar 2026 00:12:50 +0000 Subject: [PATCH 1/3] Initial plan From 6da1ba0035ffd7769379918cea3808f8c3a3dc89 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 3 Mar 2026 00:23:05 +0000 Subject: [PATCH 2/3] fix: remove undefined optional SENTRY_HOST from sentry MCP config Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/mcp-inspector.lock.yml | 5 ++--- .github/workflows/shared/mcp/sentry.md | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/mcp-inspector.lock.yml b/.github/workflows/mcp-inspector.lock.yml index acf6b17109c..7c9d79c4509 100644 --- a/.github/workflows/mcp-inspector.lock.yml +++ b/.github/workflows/mcp-inspector.lock.yml @@ -42,7 +42,7 @@ # - shared/mcp/tavily.md # - shared/reporting.md # -# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"a47d738441d992624473007ef6642d81da6062c254d4f043ac1438370a169ef4"} +# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"50fbf29123a8c727c21f28170fd58aa1d6f5b74177bd42a5f6300b4229de44a6"} name: "MCP Inspector Agent" "on": @@ -965,8 +965,7 @@ jobs: ], "env": { "OPENAI_API_KEY": "\${SENTRY_OPENAI_API_KEY}", - "SENTRY_ACCESS_TOKEN": "\${SENTRY_ACCESS_TOKEN}", - "SENTRY_HOST": "\${SENTRY_HOST}" + "SENTRY_ACCESS_TOKEN": "\${SENTRY_ACCESS_TOKEN}" } }, "serena": { diff --git a/.github/workflows/shared/mcp/sentry.md b/.github/workflows/shared/mcp/sentry.md index c06449c466c..b8b19694cc8 100644 --- a/.github/workflows/shared/mcp/sentry.md +++ b/.github/workflows/shared/mcp/sentry.md @@ -20,7 +20,6 @@ mcp-servers: - get_doc env: SENTRY_ACCESS_TOKEN: ${{ secrets.SENTRY_ACCESS_TOKEN }} - SENTRY_HOST: ${{ env.SENTRY_HOST }} # Optional OPENAI_API_KEY: ${{ secrets.SENTRY_OPENAI_API_KEY }} # Optional --- From 9310651d29198e7b52323abe148f746294e4cba6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 3 Mar 2026 00:40:32 +0000 Subject: [PATCH 3/3] fix: keep SENTRY_HOST with fallback default, fix compiler to handle env expressions in MCP configs Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/mcp-inspector.lock.yml | 8 +++++--- .github/workflows/shared/mcp/sentry.md | 1 + pkg/workflow/mcp_environment.go | 8 +++++++- pkg/workflow/secret_extraction.go | 19 +++++++++++++++++++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/.github/workflows/mcp-inspector.lock.yml b/.github/workflows/mcp-inspector.lock.yml index 7c9d79c4509..a5f702fedc0 100644 --- a/.github/workflows/mcp-inspector.lock.yml +++ b/.github/workflows/mcp-inspector.lock.yml @@ -42,7 +42,7 @@ # - shared/mcp/tavily.md # - shared/reporting.md # -# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"50fbf29123a8c727c21f28170fd58aa1d6f5b74177bd42a5f6300b4229de44a6"} +# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"e92fc7f19a13329f2f521f2c3ade949e9a30c1bd31c9752c012a660be935c8a8"} name: "MCP Inspector Agent" "on": @@ -750,6 +750,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NOTION_API_TOKEN: ${{ secrets.NOTION_API_TOKEN }} SENTRY_ACCESS_TOKEN: ${{ secrets.SENTRY_ACCESS_TOKEN }} + SENTRY_HOST: ${{ env.SENTRY_HOST || 'https://sentry.io' }} SENTRY_OPENAI_API_KEY: ${{ secrets.SENTRY_OPENAI_API_KEY }} TAVILY_API_KEY: ${{ secrets.TAVILY_API_KEY }} run: | @@ -768,7 +769,7 @@ jobs: export DEBUG="*" export GH_AW_ENGINE="copilot" - export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_LOCKDOWN -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -e AZURE_CLIENT_ID -e AZURE_CLIENT_SECRET -e AZURE_TENANT_ID -e BRAVE_API_KEY -e CONTEXT7_API_KEY -e DD_API_KEY -e DD_APPLICATION_KEY -e DD_SITE -e NOTION_API_TOKEN -e SENTRY_ACCESS_TOKEN -e SENTRY_OPENAI_API_KEY -e TAVILY_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.1.6' + export MCP_GATEWAY_DOCKER_COMMAND='docker run -i --rm --network host -v /var/run/docker.sock:/var/run/docker.sock -e MCP_GATEWAY_PORT -e MCP_GATEWAY_DOMAIN -e MCP_GATEWAY_API_KEY -e MCP_GATEWAY_PAYLOAD_DIR -e MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD -e DEBUG -e MCP_GATEWAY_LOG_DIR -e GH_AW_MCP_LOG_DIR -e GH_AW_SAFE_OUTPUTS -e GH_AW_SAFE_OUTPUTS_CONFIG_PATH -e GH_AW_SAFE_OUTPUTS_TOOLS_PATH -e GH_AW_ASSETS_BRANCH -e GH_AW_ASSETS_MAX_SIZE_KB -e GH_AW_ASSETS_ALLOWED_EXTS -e DEFAULT_BRANCH -e GITHUB_MCP_SERVER_TOKEN -e GITHUB_MCP_LOCKDOWN -e GITHUB_REPOSITORY -e GITHUB_SERVER_URL -e GITHUB_SHA -e GITHUB_WORKSPACE -e GITHUB_TOKEN -e GITHUB_RUN_ID -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ATTEMPT -e GITHUB_JOB -e GITHUB_ACTION -e GITHUB_EVENT_NAME -e GITHUB_EVENT_PATH -e GITHUB_ACTOR -e GITHUB_ACTOR_ID -e GITHUB_TRIGGERING_ACTOR -e GITHUB_WORKFLOW -e GITHUB_WORKFLOW_REF -e GITHUB_WORKFLOW_SHA -e GITHUB_REF -e GITHUB_REF_NAME -e GITHUB_REF_TYPE -e GITHUB_HEAD_REF -e GITHUB_BASE_REF -e GH_AW_SAFE_OUTPUTS_PORT -e GH_AW_SAFE_OUTPUTS_API_KEY -e AZURE_CLIENT_ID -e AZURE_CLIENT_SECRET -e AZURE_TENANT_ID -e BRAVE_API_KEY -e CONTEXT7_API_KEY -e DD_API_KEY -e DD_APPLICATION_KEY -e DD_SITE -e NOTION_API_TOKEN -e SENTRY_ACCESS_TOKEN -e SENTRY_HOST -e SENTRY_OPENAI_API_KEY -e TAVILY_API_KEY -v /tmp/gh-aw/mcp-payloads:/tmp/gh-aw/mcp-payloads:rw -v /opt:/opt:ro -v /tmp:/tmp:rw -v '"${GITHUB_WORKSPACE}"':'"${GITHUB_WORKSPACE}"':rw ghcr.io/github/gh-aw-mcpg:v0.1.6' mkdir -p /home/runner/.copilot cat << GH_AW_MCP_CONFIG_EOF | bash /opt/gh-aw/actions/start_mcp_gateway.sh @@ -965,7 +966,8 @@ jobs: ], "env": { "OPENAI_API_KEY": "\${SENTRY_OPENAI_API_KEY}", - "SENTRY_ACCESS_TOKEN": "\${SENTRY_ACCESS_TOKEN}" + "SENTRY_ACCESS_TOKEN": "\${SENTRY_ACCESS_TOKEN}", + "SENTRY_HOST": "\${SENTRY_HOST}" } }, "serena": { diff --git a/.github/workflows/shared/mcp/sentry.md b/.github/workflows/shared/mcp/sentry.md index b8b19694cc8..8d86dd2cfe4 100644 --- a/.github/workflows/shared/mcp/sentry.md +++ b/.github/workflows/shared/mcp/sentry.md @@ -20,6 +20,7 @@ mcp-servers: - get_doc env: SENTRY_ACCESS_TOKEN: ${{ secrets.SENTRY_ACCESS_TOKEN }} + SENTRY_HOST: ${{ env.SENTRY_HOST || 'https://sentry.io' }} # Optional OPENAI_API_KEY: ${{ secrets.SENTRY_OPENAI_API_KEY }} # Optional --- diff --git a/pkg/workflow/mcp_environment.go b/pkg/workflow/mcp_environment.go index 8013fb27fc1..c86fd21c03c 100644 --- a/pkg/workflow/mcp_environment.go +++ b/pkg/workflow/mcp_environment.go @@ -170,11 +170,17 @@ func collectMCPEnvironmentVariables(tools map[string]any, mcpTools []string, wor maps.Copy(envVars, headerSecrets) } - // Also extract secrets from env section if present + // Also extract secrets and env expressions from env section if present if len(mcpConfig.Env) > 0 { envSecrets := ExtractSecretsFromMap(mcpConfig.Env) mcpEnvironmentLog.Printf("Extracted %d secrets from env section of MCP server '%s'", len(envSecrets), toolName) maps.Copy(envVars, envSecrets) + + // Also extract env var expressions in addition to secrets + // (e.g., ${{ env.SENTRY_HOST || 'https://sentry.io' }}) so the gateway container can resolve them + envExprs := ExtractEnvExpressionsFromMap(mcpConfig.Env) + mcpEnvironmentLog.Printf("Extracted %d env expressions from env section of MCP server '%s'", len(envExprs), toolName) + maps.Copy(envVars, envExprs) } } } diff --git a/pkg/workflow/secret_extraction.go b/pkg/workflow/secret_extraction.go index 606d594d353..b75b1adac08 100644 --- a/pkg/workflow/secret_extraction.go +++ b/pkg/workflow/secret_extraction.go @@ -91,6 +91,25 @@ func ExtractSecretsFromMap(values map[string]string) map[string]string { return allSecrets } +// ExtractEnvExpressionsFromMap extracts all env variable expressions from a map of string values +// Returns a map of environment variable names to their full env expressions (including fallbacks) +// Example: +// +// Input: {"SENTRY_HOST": "${{ env.SENTRY_HOST || 'https://sentry.io' }}", "DD_SITE": "${{ env.DD_SITE }}"} +// Output: {"SENTRY_HOST": "${{ env.SENTRY_HOST || 'https://sentry.io' }}", "DD_SITE": "${{ env.DD_SITE }}"} +func ExtractEnvExpressionsFromMap(values map[string]string) map[string]string { + secretLog.Printf("Extracting env expressions from map with %d entries", len(values)) + allEnvVars := make(map[string]string) + + for _, value := range values { + envVars := ExtractEnvExpressionsFromValue(value) + maps.Copy(allEnvVars, envVars) + } + + secretLog.Printf("Extracted total of %d unique env expressions from map", len(allEnvVars)) + return allEnvVars +} + // ReplaceSecretsWithEnvVars replaces secret expressions in a value with environment variable references // Example: "${{ secrets.DD_API_KEY }}" -> "\${DD_API_KEY}" // The backslash is used to escape the ${} for proper JSON rendering in Copilot configs