diff --git a/packages/core/src/telemetry/clearcut-logger/clearcut-logger.test.ts b/packages/core/src/telemetry/clearcut-logger/clearcut-logger.test.ts index 9eca914db5..fa14fcb017 100644 --- a/packages/core/src/telemetry/clearcut-logger/clearcut-logger.test.ts +++ b/packages/core/src/telemetry/clearcut-logger/clearcut-logger.test.ts @@ -419,6 +419,31 @@ describe('ClearcutLogger', () => { ); }); + describe('GH_WORKFLOW_NAME metadata', () => { + it('includes workflow name when GH_WORKFLOW_NAME is set', () => { + const { logger } = setup({}); + vi.stubEnv('GH_WORKFLOW_NAME', 'test-workflow'); + + const event = logger?.createLogEvent(EventNames.API_ERROR, []); + expect(event?.event_metadata[0]).toContainEqual({ + gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_WORKFLOW_NAME, + value: 'test-workflow', + }); + }); + + it('does not include workflow name when GH_WORKFLOW_NAME is not set', () => { + const { logger } = setup({}); + vi.stubEnv('GH_WORKFLOW_NAME', undefined); + + const event = logger?.createLogEvent(EventNames.API_ERROR, []); + const hasWorkflowName = event?.event_metadata[0].some( + (item) => + item.gemini_cli_key === EventMetadataKey.GEMINI_CLI_GH_WORKFLOW_NAME, + ); + expect(hasWorkflowName).toBe(false); + }); + }); + describe('logChatCompressionEvent', () => { it('logs an event with proper fields', () => { const { logger } = setup(); diff --git a/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts b/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts index a465e9dec8..81a4e771b4 100644 --- a/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts +++ b/packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts @@ -149,6 +149,13 @@ function determineSurface(): string { } } +/** + * Determines the GitHub Actions workflow name if the CLI is running in a GitHub Actions environment. + */ +function determineGHWorkflowName(): string | undefined { + return process.env['GH_WORKFLOW_NAME']; +} + /** * Clearcut URL to send logging events to. */ @@ -260,31 +267,39 @@ export class ClearcutLogger { data: EventValue[] = [], ): LogEvent { const surface = determineSurface(); + const ghWorkflowName = determineGHWorkflowName(); + const baseMetadata: EventValue[] = [ + ...data, + { + gemini_cli_key: EventMetadataKey.GEMINI_CLI_SURFACE, + value: surface, + }, + { + gemini_cli_key: EventMetadataKey.GEMINI_CLI_VERSION, + value: CLI_VERSION, + }, + { + gemini_cli_key: EventMetadataKey.GEMINI_CLI_GIT_COMMIT_HASH, + value: GIT_COMMIT_INFO, + }, + { + gemini_cli_key: EventMetadataKey.GEMINI_CLI_OS, + value: process.platform, + }, + ]; + + if (ghWorkflowName) { + baseMetadata.push({ + gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_WORKFLOW_NAME, + value: ghWorkflowName, + }); + } + return { console_type: 'GEMINI_CLI', application: 102, // GEMINI_CLI event_name: eventName as string, - event_metadata: [ - [ - ...data, - { - gemini_cli_key: EventMetadataKey.GEMINI_CLI_SURFACE, - value: surface, - }, - { - gemini_cli_key: EventMetadataKey.GEMINI_CLI_VERSION, - value: CLI_VERSION, - }, - { - gemini_cli_key: EventMetadataKey.GEMINI_CLI_GIT_COMMIT_HASH, - value: GIT_COMMIT_INFO, - }, - { - gemini_cli_key: EventMetadataKey.GEMINI_CLI_OS, - value: process.platform, - }, - ], - ], + event_metadata: [baseMetadata], }; } diff --git a/packages/core/src/telemetry/clearcut-logger/event-metadata-key.ts b/packages/core/src/telemetry/clearcut-logger/event-metadata-key.ts index 55ab78338d..fc64f8a714 100644 --- a/packages/core/src/telemetry/clearcut-logger/event-metadata-key.ts +++ b/packages/core/src/telemetry/clearcut-logger/event-metadata-key.ts @@ -7,7 +7,7 @@ // Defines valid event metadata keys for Clearcut logging. export enum EventMetadataKey { // Deleted enums: 24 - // Next ID: 129 + // Next ID: 131 GEMINI_CLI_KEY_UNKNOWN = 0, @@ -191,6 +191,9 @@ export enum EventMetadataKey { // Logs active user settings GEMINI_CLI_USER_SETTINGS = 84, + // Logs the name of the GitHub Action workflow that triggered the session. + GEMINI_CLI_GH_WORKFLOW_NAME = 130, + // ========================================================================== // Loop Detected Event Keys // ===========================================================================