From 4b8779770e3f45b3258af89b68516010ba3b5776 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 8 Jan 2026 15:39:33 +0000 Subject: [PATCH] Improve tests to verify user-agent content and handle empty sanitized IDs Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com> --- __test__/git-command-manager.test.ts | 74 +++++++++++++++++++++++++--- dist/index.js | 5 +- src/git-command-manager.ts | 3 +- 3 files changed, 74 insertions(+), 8 deletions(-) diff --git a/__test__/git-command-manager.test.ts b/__test__/git-command-manager.test.ts index 41bc31b..5b21f31 100644 --- a/__test__/git-command-manager.test.ts +++ b/__test__/git-command-manager.test.ts @@ -393,10 +393,13 @@ describe('git user-agent with orchestration ID', () => { const orchId = 'test-orch-id-12345' process.env['ACTIONS_ORCHESTRATION_ID'] = orchId + let capturedEnv: any = null mockExec.mockImplementation((path, args, options) => { if (args.includes('version')) { options.listeners.stdout(Buffer.from('2.18')) } + // Capture env on any command + capturedEnv = options.env return 0 }) jest.spyOn(exec, 'exec').mockImplementation(mockExec) @@ -410,19 +413,28 @@ describe('git user-agent with orchestration ID', () => { doSparseCheckout ) - // The user agent should be set with orchestration ID - // We can't directly inspect gitEnv, but we verify the git command was created successfully + // Call a git command to trigger env capture after user-agent is set + await git.init() + + // Verify the user agent includes the orchestration ID expect(git).toBeDefined() + expect(capturedEnv).toBeDefined() + expect(capturedEnv['GIT_HTTP_USER_AGENT']).toBe( + `git/2.18 (github-actions-checkout) actions_orchestration_id/${orchId}` + ) }) it('should sanitize invalid characters in orchestration ID', async () => { const orchId = 'test (with) special/chars' process.env['ACTIONS_ORCHESTRATION_ID'] = orchId + let capturedEnv: any = null mockExec.mockImplementation((path, args, options) => { if (args.includes('version')) { options.listeners.stdout(Buffer.from('2.18')) } + // Capture env on any command + capturedEnv = options.env return 0 }) jest.spyOn(exec, 'exec').mockImplementation(mockExec) @@ -436,18 +448,27 @@ describe('git user-agent with orchestration ID', () => { doSparseCheckout ) - // The user agent should be set with sanitized orchestration ID - // We can't directly inspect gitEnv, but we verify the git command was created successfully + // Call a git command to trigger env capture after user-agent is set + await git.init() + + // Verify the user agent has sanitized orchestration ID (spaces, parentheses, slash replaced) expect(git).toBeDefined() + expect(capturedEnv).toBeDefined() + expect(capturedEnv['GIT_HTTP_USER_AGENT']).toBe( + 'git/2.18 (github-actions-checkout) actions_orchestration_id/test__with__special_chars' + ) }) it('should not modify user-agent when ACTIONS_ORCHESTRATION_ID is not set', async () => { delete process.env['ACTIONS_ORCHESTRATION_ID'] + let capturedEnv: any = null mockExec.mockImplementation((path, args, options) => { if (args.includes('version')) { options.listeners.stdout(Buffer.from('2.18')) } + // Capture env on any command + capturedEnv = options.env return 0 }) jest.spyOn(exec, 'exec').mockImplementation(mockExec) @@ -461,8 +482,49 @@ describe('git user-agent with orchestration ID', () => { doSparseCheckout ) - // The user agent should be set without orchestration ID - // We can't directly inspect gitEnv, but we verify the git command was created successfully + // Call a git command to trigger env capture after user-agent is set + await git.init() + + // Verify the user agent does NOT contain orchestration ID expect(git).toBeDefined() + expect(capturedEnv).toBeDefined() + expect(capturedEnv['GIT_HTTP_USER_AGENT']).toBe( + 'git/2.18 (github-actions-checkout)' + ) + }) + + it('should not append orchestration ID when it becomes empty after sanitization', async () => { + const orchId = '()///' + process.env['ACTIONS_ORCHESTRATION_ID'] = orchId + + let capturedEnv: any = null + mockExec.mockImplementation((path, args, options) => { + if (args.includes('version')) { + options.listeners.stdout(Buffer.from('2.18')) + } + // Capture env on any command + capturedEnv = options.env + return 0 + }) + jest.spyOn(exec, 'exec').mockImplementation(mockExec) + + const workingDirectory = 'test' + const lfs = false + const doSparseCheckout = false + git = await commandManager.createCommandManager( + workingDirectory, + lfs, + doSparseCheckout + ) + + // Call a git command to trigger env capture after user-agent is set + await git.init() + + // Verify the user agent does NOT contain orchestration ID when sanitized ID is empty + expect(git).toBeDefined() + expect(capturedEnv).toBeDefined() + expect(capturedEnv['GIT_HTTP_USER_AGENT']).toBe( + 'git/2.18 (github-actions-checkout)' + ) }) }) diff --git a/dist/index.js b/dist/index.js index c913627..afcd3f8 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1213,7 +1213,10 @@ class GitCommandManager { // Sanitize the orchestration ID to ensure it contains only valid characters // Valid characters: 0-9, a-z, _, -, . const sanitizedId = orchId.replace(/[^a-z0-9_.-]/gi, '_'); - gitHttpUserAgent = `${gitHttpUserAgent} actions_orchestration_id/${sanitizedId}`; + // Only append if sanitized ID contains at least one alphanumeric character + if (sanitizedId && /[a-z0-9]/i.test(sanitizedId)) { + gitHttpUserAgent = `${gitHttpUserAgent} actions_orchestration_id/${sanitizedId}`; + } } core.debug(`Set git useragent to: ${gitHttpUserAgent}`); this.gitEnv['GIT_HTTP_USER_AGENT'] = gitHttpUserAgent; diff --git a/src/git-command-manager.ts b/src/git-command-manager.ts index 8d14d7b..ea2302a 100644 --- a/src/git-command-manager.ts +++ b/src/git-command-manager.ts @@ -738,7 +738,8 @@ class GitCommandManager { // Sanitize the orchestration ID to ensure it contains only valid characters // Valid characters: 0-9, a-z, _, -, . const sanitizedId = orchId.replace(/[^a-z0-9_.-]/gi, '_') - if (sanitizedId.trim().length > 0) { + // Only append if sanitized ID contains at least one alphanumeric character + if (sanitizedId && /[a-z0-9]/i.test(sanitizedId)) { gitHttpUserAgent = `${gitHttpUserAgent} actions_orchestration_id/${sanitizedId}` } }