From fab4258c6e9d27c6ee22af009d8c1988182bb69f Mon Sep 17 00:00:00 2001 From: Sangyeon Cho Date: Mon, 2 Feb 2026 07:01:29 +0900 Subject: [PATCH] fix: pass OpenTelemetry environment variables to Claude Code subprocess (#886) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: pass OpenTelemetry environment variables to Claude Code subprocess Environment variables set in workflow's step `env:` block were not being passed to the Claude Code subprocess because composite actions only forward explicitly referenced environment variables. This fix adds references for telemetry-related environment variables: - CLAUDE_CODE_ENABLE_TELEMETRY - OTEL_METRICS_EXPORTER - OTEL_LOGS_EXPORTER - OTEL_EXPORTER_OTLP_PROTOCOL - OTEL_EXPORTER_OTLP_ENDPOINT - OTEL_METRIC_EXPORT_INTERVAL - OTEL_LOGS_EXPORT_INTERVAL - OTEL_RESOURCE_ATTRIBUTES Co-Authored-By: 조상연[플레이스 AI] Co-Authored-By: csy1204 Co-Authored-By: Claude Opus 4.5 * test: add tests for OTEL environment variables passthrough Verify that telemetry-related environment variables are correctly passed through to sdkOptions.env when set in process.env. Co-Authored-By: 조상연[플레이스 AI] Co-Authored-By: csy1204 Co-Authored-By: Claude Opus 4.5 * fix: add missing OTEL_EXPORTER_OTLP_HEADERS environment variable Add OTEL_EXPORTER_OTLP_HEADERS to the list of OpenTelemetry environment variables passed through to the Claude Code subprocess. This variable is needed for authentication when connecting to OTLP endpoints that require bearer tokens or other credentials. Co-Authored-By: Claude Opus 4.5 --------- Co-authored-by: 조상연[플레이스 AI] Co-authored-by: Claude Opus 4.5 --- action.yml | 11 +++++ base-action/action.yml | 11 +++++ base-action/test/parse-sdk-options.test.ts | 55 ++++++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/action.yml b/action.yml index 16ed06b..c488614 100644 --- a/action.yml +++ b/action.yml @@ -312,6 +312,17 @@ runs: ANTHROPIC_DEFAULT_HAIKU_MODEL: ${{ env.ANTHROPIC_DEFAULT_HAIKU_MODEL }} ANTHROPIC_DEFAULT_OPUS_MODEL: ${{ env.ANTHROPIC_DEFAULT_OPUS_MODEL }} + # Telemetry configuration + CLAUDE_CODE_ENABLE_TELEMETRY: ${{ env.CLAUDE_CODE_ENABLE_TELEMETRY }} + OTEL_METRICS_EXPORTER: ${{ env.OTEL_METRICS_EXPORTER }} + OTEL_LOGS_EXPORTER: ${{ env.OTEL_LOGS_EXPORTER }} + OTEL_EXPORTER_OTLP_PROTOCOL: ${{ env.OTEL_EXPORTER_OTLP_PROTOCOL }} + OTEL_EXPORTER_OTLP_ENDPOINT: ${{ env.OTEL_EXPORTER_OTLP_ENDPOINT }} + OTEL_EXPORTER_OTLP_HEADERS: ${{ env.OTEL_EXPORTER_OTLP_HEADERS }} + OTEL_METRIC_EXPORT_INTERVAL: ${{ env.OTEL_METRIC_EXPORT_INTERVAL }} + OTEL_LOGS_EXPORT_INTERVAL: ${{ env.OTEL_LOGS_EXPORT_INTERVAL }} + OTEL_RESOURCE_ATTRIBUTES: ${{ env.OTEL_RESOURCE_ATTRIBUTES }} + - name: Update comment with job link if: steps.prepare.outputs.contains_trigger == 'true' && steps.prepare.outputs.claude_comment_id && always() shell: bash diff --git a/base-action/action.yml b/base-action/action.yml index e6e06e1..8716efd 100644 --- a/base-action/action.yml +++ b/base-action/action.yml @@ -202,3 +202,14 @@ runs: ANTHROPIC_DEFAULT_SONNET_MODEL: ${{ env.ANTHROPIC_DEFAULT_SONNET_MODEL }} ANTHROPIC_DEFAULT_HAIKU_MODEL: ${{ env.ANTHROPIC_DEFAULT_HAIKU_MODEL }} ANTHROPIC_DEFAULT_OPUS_MODEL: ${{ env.ANTHROPIC_DEFAULT_OPUS_MODEL }} + + # Telemetry configuration + CLAUDE_CODE_ENABLE_TELEMETRY: ${{ env.CLAUDE_CODE_ENABLE_TELEMETRY }} + OTEL_METRICS_EXPORTER: ${{ env.OTEL_METRICS_EXPORTER }} + OTEL_LOGS_EXPORTER: ${{ env.OTEL_LOGS_EXPORTER }} + OTEL_EXPORTER_OTLP_PROTOCOL: ${{ env.OTEL_EXPORTER_OTLP_PROTOCOL }} + OTEL_EXPORTER_OTLP_ENDPOINT: ${{ env.OTEL_EXPORTER_OTLP_ENDPOINT }} + OTEL_EXPORTER_OTLP_HEADERS: ${{ env.OTEL_EXPORTER_OTLP_HEADERS }} + OTEL_METRIC_EXPORT_INTERVAL: ${{ env.OTEL_METRIC_EXPORT_INTERVAL }} + OTEL_LOGS_EXPORT_INTERVAL: ${{ env.OTEL_LOGS_EXPORT_INTERVAL }} + OTEL_RESOURCE_ATTRIBUTES: ${{ env.OTEL_RESOURCE_ATTRIBUTES }} diff --git a/base-action/test/parse-sdk-options.test.ts b/base-action/test/parse-sdk-options.test.ts index 175508a..9c1095c 100644 --- a/base-action/test/parse-sdk-options.test.ts +++ b/base-action/test/parse-sdk-options.test.ts @@ -312,4 +312,59 @@ describe("parseSdkOptions", () => { expect(result.hasJsonSchema).toBe(true); }); }); + + describe("environment variables passthrough", () => { + test("should include OTEL environment variables in sdkOptions.env", () => { + // Set up test environment variables + const originalEnv = { ...process.env }; + process.env.CLAUDE_CODE_ENABLE_TELEMETRY = "1"; + process.env.OTEL_METRICS_EXPORTER = "otlp"; + process.env.OTEL_LOGS_EXPORTER = "otlp"; + process.env.OTEL_EXPORTER_OTLP_PROTOCOL = "http/json"; + process.env.OTEL_EXPORTER_OTLP_ENDPOINT = "https://example.com"; + process.env.OTEL_EXPORTER_OTLP_HEADERS = + "Authorization=Bearer test-token"; + process.env.OTEL_METRIC_EXPORT_INTERVAL = "10000"; + process.env.OTEL_LOGS_EXPORT_INTERVAL = "5000"; + process.env.OTEL_RESOURCE_ATTRIBUTES = "department=test"; + + try { + const options: ClaudeOptions = {}; + const result = parseSdkOptions(options); + + // Verify OTEL env vars are passed through to sdkOptions.env + expect(result.sdkOptions.env?.CLAUDE_CODE_ENABLE_TELEMETRY).toBe("1"); + expect(result.sdkOptions.env?.OTEL_METRICS_EXPORTER).toBe("otlp"); + expect(result.sdkOptions.env?.OTEL_LOGS_EXPORTER).toBe("otlp"); + expect(result.sdkOptions.env?.OTEL_EXPORTER_OTLP_PROTOCOL).toBe( + "http/json", + ); + expect(result.sdkOptions.env?.OTEL_EXPORTER_OTLP_ENDPOINT).toBe( + "https://example.com", + ); + expect(result.sdkOptions.env?.OTEL_EXPORTER_OTLP_HEADERS).toBe( + "Authorization=Bearer test-token", + ); + expect(result.sdkOptions.env?.OTEL_METRIC_EXPORT_INTERVAL).toBe( + "10000", + ); + expect(result.sdkOptions.env?.OTEL_LOGS_EXPORT_INTERVAL).toBe("5000"); + expect(result.sdkOptions.env?.OTEL_RESOURCE_ATTRIBUTES).toBe( + "department=test", + ); + } finally { + // Restore original environment + process.env = originalEnv; + } + }); + + test("should set CLAUDE_CODE_ENTRYPOINT in sdkOptions.env", () => { + const options: ClaudeOptions = {}; + const result = parseSdkOptions(options); + + expect(result.sdkOptions.env?.CLAUDE_CODE_ENTRYPOINT).toBe( + "claude-code-github-action", + ); + }); + }); });