Force exit once inference finishes in case we are holding any connections open

This commit is contained in:
Sean Goedecke
2025-08-05 21:42:07 +00:00
parent 0cbed4a106
commit 4685e0dcd4
5 changed files with 32 additions and 7 deletions

View File

@@ -34,6 +34,12 @@ vi.mock('../src/mcp.js', () => ({
vi.mock('@actions/core', () => core)
// Mock process.exit to prevent it from actually exiting during tests
const mockProcessExit = vi.spyOn(process, 'exit').mockImplementation(() => {
// Prevent actual exit, but don't throw - just return
return undefined as never
})
// The module being tested should be imported dynamically. This ensures that the
// mocks are used in place of any actual dependencies.
const {run} = await import('../src/main.js')
@@ -41,6 +47,7 @@ const {run} = await import('../src/main.js')
describe('main.ts - prompt.yml integration', () => {
beforeEach(() => {
vi.clearAllMocks()
mockProcessExit.mockClear()
// Mock environment variables
process.env['GITHUB_TOKEN'] = 'test-token'
@@ -103,8 +110,12 @@ model: openai/gpt-4o
}
})
// Expect the run function to complete successfully
await run()
// Verify process.exit was called with code 0 (success)
expect(mockProcessExit).toHaveBeenCalledWith(0)
// Verify simpleInference was called with the correct message structure
expect(mockSimpleInference).toHaveBeenCalledWith(
expect.objectContaining({
@@ -171,6 +182,9 @@ model: openai/gpt-4o
messages: [{role: 'user', content: 'Here is the data: FILE_CONTENTS'}],
}),
)
// Verify process.exit was called with code 0 (success)
expect(mockProcessExit).toHaveBeenCalledWith(0)
})
it('should fall back to legacy format when not using prompt YAML', async () => {
@@ -215,5 +229,8 @@ model: openai/gpt-4o
token: 'test-token',
}),
)
// Verify process.exit was called with code 0 (success)
expect(mockProcessExit).toHaveBeenCalledWith(0)
})
})

View File

@@ -96,7 +96,8 @@ vi.mock('@actions/core', () => core)
// Mock process.exit to prevent it from actually exiting during tests
const mockProcessExit = vi.spyOn(process, 'exit').mockImplementation(() => {
throw new Error('process.exit called')
// Prevent actual exit, but don't throw - just return
return undefined as never
})
// The module being tested should be imported dynamically. This ensures that the
@@ -127,6 +128,7 @@ describe('main.ts', () => {
expect(core.setOutput).toHaveBeenCalled()
verifyStandardResponse()
expect(mockProcessExit).toHaveBeenCalledWith(0)
})
it('Sets a failed status when no prompt is set', async () => {
@@ -135,8 +137,7 @@ describe('main.ts', () => {
'prompt-file': '',
})
// Expect the run function to throw due to process.exit being mocked
await expect(run()).rejects.toThrow('process.exit called')
await run()
expect(core.setFailed).toHaveBeenCalledWith('Neither prompt-file nor prompt was set')
expect(mockProcessExit).toHaveBeenCalledWith(1)
@@ -165,6 +166,7 @@ describe('main.ts', () => {
expect(mockConnectToGitHubMCP).not.toHaveBeenCalled()
expect(mockMcpInference).not.toHaveBeenCalled()
verifyStandardResponse()
expect(mockProcessExit).toHaveBeenCalledWith(0)
})
it('uses MCP inference when enabled and connection succeeds', async () => {
@@ -197,6 +199,7 @@ describe('main.ts', () => {
)
expect(mockSimpleInference).not.toHaveBeenCalled()
verifyStandardResponse()
expect(mockProcessExit).toHaveBeenCalledWith(0)
})
it('falls back to simple inference when MCP connection fails', async () => {
@@ -215,6 +218,7 @@ describe('main.ts', () => {
expect(mockMcpInference).not.toHaveBeenCalled()
expect(core.warning).toHaveBeenCalledWith('MCP connection failed, falling back to simple inference')
verifyStandardResponse()
expect(mockProcessExit).toHaveBeenCalledWith(0)
})
it('properly integrates with loadContentFromFileOrInput', async () => {
@@ -248,6 +252,7 @@ describe('main.ts', () => {
responseFormat: undefined,
})
verifyStandardResponse()
expect(mockProcessExit).toHaveBeenCalledWith(0)
})
it('handles non-existent prompt-file with an error', async () => {
@@ -259,8 +264,7 @@ describe('main.ts', () => {
'prompt-file': promptFile,
})
// Expect the run function to throw due to process.exit being mocked
await expect(run()).rejects.toThrow('process.exit called')
await run()
expect(core.setFailed).toHaveBeenCalledWith(`File for prompt-file was not found: ${promptFile}`)
expect(mockProcessExit).toHaveBeenCalledWith(1)

2
dist/index.js generated vendored
View File

@@ -51790,6 +51790,8 @@ async function run() {
// Force exit to prevent hanging on open connections
process.exit(1);
}
// Force exit to prevent hanging on open connections
process.exit(0);
}
function tempDir() {
const tempDirectory = process.env['RUNNER_TEMP'] || require$$0.tmpdir();

2
dist/index.js.map generated vendored

File diff suppressed because one or more lines are too long

View File

@@ -105,10 +105,12 @@ export async function run(): Promise<void> {
} else {
core.setFailed(`An unexpected error occurred: ${JSON.stringify(error, null, 2)}`)
}
// Force exit to prevent hanging on open connections
process.exit(1)
}
// Force exit to prevent hanging on open connections
process.exit(0)
}
function tempDir(): string {