Conversation
…ns/setup trace IDs When observability.otlp.endpoint is set in the workflow frontmatter, the MCP gateway config now includes an opentelemetry section (spec §4.1.3.6) with: - endpoint from OTEL_EXPORTER_OTLP_ENDPOINT env var - headers parsed from OTEL_EXPORTER_OTLP_HEADERS (comma-separated key=value) - traceId from GITHUB_AW_OTEL_TRACE_ID (set by actions/setup step) - spanId from GITHUB_AW_OTEL_PARENT_SPAN_ID (set by actions/setup step) Agent-Logs-Url: https://github.com/github/gh-aw/sessions/7b2ea1c3-184d-4a30-9426-2ac47eceaf54 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
pkg/workflow/mcp_gateway_config.go
Outdated
| // Detect OTLP configuration from observability.otlp frontmatter. | ||
| // When configured, the gateway will emit distributed traces to the OTLP collector | ||
| // using the trace/span IDs from the actions/setup step for cross-job correlation. | ||
| otlpEndpoint, _ := extractOTLPConfigFromRaw(workflowData.RawFrontmatter) |
There was a problem hiding this comment.
@copilot must operate on full resolved front matter with imports
There was a problem hiding this comment.
Fixed in b8188e6. buildMCPGatewayConfig now uses workflowData.OTLPEndpoint, which is the fully resolved endpoint set by injectOTLPConfig after merging observability from both the top-level frontmatter and any imported shared workflows (e.g. shared/observability-otlp.md). The observability field is now extracted from imports using a first-wins strategy (same pattern as activationGitHubToken), merged into RawFrontmatter before injectOTLPConfig runs, making it the single source of truth for all downstream code.
pkg/workflow/mcp_setup_generator.go
Outdated
| // - traceId: from GITHUB_AW_OTEL_TRACE_ID (set by actions/setup via GITHUB_ENV) | ||
| // - spanId: from GITHUB_AW_OTEL_PARENT_SPAN_ID (set by actions/setup via GITHUB_ENV) | ||
| // The variable is consumed by ${GH_AW_GATEWAY_OTEL} in the MCP config heredoc. | ||
| otlpEndpoint, _ := extractOTLPConfigFromRaw(workflowData.RawFrontmatter) |
There was a problem hiding this comment.
@copilot must operate on fully resolved front matter with imports
There was a problem hiding this comment.
Fixed in b8188e6. mcp_setup_generator.go now checks workflowData.OTLPEndpoint != "" instead of re-reading raw frontmatter. OTLPEndpoint is the fully resolved endpoint set by injectOTLPConfig, which now also picks up observability defined in imported shared workflows via the new MergedObservability field in ImportsResult.
- Add observability extraction from imported shared workflows in the imports system (first-wins strategy, same as activationGitHubToken) - Before calling injectOTLPConfig, merge imported observability into RawFrontmatter when the top-level frontmatter has no observability section - Store the resolved OTLP endpoint in WorkflowData.OTLPEndpoint (set by injectOTLPConfig as the single source of truth including imports) - buildMCPGatewayConfig and mcp_setup_generator.go now use workflowData.OTLPEndpoint instead of independently re-reading raw frontmatter Agent-Logs-Url: https://github.com/github/gh-aw/sessions/257796c2-5f84-437a-957f-65ea15d03d61 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. 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:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot review mcp gateway specification for proper implementation. There is no change needed with awf, it's all in the mcp config file |
…riable
Per spec §4.1.3.6, the opentelemetry configuration belongs in the MCP
config file using ${VARIABLE_NAME} expressions (the same pattern used
for domain, apiKey, etc.). Remove the shell-built GH_AW_GATEWAY_OTEL
variable and instead render the opentelemetry object statically with
${OTEL_EXPORTER_OTLP_ENDPOINT}, ${GITHUB_AW_OTEL_TRACE_ID}, and
${GITHUB_AW_OTEL_PARENT_SPAN_ID} references. The gateway expands these
at config-load time from env vars passed via -e flags.
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/80f8d9fa-8b38-4a3e-8a2c-e49ef408b516
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done in e4529e0. The "opentelemetry": {
"endpoint": "${OTEL_EXPORTER_OTLP_ENDPOINT}",
"traceId": "${GITHUB_AW_OTEL_TRACE_ID}",
"spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}"
}The shell code that built 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:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot do not use env variable. Write the values in tbe config file. |
Endpoint and headers are available at compile time from the frontmatter
so write them as literal values in the opentelemetry config block. Only
traceId and spanId remain as ${VARIABLE_NAME} expressions since they are
set at runtime via GITHUB_ENV by actions/setup and cannot be known at
compile time. Remove OTEL_EXPORTER_OTLP_ENDPOINT and
OTEL_EXPORTER_OTLP_HEADERS from the gateway container -e flags since the
gateway reads those values directly from its config file now.
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/0ecb18c0-a493-4c1d-b078-4c19df61dd9b
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done in 321d01f. The endpoint and parsed headers are now written as literal values directly in the config. Only "opentelemetry": {
"endpoint": "https://collector.example.com:4318/v1/traces",
"headers": {"api-key": "myApiKey"},
"traceId": "${GITHUB_AW_OTEL_TRACE_ID}",
"spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}"
}
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:
If you need me to access, download, or install something from one of these locations, you can either:
|
| "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" | ||
| "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}", | ||
| "opentelemetry": { | ||
| "endpoint": "${{ secrets.GH_AW_OTEL_ENDPOINT }}", |
There was a problem hiding this comment.
Done in eca8a58. Headers are now written as a raw string literal directly in the config (same treatment as endpoint), so ${{ secrets.GH_AW_OTEL_HEADERS }} is preserved and expanded by GitHub Actions at runtime:
"opentelemetry": {
"endpoint": "${{ secrets.GH_AW_OTEL_ENDPOINT }}",
"headers": "${{ secrets.GH_AW_OTEL_HEADERS }}",
"traceId": "${GITHUB_AW_OTEL_TRACE_ID}",
"spanId": "${GITHUB_AW_OTEL_PARENT_SPAN_ID}"
}Switch OTLPHeaders from map[string]string to string so that GitHub
Actions expressions (${{ secrets.X }}) are preserved and written
verbatim in the config just like the endpoint. Remove the now-unused
parseOTLPHeaders helper and its tests.
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/3de8b920-c862-4a7c-982d-ea8bbd6d9a51
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. 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:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
✅ GitHub MCP | ✅ MCP Scripts GH CLI | ✅ Playwright | ✅ Web Fetch | ✅ File Write | ✅ Bash | ✅ Discussion | ✅ Build | ✅ Discussion Create | ✅ Dispatch | ✅ PR Review Overall: PASS — PR #24697 by Note 🔒 Integrity filter blocked 1 itemThe following item were blocked because they don't meet the GitHub integrity level.
To allow these resources, lower tools:
github:
min-integrity: approved # merged | approved | unapproved | none
|
There was a problem hiding this comment.
🤖 Smoke test agent review pass. The OTLP endpoint resolution approach (storing resolved values on WorkflowData) is clean and avoids downstream raw-frontmatter re-reads. Two inline suggestions: store OTLPHeaders alongside OTLPEndpoint for consistency, and consider logging unmarshal errors for imported observability configs.
Note
🔒 Integrity filter blocked 1 item
The following item were blocked because they don't meet the GitHub integrity level.
- #24788
list_pull_requests: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".
To allow these resources, lower min-integrity in your GitHub frontmatter:
tools:
github:
min-integrity: approved # merged | approved | unapproved | none📰 BREAKING: Report filed by Smoke Copilot · ● 1.2M
| otlpLog.Printf("Injected OTEL env vars into workflow env block") | ||
|
|
||
| // Store the resolved endpoint so downstream code (mcp_gateway_config, mcp_setup_generator) | ||
| // can use workflowData.OTLPEndpoint as the single source of truth instead of |
There was a problem hiding this comment.
🤖 Smoke test agent dropping by! Setting workflowData.OTLPEndpoint here as the single resolved source of truth is a clean approach — downstream code no longer needs to re-parse raw frontmatter. Consider also storing OTLPHeaders here similarly so both travel together through the pipeline.
| SecretMasking *SecretMaskingConfig // secret masking configuration | ||
| ParsedFrontmatter *FrontmatterConfig // cached parsed frontmatter configuration (for performance optimization) | ||
| RawFrontmatter map[string]any // raw parsed frontmatter map (for passing to hash functions without re-parsing) | ||
| OTLPEndpoint string // resolved OTLP endpoint (from observability.otlp.endpoint, including imports; set by injectOTLPConfig) |
There was a problem hiding this comment.
🤖 Smoke agent here! OTLPEndpoint is well-placed in WorkflowData. A natural follow-up would be adding OTLPHeaders string on the next line so both resolved values travel together and downstream consumers (like mcp_renderer.go) don't need separate logic to re-derive them.
|
📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤 |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
💥 Automated smoke test review - all systems nominal!
💥 [THE END] — Illustrated by Smoke Claude · ● 186.2K
| "opentelemetry": { | ||
| "endpoint": "${{ secrets.GH_AW_OTEL_ENDPOINT }}", | ||
| "headers": ${_GH_AW_OTLP_HEADERS_JSON}, | ||
| "traceId": "${GITHUB_AW_OTEL_TRACE_ID}", |
There was a problem hiding this comment.
The opentelemetry config block looks good — passing traceId and spanId from env vars enables proper distributed tracing across MCP gateway spans. Consider adding a fallback or validation step if these env vars are unset (e.g., empty string), to avoid sending malformed trace context to the OTLP collector.
| "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" | ||
| "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}", | ||
| "opentelemetry": { | ||
| "endpoint": "${{ secrets.GH_AW_OTEL_ENDPOINT }}", |
There was a problem hiding this comment.
The OTLP headers conversion pattern (node -e '...') with 2>/dev/null || echo "{}" is a safe fallback, but the inline node script is quite dense. A brief comment explaining the intent (converting key=value,... to JSON object) would help maintainability. The || echo "{}" fallback correctly handles node failures.
There was a problem hiding this comment.
🤖 Smoke agent agreeing! The inline Node.js OTLP headers conversion is self-contained and the || echo "{}" fallback is solid. A brief comment like # convert KEY=val,... to JSON object would definitely help future readers. Good catch!
📰 BREAKING: Report filed by Smoke Copilot · ● 871K
|
@copilot resolve the merge conflicts in this pull request |
…ntelemetry-mcp-gateway # Conflicts: # pkg/workflow/observability_otlp_test.go Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Done in f272c93. The conflict in 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:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing... |
|
✅ All tools validated successfully! Agent Container Smoke Test confirms agent container is ready. |
|
🌑 The shadows whisper... Smoke Codex failed. The oracle requires further meditation... |
|
🎬 THE END — Smoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨ |
Agent Container Tool Check
Result: 12/12 tools available ✅ Overall Status: PASS
|
|
Smoke Test: Copilot - 24016851148
Overall: 11/12 — Serena MCP tools unavailable in this context. PR Author:
|
There was a problem hiding this comment.
🤖 Smoke test review for PR #24697 — MCP gateway OTLP configuration. The approach of resolving OTLPEndpoint onto WorkflowData is clean. Main suggestion: add OTLPHeaders alongside OTLPEndpoint so both resolved values travel together. Overall this is a solid tracing integration.
📰 BREAKING: Report filed by Smoke Copilot · ● 871K
| otlpLog.Printf("Injected OTEL env vars into workflow env block") | ||
|
|
||
| // Store the resolved endpoint so downstream code (mcp_gateway_config, mcp_setup_generator) | ||
| // can use workflowData.OTLPEndpoint as the single source of truth instead of |
There was a problem hiding this comment.
🤖 Smoke agent here! Setting workflowData.OTLPEndpoint as the single resolved source of truth is exactly right. For symmetry, consider storing OTLPHeaders here too so both values are resolved in one place and always travel together through the compilation pipeline.
| SecretMasking *SecretMaskingConfig // secret masking configuration | ||
| ParsedFrontmatter *FrontmatterConfig // cached parsed frontmatter configuration (for performance optimization) | ||
| RawFrontmatter map[string]any // raw parsed frontmatter map (for passing to hash functions without re-parsing) | ||
| OTLPEndpoint string // resolved OTLP endpoint (from observability.otlp.endpoint, including imports; set by injectOTLPConfig) |
There was a problem hiding this comment.
🤖 Smoke agent checking in! OTLPEndpoint as a resolved field on WorkflowData is a clean design — downstream consumers no longer need to re-parse raw frontmatter. Consider adding OTLPHeaders string on the next line so both resolved values travel together through the pipeline and mcp_renderer.go has a single source of truth for both.
|
📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤 |
Smoke Test Results — Run 24016851157
Overall: PARTIAL — Tavily rate-limited (429); thread resolve skipped (no node IDs); close PR skipped (no safe PR).
|
There was a problem hiding this comment.
💥 Automated smoke test review - all systems nominal!
💥 [THE END] — Illustrated by Smoke Claude · ● 205.9K
| "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}" | ||
| "payloadDir": "${MCP_GATEWAY_PAYLOAD_DIR}", | ||
| "opentelemetry": { | ||
| "endpoint": "${{ secrets.GH_AW_OTEL_ENDPOINT }}", |
There was a problem hiding this comment.
Smoke test review comment #1 — Run 24016851157: The OTLP headers JSON conversion using node -e is a nice portable approach. Consider adding error handling for malformed header values.
| @@ -594,7 +599,13 @@ jobs: | |||
| "port": $MCP_GATEWAY_PORT, | |||
There was a problem hiding this comment.
Smoke test review comment #2 — Run 24016851157: OpenTelemetry config looks good. The traceId and spanId from env vars will properly propagate spans through the MCP gateway.
gh-aw-mcpg v0.2.14 added support for OpenTelemetry OTLP tracing (spec §4.1.3.6). This wires up the gateway's
opentelemetryconfig block automatically whenobservability.otlpis present in workflow frontmatter (including via imported shared workflows), correlating gateway traces under the same trace/span started by theactions/setupstep.Changes
pkg/parser/import_field_extractor.go— Extractobservabilityfrom imported workflows using a first-wins strategy (same pattern asactivationGitHubToken)pkg/parser/import_processor.go— AddMergedObservability stringtoImportsResultpkg/workflow/compiler_types.go— AddOTLPEndpoint stringtoWorkflowData(the fully-resolved OTLP endpoint, set byinjectOTLPConfig)pkg/workflow/compiler_orchestrator_workflow.go— Before callinginjectOTLPConfig, merge imported observability intoRawFrontmatterwhen the top-level workflow has noobservabilitysection (enables shared imports likeshared/observability-otlp.md)pkg/workflow/observability_otlp.go— Store the resolved endpoint inworkflowData.OTLPEndpointafter injection — single source of truth for all downstream codepkg/workflow/tools_types.go— ReplaceOTLPEnabled boolwithOTLPEndpoint stringandOTLPHeaders stringonMCPGatewayRuntimeConfig(yaml:"-", compiler-derived, not user-settable)pkg/workflow/mcp_gateway_config.go— PopulateOTLPEndpointandOTLPHeadersfrom the fully-resolved frontmatter (including imports)pkg/workflow/mcp_renderer.go— Write theopentelemetryblock directly into the gateway config JSON. The endpoint is written as a literal value. Headers require a JSON object per the gateway schema, so a bash preamble is generated before the heredoc that convertsOTEL_EXPORTER_OTLP_HEADERS(already a job-level env var frominjectOTLPConfig) fromkey=value,...OTLP string format to a JSON object vianode; the heredoc uses the unquoted bash variable${_GH_AW_OTLP_HEADERS_JSON}so bash expands it to the actual object.traceIdandspanIduse${GITHUB_AW_OTEL_TRACE_ID}/${GITHUB_AW_OTEL_PARENT_SPAN_ID}which bash expands from the GITHUB_ENV values set byactions/setup.pkg/workflow/mcp_setup_generator.go— Pass onlyGITHUB_AW_OTEL_TRACE_IDandGITHUB_AW_OTEL_PARENT_SPAN_IDto the gateway container via-e;OTEL_EXPORTER_OTLP_ENDPOINTandOTEL_EXPORTER_OTLP_HEADERSare no longer forwarded since their values are written directly in the configRuntime gateway config produced
The endpoint is taken directly from the
observability.otlpfrontmatter and written as a literal value — GitHub Actions expressions (e.g.${{ secrets.X }}) are preserved verbatim and expanded by the runner at execution time. Headers are converted at runtime from the OTLPkey=value,...string format to a proper JSON object (as required by the gateway schema) using a generated bash preamble.GITHUB_AW_OTEL_TRACE_IDandGITHUB_AW_OTEL_PARENT_SPAN_IDare written toGITHUB_ENVbyactions/setupviaaction_setup_otlp.cjs, making the gateway spans children of the setup span and correlating all MCP tool call traces under the workflow's root trace.The
observability.otlpconfig is now fully resolved including imports: a shared workflow (e.g..github/workflows/shared/observability-otlp.md) imported by multiple workflows will correctly enable gateway OTLP tracing in each of them.No lock files change for workflows without
observability.otlpconfigured.✨ PR Review Safe Output Test - Run 24007522566
✨ PR Review Safe Output Test - Run 24013947849
✨ PR Review Safe Output Test - Run 24016851157