Compare commits

...

16 Commits

Author SHA1 Message Date
copilot-swe-agent[bot] 83c13c81ba Improve test cleanup and add missing test coverage
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 19:19:35 +00:00
copilot-swe-agent[bot] bccbba401a Fix lint error: remove unnecessary escape in regex
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 18:30:18 +00:00
copilot-swe-agent[bot] 3a191eecf6 Add default user-agent 'actions/http-client' when none provided
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 18:10:12 +00:00
copilot-swe-agent[bot] 97f5a6f0dc Simplify constructor by handling undefined in helper method
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 18:03:26 +00:00
copilot-swe-agent[bot] 48a7cdbf9c Remove .gitignore change for .nx/ directory
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 17:54:40 +00:00
copilot-swe-agent[bot] 3f1933edf9 Revert unrelated version bumps in package-lock.json files
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 17:50:28 +00:00
copilot-swe-agent[bot] 2215c8e5aa Restrict sanitization to only allow 0-9, a-z, _, -, .
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 17:37:28 +00:00
copilot-swe-agent[bot] af6de2cb95 Move orchestration ID logic to constructor for efficiency
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 17:30:28 +00:00
copilot-swe-agent[bot] 1dc58e3080 Rename github_orchestration_id to actions_orchestration_id
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 17:20:43 +00:00
copilot-swe-agent[bot] 20596c1d96 Move hyphen to end of character class for cleaner regex
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 16:30:09 +00:00
copilot-swe-agent[bot] 557f80fd03 Fix regex to properly escape hyphen in character class
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 16:28:52 +00:00
copilot-swe-agent[bot] 32c52bb78a Use product/version format and sanitize orchestration ID
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 16:26:29 +00:00
copilot-swe-agent[bot] 6d9a3fe547 Format code and update .gitignore to exclude .nx cache
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 15:36:15 +00:00
copilot-swe-agent[bot] 4e1c194b34 Add ACTIONS_ORCHESTRATION_ID support to http-client user-agent
Co-authored-by: TingluoHuang <1750815+TingluoHuang@users.noreply.github.com>
2026-01-06 15:32:55 +00:00
copilot-swe-agent[bot] 09cb71a033 Initial plan 2026-01-06 15:22:42 +00:00
Salman Chishti 2506e78e82 Merge pull request #2212 from actions/artifact-v5.0.1-release
docs(artifact): release @actions/artifact v5.0.1
2025-12-12 15:39:59 +00:00
2 changed files with 80 additions and 3 deletions
+67 -2
View File
@@ -21,7 +21,10 @@ describe('basics', () => {
_http = new httpm.HttpClient('http-client-tests')
})
afterEach(() => {})
afterEach(() => {
// Clean up environment variable to prevent test pollution
delete process.env['ACTIONS_ORCHESTRATION_ID']
})
it('constructs', () => {
const http: httpm.HttpClient = new httpm.HttpClient('thttp-client-tests')
@@ -60,7 +63,7 @@ describe('basics', () => {
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.url).toBe('https://postman-echo.com/get')
expect(obj.headers['user-agent']).toBeFalsy()
expect(obj.headers['user-agent']).toBe('actions/http-client')
})
/* TODO write a mock rather then relying on a third party
@@ -374,4 +377,66 @@ describe('basics', () => {
httpm.MediaTypes.ApplicationJson
)
})
it('appends orchestration ID to user-agent when ACTIONS_ORCHESTRATION_ID is set', async () => {
const orchId = 'test-orch-id-12345'
process.env['ACTIONS_ORCHESTRATION_ID'] = orchId
const http: httpm.HttpClient = new httpm.HttpClient('http-client-tests')
const res: httpm.HttpClientResponse = await http.get(
'https://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.headers['user-agent']).toBe(
`http-client-tests actions_orchestration_id/${orchId}`
)
})
it('sanitizes invalid characters in orchestration ID', async () => {
const orchId = 'test (with) special/chars'
process.env['ACTIONS_ORCHESTRATION_ID'] = orchId
const http: httpm.HttpClient = new httpm.HttpClient('http-client-tests')
const res: httpm.HttpClientResponse = await http.get(
'https://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
// Spaces, parentheses, and slashes should be replaced with underscores
expect(obj.headers['user-agent']).toBe(
'http-client-tests actions_orchestration_id/test__with__special_chars'
)
})
it('does not modify user-agent when ACTIONS_ORCHESTRATION_ID is not set', async () => {
delete process.env['ACTIONS_ORCHESTRATION_ID']
const http: httpm.HttpClient = new httpm.HttpClient('http-client-tests')
const res: httpm.HttpClientResponse = await http.get(
'https://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.headers['user-agent']).toBe('http-client-tests')
})
it('uses default user-agent with orchestration ID when no custom user-agent provided', async () => {
const orchId = 'test-default-id-12345'
process.env['ACTIONS_ORCHESTRATION_ID'] = orchId
const http: httpm.HttpClient = new httpm.HttpClient()
const res: httpm.HttpClientResponse = await http.get(
'https://postman-echo.com/get'
)
expect(res.message.statusCode).toBe(200)
const body: string = await res.readBody()
const obj = JSON.parse(body)
expect(obj.headers['user-agent']).toBe(
`actions/http-client actions_orchestration_id/${orchId}`
)
})
})
+13 -1
View File
@@ -147,7 +147,7 @@ export class HttpClient {
handlers?: ifm.RequestHandler[],
requestOptions?: ifm.RequestOptions
) {
this.userAgent = userAgent
this.userAgent = this._getUserAgentWithOrchestrationId(userAgent)
this.handlers = handlers || []
this.requestOptions = requestOptions
if (requestOptions) {
@@ -816,6 +816,18 @@ export class HttpClient {
return proxyAgent
}
private _getUserAgentWithOrchestrationId(userAgent?: string): string {
const baseUserAgent = userAgent || 'actions/http-client'
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, '_')
return `${baseUserAgent} actions_orchestration_id/${sanitizedId}`
}
return baseUserAgent
}
private async _performExponentialBackoff(retryNumber: number): Promise<void> {
retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber)
const ms: number = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber)