Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions containers/api-proxy/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ USER apiproxy
# 10004 - OpenCode API proxy (routes to Anthropic)
EXPOSE 10000 10001 10002 10004

# Redirect stdout/stderr to log file for persistence
# Use shell form to enable redirection and tee for both file and console
CMD node server.js 2>&1 | tee -a /var/log/api-proxy/api-proxy.log
# Use exec form so Node.js is PID 1 and receives SIGTERM directly
# Docker captures stdout/stderr automatically, no need for manual log redirection
CMD ["node", "server.js"]
Comment on lines +33 to +35
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switching api-proxy to exec-form CMD fixes signal handling, but it also removes the tee pipeline that persisted stdout/stderr into the mounted /var/log/api-proxy volume. The container’s logging.js explicitly relies on tee for file persistence, and src/docker-manager.ts mounts/creates api-proxy-logs expecting files there. Consider preserving file-based logs by writing directly to /var/log/api-proxy/api-proxy.log from Node (while keeping exec form), or update the volume mount / log-preservation logic to use docker logs instead so troubleshooting/artifact collection doesn’t regress.

Copilot uses AI. Check for mistakes.
16 changes: 16 additions & 0 deletions scripts/ci/postprocess-smoke-workflows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ const shallowDepthRegex = /^(\s+)depth: 1\n/gm;
// instead of pre-built GHCR images that may be stale.
const imageTagRegex = /--image-tag\s+[0-9.]+\s+--skip-pull/g;

// Add --skip-cleanup after sudo -E awf to skip container shutdown in CI
// (saves ~10 seconds per run since containers are cleaned up when runner terminates)
// Match patterns:
// - sudo -E awf --<flag> ... (with any flags after awf except --skip-cleanup which may already exist)
// - sudo -E awf "$command" (when command is directly after awf)
// Strategy: Insert --skip-cleanup right after "awf " if not already present
const awfCleanupRegex = /sudo -E awf (?!.*--skip-cleanup)/g;

for (const workflowPath of workflowPaths) {
Comment on lines +97 to 105
Copy link

Copilot AI Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description says the postprocess script removes a non-existent pelis-agent-factory-advisor.lock.yml reference, but workflowPaths still includes it (and the file exists in .github/workflows/). Please clarify whether that description bullet is outdated or if the script/workflow list should be updated accordingly.

Copilot uses AI. Check for mistakes.
let content = fs.readFileSync(workflowPath, 'utf-8');
let modified = false;
Expand Down Expand Up @@ -139,6 +147,14 @@ for (const workflowPath of workflowPaths) {
console.log(` Replaced ${imageTagMatches.length} --image-tag/--skip-pull with --build-local`);
}

// Add --skip-cleanup to all awf invocations (saves ~10s per run in CI)
const awfCleanupMatches = content.match(awfCleanupRegex);
if (awfCleanupMatches) {
content = content.replace(awfCleanupRegex, 'sudo -E awf --skip-cleanup ');
modified = true;
console.log(` Added --skip-cleanup to ${awfCleanupMatches.length} awf invocation(s)`);
}

if (modified) {
fs.writeFileSync(workflowPath, content);
console.log(`Updated ${workflowPath}`);
Expand Down
12 changes: 12 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,11 @@ program
'Keep containers running after command exits',
false
)
.option(
'--skip-cleanup',
'Skip all cleanup (containers, iptables, work dir) - useful in CI where runner terminates anyway',
false
)
.option(
'--tty',
'Allocate a pseudo-TTY for the container (required for interactive tools like Claude Code)',
Expand Down Expand Up @@ -1062,6 +1067,7 @@ program
agentCommand,
logLevel,
keepContainers: options.keepContainers,
skipCleanup: options.skipCleanup,
tty: options.tty || false,
workDir: options.workDir,
buildLocal: options.buildLocal,
Expand Down Expand Up @@ -1180,6 +1186,12 @@ program
logger.info(`Received ${signal}, cleaning up...`);
}

// Skip all cleanup if requested (useful in CI where runner terminates anyway)
if (config.skipCleanup) {
logger.info('Skipping cleanup (--skip-cleanup enabled)');
return;
}

if (containersStarted) {
await stopContainers(config.workDir, config.keepContainers);
}
Expand Down
17 changes: 17 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,23 @@ export interface WrapperConfig {
*/
keepContainers: boolean;

/**
* Whether to skip cleanup when the process exits
*
* When true:
* - Containers are not stopped (left running or stopped by Docker daemon)
* - Host iptables rules are not cleaned up
* - Work directory is not deleted
* - Useful in CI environments where the runner will terminate anyway,
* saving ~10 seconds of shutdown time
*
* This is a stronger version of keepContainers that also skips all cleanup
* operations, not just container removal.
*
* @default false
*/
skipCleanup?: boolean;

/**
* Whether to allocate a pseudo-TTY for the agent execution container
*
Expand Down
Loading