mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-10 14:10:37 -07:00
feat(telemetry): add specific PR, issue, and custom tracking IDs for GitHub Actions (#21129)
This commit is contained in:
@@ -339,6 +339,12 @@ Captures startup configuration and user prompt submissions.
|
||||
- `mcp_tools` (string, if applicable)
|
||||
- `mcp_tools_count` (int, if applicable)
|
||||
- `output_format` ("text", "json", or "stream-json")
|
||||
- `github_workflow_name` (string, optional)
|
||||
- `github_repository_hash` (string, optional)
|
||||
- `github_event_name` (string, optional)
|
||||
- `github_pr_number` (string, optional)
|
||||
- `github_issue_number` (string, optional)
|
||||
- `github_custom_tracking_id` (string, optional)
|
||||
|
||||
- `gemini_cli.user_prompt`: Emitted when a user submits a prompt.
|
||||
- **Attributes**:
|
||||
|
||||
@@ -195,6 +195,9 @@ describe('ClearcutLogger', () => {
|
||||
vi.stubEnv('MONOSPACE_ENV', '');
|
||||
vi.stubEnv('REPLIT_USER', '');
|
||||
vi.stubEnv('__COG_BASHRC_SOURCED', '');
|
||||
vi.stubEnv('GH_PR_NUMBER', '');
|
||||
vi.stubEnv('GH_ISSUE_NUMBER', '');
|
||||
vi.stubEnv('GH_CUSTOM_TRACKING_ID', '');
|
||||
});
|
||||
|
||||
function setup({
|
||||
@@ -596,6 +599,110 @@ describe('ClearcutLogger', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('GITHUB_EVENT_NAME metadata', () => {
|
||||
it('includes event name when GITHUB_EVENT_NAME is set', () => {
|
||||
const { logger } = setup({});
|
||||
vi.stubEnv('GITHUB_EVENT_NAME', 'issues');
|
||||
|
||||
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
|
||||
expect(event?.event_metadata[0]).toContainEqual({
|
||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_EVENT_NAME,
|
||||
value: 'issues',
|
||||
});
|
||||
});
|
||||
|
||||
it('does not include event name when GITHUB_EVENT_NAME is not set', () => {
|
||||
const { logger } = setup({});
|
||||
vi.stubEnv('GITHUB_EVENT_NAME', undefined);
|
||||
|
||||
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
|
||||
const hasEventName = event?.event_metadata[0].some(
|
||||
(item) =>
|
||||
item.gemini_cli_key === EventMetadataKey.GEMINI_CLI_GH_EVENT_NAME,
|
||||
);
|
||||
expect(hasEventName).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GH_PR_NUMBER metadata', () => {
|
||||
it('includes PR number when GH_PR_NUMBER is set', () => {
|
||||
vi.stubEnv('GH_PR_NUMBER', '123');
|
||||
const { logger } = setup({});
|
||||
|
||||
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
|
||||
|
||||
expect(event?.event_metadata[0]).toContainEqual({
|
||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_PR_NUMBER,
|
||||
value: '123',
|
||||
});
|
||||
});
|
||||
|
||||
it('does not include PR number when GH_PR_NUMBER is not set', () => {
|
||||
vi.stubEnv('GH_PR_NUMBER', undefined);
|
||||
const { logger } = setup({});
|
||||
|
||||
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
|
||||
const hasPRNumber = event?.event_metadata[0].some(
|
||||
(item) =>
|
||||
item.gemini_cli_key === EventMetadataKey.GEMINI_CLI_GH_PR_NUMBER,
|
||||
);
|
||||
expect(hasPRNumber).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GH_ISSUE_NUMBER metadata', () => {
|
||||
it('includes issue number when GH_ISSUE_NUMBER is set', () => {
|
||||
vi.stubEnv('GH_ISSUE_NUMBER', '456');
|
||||
const { logger } = setup({});
|
||||
|
||||
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
|
||||
|
||||
expect(event?.event_metadata[0]).toContainEqual({
|
||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_ISSUE_NUMBER,
|
||||
value: '456',
|
||||
});
|
||||
});
|
||||
|
||||
it('does not include issue number when GH_ISSUE_NUMBER is not set', () => {
|
||||
vi.stubEnv('GH_ISSUE_NUMBER', undefined);
|
||||
const { logger } = setup({});
|
||||
|
||||
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
|
||||
const hasIssueNumber = event?.event_metadata[0].some(
|
||||
(item) =>
|
||||
item.gemini_cli_key === EventMetadataKey.GEMINI_CLI_GH_ISSUE_NUMBER,
|
||||
);
|
||||
expect(hasIssueNumber).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GH_CUSTOM_TRACKING_ID metadata', () => {
|
||||
it('includes custom tracking ID when GH_CUSTOM_TRACKING_ID is set', () => {
|
||||
vi.stubEnv('GH_CUSTOM_TRACKING_ID', 'abc-789');
|
||||
const { logger } = setup({});
|
||||
|
||||
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
|
||||
|
||||
expect(event?.event_metadata[0]).toContainEqual({
|
||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_CUSTOM_TRACKING_ID,
|
||||
value: 'abc-789',
|
||||
});
|
||||
});
|
||||
|
||||
it('does not include custom tracking ID when GH_CUSTOM_TRACKING_ID is not set', () => {
|
||||
vi.stubEnv('GH_CUSTOM_TRACKING_ID', undefined);
|
||||
const { logger } = setup({});
|
||||
|
||||
const event = logger?.createLogEvent(EventNames.API_ERROR, []);
|
||||
const hasTrackingId = event?.event_metadata[0].some(
|
||||
(item) =>
|
||||
item.gemini_cli_key ===
|
||||
EventMetadataKey.GEMINI_CLI_GH_CUSTOM_TRACKING_ID,
|
||||
);
|
||||
expect(hasTrackingId).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GITHUB_REPOSITORY metadata', () => {
|
||||
it('includes hashed repository when GITHUB_REPOSITORY is set', () => {
|
||||
vi.stubEnv('GITHUB_REPOSITORY', 'google/gemini-cli');
|
||||
|
||||
@@ -190,6 +190,34 @@ function determineGHRepositoryName(): string | undefined {
|
||||
return process.env['GITHUB_REPOSITORY'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the GitHub event name if the CLI is running in a GitHub Actions environment.
|
||||
*/
|
||||
function determineGHEventName(): string | undefined {
|
||||
return process.env['GITHUB_EVENT_NAME'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the GitHub Pull Request number if the CLI is running in a GitHub Actions environment.
|
||||
*/
|
||||
function determineGHPRNumber(): string | undefined {
|
||||
return process.env['GH_PR_NUMBER'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the GitHub Issue number if the CLI is running in a GitHub Actions environment.
|
||||
*/
|
||||
function determineGHIssueNumber(): string | undefined {
|
||||
return process.env['GH_ISSUE_NUMBER'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the GitHub custom tracking ID if the CLI is running in a GitHub Actions environment.
|
||||
*/
|
||||
function determineGHCustomTrackingId(): string | undefined {
|
||||
return process.env['GH_CUSTOM_TRACKING_ID'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clearcut URL to send logging events to.
|
||||
*/
|
||||
@@ -372,6 +400,10 @@ export class ClearcutLogger {
|
||||
const email = this.userAccountManager.getCachedGoogleAccount();
|
||||
const surface = determineSurface();
|
||||
const ghWorkflowName = determineGHWorkflowName();
|
||||
const ghEventName = determineGHEventName();
|
||||
const ghPRNumber = determineGHPRNumber();
|
||||
const ghIssueNumber = determineGHIssueNumber();
|
||||
const ghCustomTrackingId = determineGHCustomTrackingId();
|
||||
const baseMetadata: EventValue[] = [
|
||||
...data,
|
||||
{
|
||||
@@ -406,6 +438,34 @@ export class ClearcutLogger {
|
||||
});
|
||||
}
|
||||
|
||||
if (ghEventName) {
|
||||
baseMetadata.push({
|
||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_EVENT_NAME,
|
||||
value: ghEventName,
|
||||
});
|
||||
}
|
||||
|
||||
if (ghPRNumber) {
|
||||
baseMetadata.push({
|
||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_PR_NUMBER,
|
||||
value: ghPRNumber,
|
||||
});
|
||||
}
|
||||
|
||||
if (ghIssueNumber) {
|
||||
baseMetadata.push({
|
||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_ISSUE_NUMBER,
|
||||
value: ghIssueNumber,
|
||||
});
|
||||
}
|
||||
|
||||
if (ghCustomTrackingId) {
|
||||
baseMetadata.push({
|
||||
gemini_cli_key: EventMetadataKey.GEMINI_CLI_GH_CUSTOM_TRACKING_ID,
|
||||
value: ghCustomTrackingId,
|
||||
});
|
||||
}
|
||||
|
||||
const logEvent: LogEvent = {
|
||||
console_type: 'GEMINI_CLI',
|
||||
application: 102, // GEMINI_CLI
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
// Defines valid event metadata keys for Clearcut logging.
|
||||
export enum EventMetadataKey {
|
||||
// Deleted enums: 24
|
||||
// Next ID: 176
|
||||
// Next ID: 180
|
||||
|
||||
GEMINI_CLI_KEY_UNKNOWN = 0,
|
||||
|
||||
@@ -231,6 +231,18 @@ export enum EventMetadataKey {
|
||||
// Logs the repository name of the GitHub Action that triggered the session.
|
||||
GEMINI_CLI_GH_REPOSITORY_NAME_HASH = 132,
|
||||
|
||||
// Logs the event name of the GitHub Action that triggered the session.
|
||||
GEMINI_CLI_GH_EVENT_NAME = 176,
|
||||
|
||||
// Logs the Pull Request number if the workflow is operating on a PR.
|
||||
GEMINI_CLI_GH_PR_NUMBER = 177,
|
||||
|
||||
// Logs the Issue number if the workflow is operating on an Issue.
|
||||
GEMINI_CLI_GH_ISSUE_NUMBER = 178,
|
||||
|
||||
// Logs a custom tracking string (e.g. a comma-separated list of issue IDs for scheduled batches).
|
||||
GEMINI_CLI_GH_CUSTOM_TRACKING_ID = 179,
|
||||
|
||||
// ==========================================================================
|
||||
// Loop Detected Event Keys
|
||||
// ===========================================================================
|
||||
|
||||
Reference in New Issue
Block a user