Skip to content

Commit a2fd223

Browse files
committed
Properly clean up tmp files
1 parent 3ba8e1b commit a2fd223

File tree

4 files changed

+85
-5
lines changed

4 files changed

+85
-5
lines changed

__tests__/main.test.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,19 @@ vi.mock('fs', () => ({
7575
writeFileSync: mockWriteFileSync,
7676
}))
7777

78+
// Mocks for tmp module to control temporary file creation and cleanup
79+
const mockRemoveCallback = vi.fn()
80+
const mockFileSync = vi.fn().mockReturnValue({
81+
name: '/secure/temp/dir/modelResponse-abc123.txt',
82+
removeCallback: mockRemoveCallback,
83+
})
84+
const mockSetGracefulCleanup = vi.fn()
85+
86+
vi.mock('tmp', () => ({
87+
fileSync: mockFileSync,
88+
setGracefulCleanup: mockSetGracefulCleanup,
89+
}))
90+
7891
// Mock MCP and inference modules
7992
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8093
const mockConnectToGitHubMCP = vi.fn() as MockedFunction<any>
@@ -269,4 +282,43 @@ describe('main.ts', () => {
269282
expect(core.setFailed).toHaveBeenCalledWith(`File for prompt-file was not found: ${promptFile}`)
270283
expect(mockProcessExit).toHaveBeenCalledWith(1)
271284
})
285+
286+
it('creates secure temporary files with proper cleanup', async () => {
287+
mockInputs({
288+
prompt: 'Test prompt',
289+
'system-prompt': 'You are a test assistant.',
290+
})
291+
292+
await run()
293+
294+
expect(mockSetGracefulCleanup).toHaveBeenCalledOnce()
295+
296+
expect(mockFileSync).toHaveBeenCalledWith({
297+
prefix: 'modelResponse-',
298+
postfix: '.txt',
299+
})
300+
301+
expect(core.setOutput).toHaveBeenNthCalledWith(2, 'response-file', '/secure/temp/dir/modelResponse-abc123.txt')
302+
expect(mockWriteFileSync).toHaveBeenCalledWith('/secure/temp/dir/modelResponse-abc123.txt', 'Hello, user!', 'utf-8')
303+
expect(mockRemoveCallback).toHaveBeenCalledOnce()
304+
305+
expect(mockProcessExit).toHaveBeenCalledWith(0)
306+
})
307+
308+
it('handles cleanup errors gracefully', async () => {
309+
mockRemoveCallback.mockImplementationOnce(() => {
310+
throw new Error('Cleanup failed')
311+
})
312+
313+
mockInputs({
314+
prompt: 'Test prompt',
315+
'system-prompt': 'You are a test assistant.',
316+
})
317+
318+
await run()
319+
320+
expect(mockRemoveCallback).toHaveBeenCalledOnce()
321+
expect(core.warning).toHaveBeenCalledWith('Failed to cleanup temporary file: Error: Cleanup failed')
322+
expect(mockProcessExit).toHaveBeenCalledWith(0)
323+
})
272324
})

dist/index.js

Lines changed: 16 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ import {
1818
* @returns Resolves when the action is complete.
1919
*/
2020
export async function run(): Promise<void> {
21+
let responseFile: tmp.FileResult | null = null
22+
23+
// Set up graceful cleanup for temporary files on process exit
24+
tmp.setGracefulCleanup()
25+
2126
try {
2227
const promptFilePath = core.getInput('prompt-file')
2328
const inputVariables = core.getInput('input')
@@ -91,10 +96,9 @@ export async function run(): Promise<void> {
9196
core.setOutput('response', modelResponse || '')
9297

9398
// Create a secure temporary file instead of using the temp directory directly
94-
const responseFile = tmp.fileSync({
99+
responseFile = tmp.fileSync({
95100
prefix: 'modelResponse-',
96101
postfix: '.txt',
97-
keep: true, // Keep the file so the action can read it
98102
})
99103

100104
core.setOutput('response-file', responseFile.name)
@@ -110,6 +114,16 @@ export async function run(): Promise<void> {
110114
}
111115
// Force exit to prevent hanging on open connections
112116
process.exit(1)
117+
} finally {
118+
// Explicit cleanup of temporary file if it was created
119+
if (responseFile) {
120+
try {
121+
responseFile.removeCallback()
122+
} catch (cleanupError) {
123+
// Log cleanup errors but don't fail the action
124+
core.warning(`Failed to cleanup temporary file: ${cleanupError}`)
125+
}
126+
}
113127
}
114128

115129
// Force exit to prevent hanging on open connections

0 commit comments

Comments
 (0)