mirror of https://github.com/actions/checkout
Compare commits
3 Commits
6517390cd2
...
c8ffa5e68a
| Author | SHA1 | Date |
|---|---|---|
|
|
c8ffa5e68a | |
|
|
064fe7f331 | |
|
|
e7667abffb |
|
|
@ -376,3 +376,120 @@ describe('Test fetchDepth and fetchTags options', () => {
|
|||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('git user-agent with orchestration ID', () => {
|
||||
beforeEach(async () => {
|
||||
jest.spyOn(fshelper, 'fileExistsSync').mockImplementation(jest.fn())
|
||||
jest.spyOn(fshelper, 'directoryExistsSync').mockImplementation(jest.fn())
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks()
|
||||
// Clean up environment variable to prevent test pollution
|
||||
delete process.env['ACTIONS_ORCHESTRATION_ID']
|
||||
})
|
||||
|
||||
it('should include orchestration ID in user-agent when ACTIONS_ORCHESTRATION_ID is set', async () => {
|
||||
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)
|
||||
|
||||
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 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)
|
||||
|
||||
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 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)
|
||||
|
||||
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
|
||||
expect(git).toBeDefined()
|
||||
expect(capturedEnv).toBeDefined()
|
||||
expect(capturedEnv['GIT_HTTP_USER_AGENT']).toBe(
|
||||
'git/2.18 (github-actions-checkout)'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -98,6 +98,10 @@ inputs:
|
|||
github-server-url:
|
||||
description: The base URL for the GitHub instance that you are trying to clone from, will use environment defaults to fetch from the same instance that the workflow is running from unless specified. Example URLs are https://github.com or https://my-ghes-server.example.com
|
||||
required: false
|
||||
skip-cleanup:
|
||||
description: Skips the cleanup phase on post action hook
|
||||
required: false
|
||||
default: false
|
||||
outputs:
|
||||
ref:
|
||||
description: 'The branch, tag or SHA that was checked out'
|
||||
|
|
|
|||
|
|
@ -1206,7 +1206,17 @@ class GitCommandManager {
|
|||
}
|
||||
}
|
||||
// Set the user agent
|
||||
const gitHttpUserAgent = `git/${this.gitVersion} (github-actions-checkout)`;
|
||||
let gitHttpUserAgent = `git/${this.gitVersion} (github-actions-checkout)`;
|
||||
// Append orchestration ID if set
|
||||
const orchId = process.env['ACTIONS_ORCHESTRATION_ID'];
|
||||
if (orchId) {
|
||||
// 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) {
|
||||
gitHttpUserAgent = `${gitHttpUserAgent} actions_orchestration_id/${sanitizedId}`;
|
||||
}
|
||||
}
|
||||
core.debug(`Set git useragent to: ${gitHttpUserAgent}`);
|
||||
this.gitEnv['GIT_HTTP_USER_AGENT'] = gitHttpUserAgent;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -730,7 +730,19 @@ class GitCommandManager {
|
|||
}
|
||||
}
|
||||
// Set the user agent
|
||||
const gitHttpUserAgent = `git/${this.gitVersion} (github-actions-checkout)`
|
||||
let gitHttpUserAgent = `git/${this.gitVersion} (github-actions-checkout)`
|
||||
|
||||
// Append orchestration ID if set
|
||||
const orchId = process.env['ACTIONS_ORCHESTRATION_ID']
|
||||
if (orchId) {
|
||||
// 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) {
|
||||
gitHttpUserAgent = `${gitHttpUserAgent} actions_orchestration_id/${sanitizedId}`
|
||||
}
|
||||
}
|
||||
|
||||
core.debug(`Set git useragent to: ${gitHttpUserAgent}`)
|
||||
this.gitEnv['GIT_HTTP_USER_AGENT'] = gitHttpUserAgent
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,4 +118,9 @@ export interface IGitSourceSettings {
|
|||
* User override on the GitHub Server/Host URL that hosts the repository to be cloned
|
||||
*/
|
||||
githubServerUrl: string | undefined
|
||||
|
||||
/**
|
||||
* Disable the post action cleanup phase
|
||||
*/
|
||||
skipCleanup: boolean
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,12 @@ async function run(): Promise<void> {
|
|||
}
|
||||
|
||||
async function cleanup(): Promise<void> {
|
||||
const sourceSettings = await inputHelper.getInputs()
|
||||
|
||||
if (sourceSettings.skipCleanup) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
await gitSourceProvider.cleanup(stateHelper.RepositoryPath)
|
||||
} catch (error) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue