Skip to content

Commit 2163cb8

Browse files
authored
Refactor Docker Compose teardown into a shared helper (#3564)
* Initial plan * refactor: share compose down helper --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
1 parent c52e9fb commit 2163cb8

3 files changed

Lines changed: 24 additions & 13 deletions

File tree

src/container-cleanup.ts

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,22 @@ export async function collectDiagnosticLogs(workDir: string): Promise<void> {
172172
logger.info(`Diagnostic logs collected at: ${diagnosticsDir}`);
173173
}
174174

175+
/**
176+
* Runs `docker compose down -v -t 1` with the standard AWF options.
177+
*/
178+
export async function runComposeDown(
179+
workDir: string,
180+
options: { reject?: boolean } = {},
181+
): Promise<void> {
182+
await execa('docker', ['compose', 'down', '-v', '-t', '1'], {
183+
cwd: workDir,
184+
stdout: process.stderr,
185+
stderr: 'inherit',
186+
env: getLocalDockerEnv(),
187+
reject: options.reject ?? true,
188+
});
189+
}
190+
175191
/**
176192
* Stops and removes Docker Compose services
177193
*/
@@ -184,12 +200,7 @@ export async function stopContainers(workDir: string, keepContainers: boolean):
184200
logger.info('Stopping containers...');
185201

186202
try {
187-
await execa('docker', ['compose', 'down', '-v', '-t', '1'], {
188-
cwd: workDir,
189-
stdout: process.stderr,
190-
stderr: 'inherit',
191-
env: getLocalDockerEnv(),
192-
});
203+
await runComposeDown(workDir);
193204
logger.success('Containers stopped successfully');
194205
} catch (error) {
195206
logger.error('Failed to stop containers:', error);

src/container-lifecycle.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import execa from 'execa';
44
import { BlockedTarget } from './types';
55
import { logger } from './logger';
66
import { parseDomainWithProtocol, isWildcardPattern, wildcardToRegex } from './domain-patterns';
7+
import { runComposeDown } from './container-cleanup';
78
import {
89
AGENT_CONTAINER_NAME,
910
SQUID_CONTAINER_NAME,
@@ -218,13 +219,7 @@ export async function startContainers(workDir: string, allowedDomains: string[],
218219

219220
// Tear down before retry so Docker Compose starts fresh
220221
try {
221-
await execa('docker', ['compose', 'down', '-v', '-t', '1'], {
222-
cwd: workDir,
223-
stdout: process.stderr,
224-
stderr: 'inherit',
225-
env: getLocalDockerEnv(),
226-
reject: false,
227-
});
222+
await runComposeDown(workDir, { reject: false });
228223
} catch (cleanupError) {
229224
// Best-effort cleanup — proceed with retry regardless
230225
logger.debug('Cleanup before retry failed (proceeding anyway):', cleanupError);

src/docker-manager-lifecycle.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,11 @@ describe('docker-manager lifecycle', () => {
137137
call[0] === 'docker' && Array.isArray(call[1]) && call[1].includes('up')
138138
);
139139
expect(upCalls).toHaveLength(2);
140+
expect(mockExecaFn).toHaveBeenCalledWith(
141+
'docker',
142+
['compose', 'down', '-v', '-t', '1'],
143+
expect.objectContaining({ cwd: testDir, stdout: process.stderr, stderr: 'inherit', reject: false })
144+
);
140145
});
141146

142147
it('should retry once when awf-api-proxy exits during startup', async () => {

0 commit comments

Comments
 (0)