Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b08f07cd3 | ||
|
|
d26e9423f4 | ||
|
|
714f93aedc | ||
|
|
844423665b | ||
|
|
f2ba502b92 | ||
|
|
1db3130eb3 | ||
|
|
ca8a35d78f | ||
|
|
f7f057193f | ||
|
|
8e146e124e | ||
|
|
1ea77a84d7 | ||
|
|
7da95b182e | ||
|
|
7c689a5156 | ||
|
|
8c6c662cda | ||
|
|
3898ed70c4 | ||
|
|
523ce8ccda |
@@ -0,0 +1,27 @@
|
|||||||
|
# To get started with Dependabot version updates, you'll need to specify which
|
||||||
|
# package ecosystems to update and where the package manifests are located.
|
||||||
|
# Please see the documentation for all configuration options:
|
||||||
|
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||||
|
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "npm"
|
||||||
|
directory: "/packages/artifact"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
groups:
|
||||||
|
# Group minor and patch updates together but keep major separate
|
||||||
|
artifact-minor-patch:
|
||||||
|
update-types:
|
||||||
|
- "minor"
|
||||||
|
- "patch"
|
||||||
|
- package-ecosystem: "npm"
|
||||||
|
directory: "/packages/cache"
|
||||||
|
schedule:
|
||||||
|
interval: "daily"
|
||||||
|
groups:
|
||||||
|
# Group minor and patch updates together but keep major separate
|
||||||
|
cache-minor-patch:
|
||||||
|
update-types:
|
||||||
|
- "minor"
|
||||||
|
- "patch"
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
import * as config from '../src/internal/shared/config'
|
import * as config from '../src/internal/shared/config'
|
||||||
import os from 'os'
|
import os from 'os'
|
||||||
|
|
||||||
// Mock the 'os' module
|
// Mock the `cpus()` function in the `os` module
|
||||||
jest.mock('os', () => ({
|
jest.mock('os', () => {
|
||||||
cpus: jest.fn()
|
const osActual = jest.requireActual('os')
|
||||||
}))
|
return {
|
||||||
|
...osActual,
|
||||||
|
cpus: jest.fn()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.resetModules()
|
jest.resetModules()
|
||||||
|
|||||||
@@ -111,6 +111,16 @@ const mockGetArtifactSuccess = jest.fn(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const mockGetArtifactHung = jest.fn(() => {
|
||||||
|
const message = new http.IncomingMessage(new net.Socket())
|
||||||
|
message.statusCode = 200
|
||||||
|
// Don't push any data or call push(null) to end the stream
|
||||||
|
// This creates a stream that hangs and never completes
|
||||||
|
return {
|
||||||
|
message
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const mockGetArtifactFailure = jest.fn(() => {
|
const mockGetArtifactFailure = jest.fn(() => {
|
||||||
const message = new http.IncomingMessage(new net.Socket())
|
const message = new http.IncomingMessage(new net.Socket())
|
||||||
message.statusCode = 500
|
message.statusCode = 500
|
||||||
@@ -611,4 +621,32 @@ describe('download-artifact', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('streamExtractExternal', () => {
|
||||||
|
it('should fail if the timeout is exceeded', async () => {
|
||||||
|
const mockSlowGetArtifact = jest.fn(mockGetArtifactHung)
|
||||||
|
|
||||||
|
const mockHttpClient = (HttpClient as jest.Mock).mockImplementation(
|
||||||
|
() => {
|
||||||
|
return {
|
||||||
|
get: mockSlowGetArtifact
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
await streamExtractExternal(
|
||||||
|
fixtures.blobStorageUrl,
|
||||||
|
fixtures.workspaceDir,
|
||||||
|
{timeout: 2}
|
||||||
|
)
|
||||||
|
expect(true).toBe(false) // should not be called
|
||||||
|
} catch (e) {
|
||||||
|
expect(e).toBeInstanceOf(Error)
|
||||||
|
expect(e.message).toContain('did not respond in 2ms')
|
||||||
|
expect(mockHttpClient).toHaveBeenCalledWith(getUserAgentString())
|
||||||
|
expect(mockSlowGetArtifact).toHaveBeenCalledTimes(1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Generated
+1116
-501
File diff suppressed because it is too large
Load Diff
@@ -43,6 +43,7 @@
|
|||||||
"@actions/core": "^1.10.0",
|
"@actions/core": "^1.10.0",
|
||||||
"@actions/github": "^6.0.1",
|
"@actions/github": "^6.0.1",
|
||||||
"@actions/http-client": "^2.1.0",
|
"@actions/http-client": "^2.1.0",
|
||||||
|
"@azure/core-http": "^3.0.5",
|
||||||
"@azure/storage-blob": "^12.15.0",
|
"@azure/storage-blob": "^12.15.0",
|
||||||
"@octokit/core": "^5.2.1",
|
"@octokit/core": "^5.2.1",
|
||||||
"@octokit/plugin-request-log": "^1.0.4",
|
"@octokit/plugin-request-log": "^1.0.4",
|
||||||
@@ -57,7 +58,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/archiver": "^5.3.2",
|
"@types/archiver": "^5.3.2",
|
||||||
"@types/unzip-stream": "^0.3.4",
|
"@types/unzip-stream": "^0.3.4",
|
||||||
"typedoc": "^0.25.4",
|
"typedoc": "^0.28.13",
|
||||||
"typedoc-plugin-markdown": "^3.17.1",
|
"typedoc-plugin-markdown": "^3.17.1",
|
||||||
"typescript": "^5.2.2"
|
"typescript": "^5.2.2"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ async function streamExtract(
|
|||||||
|
|
||||||
export async function streamExtractExternal(
|
export async function streamExtractExternal(
|
||||||
url: string,
|
url: string,
|
||||||
directory: string
|
directory: string,
|
||||||
|
opts: {timeout: number} = {timeout: 30 * 1000}
|
||||||
): Promise<StreamExtractResponse> {
|
): Promise<StreamExtractResponse> {
|
||||||
const client = new httpClient.HttpClient(getUserAgentString())
|
const client = new httpClient.HttpClient(getUserAgentString())
|
||||||
const response = await client.get(url)
|
const response = await client.get(url)
|
||||||
@@ -74,16 +75,17 @@ export async function streamExtractExternal(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const timeout = 30 * 1000 // 30 seconds
|
|
||||||
let sha256Digest: string | undefined = undefined
|
let sha256Digest: string | undefined = undefined
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const timerFn = (): void => {
|
const timerFn = (): void => {
|
||||||
response.message.destroy(
|
const timeoutError = new Error(
|
||||||
new Error(`Blob storage chunk did not respond in ${timeout}ms`)
|
`Blob storage chunk did not respond in ${opts.timeout}ms`
|
||||||
)
|
)
|
||||||
|
response.message.destroy(timeoutError)
|
||||||
|
reject(timeoutError)
|
||||||
}
|
}
|
||||||
const timer = setTimeout(timerFn, timeout)
|
const timer = setTimeout(timerFn, opts.timeout)
|
||||||
|
|
||||||
const hashStream = crypto.createHash('sha256').setEncoding('hex')
|
const hashStream = crypto.createHash('sha256').setEncoding('hex')
|
||||||
const passThrough = new stream.PassThrough()
|
const passThrough = new stream.PassThrough()
|
||||||
|
|||||||
Reference in New Issue
Block a user