diff --git a/__test__/orchestration-id.test.ts b/__test__/orchestration-id.test.ts new file mode 100644 index 0000000..a8c5963 --- /dev/null +++ b/__test__/orchestration-id.test.ts @@ -0,0 +1,73 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +describe('getUserAgentWithOrchestrationId', () => { + let originalEnv: NodeJS.ProcessEnv + + beforeEach(() => { + originalEnv = {...process.env} + }) + + afterEach(() => { + process.env = originalEnv + }) + + // Since getUserAgentWithOrchestrationId is not exported, we'll test it indirectly + // by mocking the getInput and testing the behavior through the main function integration + // For now, we'll create simple unit tests that verify the logic + + test('appends orchestration ID when ACTIONS_ORCHESTRATION_ID is set', () => { + const baseUserAgent = 'actions/github-script' + const orchestrationId = 'test-orchestration-123' + process.env['ACTIONS_ORCHESTRATION_ID'] = orchestrationId + + // Simulate the logic from getUserAgentWithOrchestrationId + const sanitized = orchestrationId.replace(/[^a-zA-Z0-9.-]/g, '') + const result = `${baseUserAgent} orchestration-id/${sanitized}` + + expect(result).toBe('actions/github-script orchestration-id/test-orchestration-123') + }) + + test('sanitizes orchestration ID by removing special characters', () => { + const baseUserAgent = 'actions/github-script' + const orchestrationId = 'test@orchestration#123!abc$xyz' + + // Simulate the logic from getUserAgentWithOrchestrationId + const sanitized = orchestrationId.replace(/[^a-zA-Z0-9.-]/g, '') + const result = `${baseUserAgent} orchestration-id/${sanitized}` + + expect(result).toBe('actions/github-script orchestration-id/testorchestration123abcxyz') + }) + + test('preserves dots and hyphens in orchestration ID', () => { + const baseUserAgent = 'actions/github-script' + const orchestrationId = 'test.orchestration-123' + + // Simulate the logic from getUserAgentWithOrchestrationId + const sanitized = orchestrationId.replace(/[^a-zA-Z0-9.-]/g, '') + const result = `${baseUserAgent} orchestration-id/${sanitized}` + + expect(result).toBe('actions/github-script orchestration-id/test.orchestration-123') + }) + + test('does not append orchestration ID when ACTIONS_ORCHESTRATION_ID is not set', () => { + const baseUserAgent = 'actions/github-script' + delete process.env['ACTIONS_ORCHESTRATION_ID'] + + // Simulate the logic from getUserAgentWithOrchestrationId + const orchestrationId = process.env['ACTIONS_ORCHESTRATION_ID'] + const result = orchestrationId ? `${baseUserAgent} orchestration-id/${orchestrationId}` : baseUserAgent + + expect(result).toBe('actions/github-script') + }) + + test('does not append orchestration ID when it becomes empty after sanitization', () => { + const baseUserAgent = 'actions/github-script' + const orchestrationId = '@#$%^&*()' + + // Simulate the logic from getUserAgentWithOrchestrationId + const sanitized = orchestrationId.replace(/[^a-zA-Z0-9.-]/g, '') + const result = sanitized ? `${baseUserAgent} orchestration-id/${sanitized}` : baseUserAgent + + expect(result).toBe('actions/github-script') + }) +}) diff --git a/dist/index.js b/dist/index.js index bb06b77..4138a02 100644 --- a/dist/index.js +++ b/dist/index.js @@ -36258,6 +36258,23 @@ const wrapRequire = new Proxy(require, { process.on('unhandledRejection', handleError); main().catch(handleError); +/** + * Gets the user agent string with orchestration ID appended if available + * @param userAgent The base user agent string + * @returns The user agent string with orchestration ID appended if ACTIONS_ORCHESTRATION_ID is set + */ +function getUserAgentWithOrchestrationId(userAgent) { + const orchestrationId = process.env['ACTIONS_ORCHESTRATION_ID']; + if (!orchestrationId) { + return userAgent; + } + // Sanitize orchestration ID - only keep alphanumeric, dots, and hyphens + const sanitized = orchestrationId.replace(/[^a-zA-Z0-9.-]/g, ''); + if (!sanitized) { + return userAgent; + } + return `${userAgent} orchestration-id/${sanitized}`; +} async function main() { const token = core.getInput('github-token', { required: true }); const debug = core.getBooleanInput('debug'); @@ -36267,9 +36284,11 @@ async function main() { const retries = parseInt(core.getInput('retries')); const exemptStatusCodes = parseNumberArray(core.getInput('retry-exempt-status-codes')); const [retryOpts, requestOpts] = getRetryOptions(retries, exemptStatusCodes, utils.defaults); + const baseUserAgent = userAgent || 'actions/github-script'; + const finalUserAgent = getUserAgentWithOrchestrationId(baseUserAgent); const opts = { log: debug ? console : undefined, - userAgent: userAgent || undefined, + userAgent: finalUserAgent, previews: previews ? previews.split(',') : undefined, retry: retryOpts, request: requestOpts diff --git a/src/main.ts b/src/main.ts index baa2933..bcf0740 100644 --- a/src/main.ts +++ b/src/main.ts @@ -23,6 +23,26 @@ type Options = { request?: RequestRequestOptions } +/** + * Gets the user agent string with orchestration ID appended if available + * @param userAgent The base user agent string + * @returns The user agent string with orchestration ID appended if ACTIONS_ORCHESTRATION_ID is set + */ +function getUserAgentWithOrchestrationId(userAgent: string): string { + const orchestrationId = process.env['ACTIONS_ORCHESTRATION_ID'] + if (!orchestrationId) { + return userAgent + } + + // Sanitize orchestration ID - only keep alphanumeric, dots, and hyphens + const sanitized = orchestrationId.replace(/[^a-zA-Z0-9.-]/g, '') + if (!sanitized) { + return userAgent + } + + return `${userAgent} orchestration-id/${sanitized}` +} + async function main(): Promise { const token = core.getInput('github-token', {required: true}) const debug = core.getBooleanInput('debug') @@ -39,9 +59,12 @@ async function main(): Promise { defaultGitHubOptions ) + const baseUserAgent = userAgent || 'actions/github-script' + const finalUserAgent = getUserAgentWithOrchestrationId(baseUserAgent) + const opts: Options = { log: debug ? console : undefined, - userAgent: userAgent || undefined, + userAgent: finalUserAgent, previews: previews ? previews.split(',') : undefined, retry: retryOpts, request: requestOpts