Skip to content

Commit e91f86c

Browse files
authored
feat(telemetry): add specific PR, issue, and custom tracking IDs for GitHub Actions (#21129)
1 parent 47e4f6b commit e91f86c

4 files changed

Lines changed: 186 additions & 1 deletion

File tree

docs/cli/telemetry.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,12 @@ Captures startup configuration and user prompt submissions.
339339
- `mcp_tools` (string, if applicable)
340340
- `mcp_tools_count` (int, if applicable)
341341
- `output_format` ("text", "json", or "stream-json")
342+
- `github_workflow_name` (string, optional)
343+
- `github_repository_hash` (string, optional)
344+
- `github_event_name` (string, optional)
345+
- `github_pr_number` (string, optional)
346+
- `github_issue_number` (string, optional)
347+
- `github_custom_tracking_id` (string, optional)
342348
343349
- `gemini_cli.user_prompt`: Emitted when a user submits a prompt.
344350
- **Attributes**:

packages/core/src/telemetry/clearcut-logger/clearcut-logger.test.ts

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,9 @@ describe('ClearcutLogger', () => {
195195
vi.stubEnv('MONOSPACE_ENV', '');
196196
vi.stubEnv('REPLIT_USER', '');
197197
vi.stubEnv('__COG_BASHRC_SOURCED', '');
198+
vi.stubEnv('GH_PR_NUMBER', '');
199+
vi.stubEnv('GH_ISSUE_NUMBER', '');
200+
vi.stubEnv('GH_CUSTOM_TRACKING_ID', '');
198201
});
199202

200203
function setup({
@@ -596,6 +599,110 @@ describe('ClearcutLogger', () => {
596599
});
597600
});
598601

602+
describe('GITHUB_EVENT_NAME metadata', () => {
603+
it('includes event name when GITHUB_EVENT_NAME is set', () => {
604+
const { logger } = setup({});
605+
vi.stubEnv('GITHUB_EVENT_NAME', 'issues');
606+
607+
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
608+
expect(event?.event_metadata[0]).toContainEqual({
609+
gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_EVENT_NAME,
610+
value: 'issues',
611+
});
612+
});
613+
614+
it('does not include event name when GITHUB_EVENT_NAME is not set', () => {
615+
const { logger } = setup({});
616+
vi.stubEnv('GITHUB_EVENT_NAME', undefined);
617+
618+
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
619+
const hasEventName = event?.event_metadata[0].some(
620+
(item) =>
621+
item.gemini_cli_key === EventMetadataKey.GEMINI_CLI_GH_EVENT_NAME,
622+
);
623+
expect(hasEventName).toBe(false);
624+
});
625+
});
626+
627+
describe('GH_PR_NUMBER metadata', () => {
628+
it('includes PR number when GH_PR_NUMBER is set', () => {
629+
vi.stubEnv('GH_PR_NUMBER', '123');
630+
const { logger } = setup({});
631+
632+
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
633+
634+
expect(event?.event_metadata[0]).toContainEqual({
635+
gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_PR_NUMBER,
636+
value: '123',
637+
});
638+
});
639+
640+
it('does not include PR number when GH_PR_NUMBER is not set', () => {
641+
vi.stubEnv('GH_PR_NUMBER', undefined);
642+
const { logger } = setup({});
643+
644+
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
645+
const hasPRNumber = event?.event_metadata[0].some(
646+
(item) =>
647+
item.gemini_cli_key === EventMetadataKey.GEMINI_CLI_GH_PR_NUMBER,
648+
);
649+
expect(hasPRNumber).toBe(false);
650+
});
651+
});
652+
653+
describe('GH_ISSUE_NUMBER metadata', () => {
654+
it('includes issue number when GH_ISSUE_NUMBER is set', () => {
655+
vi.stubEnv('GH_ISSUE_NUMBER', '456');
656+
const { logger } = setup({});
657+
658+
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
659+
660+
expect(event?.event_metadata[0]).toContainEqual({
661+
gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_ISSUE_NUMBER,
662+
value: '456',
663+
});
664+
});
665+
666+
it('does not include issue number when GH_ISSUE_NUMBER is not set', () => {
667+
vi.stubEnv('GH_ISSUE_NUMBER', undefined);
668+
const { logger } = setup({});
669+
670+
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
671+
const hasIssueNumber = event?.event_metadata[0].some(
672+
(item) =>
673+
item.gemini_cli_key === EventMetadataKey.GEMINI_CLI_GH_ISSUE_NUMBER,
674+
);
675+
expect(hasIssueNumber).toBe(false);
676+
});
677+
});
678+
679+
describe('GH_CUSTOM_TRACKING_ID metadata', () => {
680+
it('includes custom tracking ID when GH_CUSTOM_TRACKING_ID is set', () => {
681+
vi.stubEnv('GH_CUSTOM_TRACKING_ID', 'abc-789');
682+
const { logger } = setup({});
683+
684+
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
685+
686+
expect(event?.event_metadata[0]).toContainEqual({
687+
gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_CUSTOM_TRACKING_ID,
688+
value: 'abc-789',
689+
});
690+
});
691+
692+
it('does not include custom tracking ID when GH_CUSTOM_TRACKING_ID is not set', () => {
693+
vi.stubEnv('GH_CUSTOM_TRACKING_ID', undefined);
694+
const { logger } = setup({});
695+
696+
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
697+
const hasTrackingId = event?.event_metadata[0].some(
698+
(item) =>
699+
item.gemini_cli_key ===
700+
EventMetadataKey.GEMINI_CLI_GH_CUSTOM_TRACKING_ID,
701+
);
702+
expect(hasTrackingId).toBe(false);
703+
});
704+
});
705+
599706
describe('GITHUB_REPOSITORY metadata', () => {
600707
it('includes hashed repository when GITHUB_REPOSITORY is set', () => {
601708
vi.stubEnv('GITHUB_REPOSITORY', 'google/gemini-cli');

packages/core/src/telemetry/clearcut-logger/clearcut-logger.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,34 @@ function determineGHRepositoryName(): string | undefined {
190190
return process.env['GITHUB_REPOSITORY'];
191191
}
192192

193+
/**
194+
* Determines the GitHub event name if the CLI is running in a GitHub Actions environment.
195+
*/
196+
function determineGHEventName(): string | undefined {
197+
return process.env['GITHUB_EVENT_NAME'];
198+
}
199+
200+
/**
201+
* Determines the GitHub Pull Request number if the CLI is running in a GitHub Actions environment.
202+
*/
203+
function determineGHPRNumber(): string | undefined {
204+
return process.env['GH_PR_NUMBER'];
205+
}
206+
207+
/**
208+
* Determines the GitHub Issue number if the CLI is running in a GitHub Actions environment.
209+
*/
210+
function determineGHIssueNumber(): string | undefined {
211+
return process.env['GH_ISSUE_NUMBER'];
212+
}
213+
214+
/**
215+
* Determines the GitHub custom tracking ID if the CLI is running in a GitHub Actions environment.
216+
*/
217+
function determineGHCustomTrackingId(): string | undefined {
218+
return process.env['GH_CUSTOM_TRACKING_ID'];
219+
}
220+
193221
/**
194222
* Clearcut URL to send logging events to.
195223
*/
@@ -372,6 +400,10 @@ export class ClearcutLogger {
372400
const email = this.userAccountManager.getCachedGoogleAccount();
373401
const surface = determineSurface();
374402
const ghWorkflowName = determineGHWorkflowName();
403+
const ghEventName = determineGHEventName();
404+
const ghPRNumber = determineGHPRNumber();
405+
const ghIssueNumber = determineGHIssueNumber();
406+
const ghCustomTrackingId = determineGHCustomTrackingId();
375407
const baseMetadata: EventValue[] = [
376408
...data,
377409
{
@@ -406,6 +438,34 @@ export class ClearcutLogger {
406438
});
407439
}
408440

441+
if (ghEventName) {
442+
baseMetadata.push({
443+
gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_EVENT_NAME,
444+
value: ghEventName,
445+
});
446+
}
447+
448+
if (ghPRNumber) {
449+
baseMetadata.push({
450+
gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_PR_NUMBER,
451+
value: ghPRNumber,
452+
});
453+
}
454+
455+
if (ghIssueNumber) {
456+
baseMetadata.push({
457+
gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_ISSUE_NUMBER,
458+
value: ghIssueNumber,
459+
});
460+
}
461+
462+
if (ghCustomTrackingId) {
463+
baseMetadata.push({
464+
gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_CUSTOM_TRACKING_ID,
465+
value: ghCustomTrackingId,
466+
});
467+
}
468+
409469
const logEvent: LogEvent = {
410470
console_type: 'GEMINI_CLI',
411471
application: 102, // GEMINI_CLI

packages/core/src/telemetry/clearcut-logger/event-metadata-key.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// Defines valid event metadata keys for Clearcut logging.
88
export enum EventMetadataKey {
99
// Deleted enums: 24
10-
// Next ID: 176
10+
// Next ID: 180
1111

1212
GEMINI_CLI_KEY_UNKNOWN = 0,
1313

@@ -231,6 +231,18 @@ export enum EventMetadataKey {
231231
// Logs the repository name of the GitHub Action that triggered the session.
232232
GEMINI_CLI_GH_REPOSITORY_NAME_HASH = 132,
233233

234+
// Logs the event name of the GitHub Action that triggered the session.
235+
GEMINI_CLI_GH_EVENT_NAME = 176,
236+
237+
// Logs the Pull Request number if the workflow is operating on a PR.
238+
GEMINI_CLI_GH_PR_NUMBER = 177,
239+
240+
// Logs the Issue number if the workflow is operating on an Issue.
241+
GEMINI_CLI_GH_ISSUE_NUMBER = 178,
242+
243+
// Logs a custom tracking string (e.g. a comma-separated list of issue IDs for scheduled batches).
244+
GEMINI_CLI_GH_CUSTOM_TRACKING_ID = 179,
245+
234246
// ==========================================================================
235247
// Loop Detected Event Keys
236248
// ===========================================================================

0 commit comments

Comments
 (0)