ci: Replace start-sandbox.ts with pnpm services --network (#31379)

This commit is contained in:
Tomi Turtiainen 2026-06-01 21:48:45 +03:00 committed by GitHub
parent 2e683ffc0f
commit 3c61c305e0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 22 additions and 59 deletions

View File

@ -74,7 +74,7 @@ jobs:
- name: Start sandbox service
if: ${{ inputs.sandbox-provider == 'n8n-sandbox' }}
run: pnpm tsx packages/testing/containers/start-sandbox.ts --network n8n-eval-net
run: pnpm --filter n8n-containers services --services sandbox --network n8n-eval-net --name n8n-svc-sandbox
- name: Start n8n containers
env:
@ -284,14 +284,13 @@ jobs:
done
# Sandbox service container logs (when using n8n-sandbox provider)
for c in sandbox-api sandbox-runner-1; do
if docker ps -aq --filter "name=$c" | grep -q .; then
echo ""
echo "============================================================"
echo "=== $c (last 100 lines) ==="
echo "============================================================"
docker logs "$c" 2>&1 | tail -100 || true
fi
for c in $(docker ps -aq --filter "label=com.docker.compose.project=n8n-svc-sandbox"); do
name=$(docker inspect --format '{{.Name}}' "$c" | sed 's|^/||')
echo ""
echo "============================================================"
echo "=== $name (last 100 lines) ==="
echo "============================================================"
docker logs "$c" 2>&1 | tail -100 || true
done
- name: Stop n8n containers
@ -302,9 +301,8 @@ jobs:
docker stop "${ids[@]}" 2>/dev/null || true
docker rm "${ids[@]}" 2>/dev/null || true
fi
# Sandbox service cleanup (safe even if containers don't exist)
docker stop sandbox-runner-1 sandbox-api 2>/dev/null || true
docker rm sandbox-runner-1 sandbox-api 2>/dev/null || true
# Sandbox service cleanup
pnpm --filter n8n-containers services:clean 2>/dev/null || true
docker network rm n8n-eval-net 2>/dev/null || true
- name: Post eval results to PR

View File

@ -63,6 +63,7 @@ ${colors.yellow}Options:${colors.reset}
--mains <n> Number of main instances (default: 1)
--workers <n> Number of worker instances (default: 1)
--name <name> Project name for parallel runs
--network <name> Docker network name (default: auto-generated)
--env KEY=VALUE Set environment variables
--plan <plan> Use performance plan preset (${Object.keys(BASE_PERFORMANCE_PLANS).join(', ')})
--help, -h Show this help
@ -154,6 +155,7 @@ async function main() {
mains: { type: 'string' },
workers: { type: 'string' },
name: { type: 'string' },
network: { type: 'string' },
env: { type: 'string', multiple: true },
plan: { type: 'string' },
},
@ -199,6 +201,7 @@ async function main() {
(servicesOnly
? `n8n-svc-${Math.random().toString(36).substring(7)}`
: `n8n-stack-${Math.random().toString(36).substring(7)}`),
networkName: values.network,
};
// Handle queue mode (mains > 1 or workers > 0)
@ -273,6 +276,7 @@ async function main() {
const stack = await createServiceStack({
services,
projectName: config.projectName,
networkName: config.networkName,
});
const envVars = writeDevEnvFile(stack, services);

View File

@ -8,6 +8,7 @@ import { createN8NStack, type N8NStack } from './stack';
export interface ServiceStackOptions {
services: ServiceName[];
projectName?: string;
networkName?: string;
}
/**
@ -22,7 +23,7 @@ export interface ServiceStackOptions {
* await stack.stop();
*/
export async function createServiceStack(options: ServiceStackOptions): Promise<N8NStack> {
const { services, projectName } = options;
const { services, projectName, networkName } = options;
return await createN8NStack({
mains: 0,
@ -30,6 +31,7 @@ export async function createServiceStack(options: ServiceStackOptions): Promise<
postgres: services.includes('postgres'),
services,
projectName,
networkName,
external: true,
});
}

View File

@ -77,6 +77,8 @@ export interface StackConfig {
services?: readonly ServiceName[];
/** When true, services target host machine instead of Docker-internal n8n */
external?: boolean;
/** When set, the Docker network uses this exact name instead of a random UUID. */
networkName?: string;
/**
* Caddy load-balancer upstream-selection policy. Only applies when `mains > 1`.
* Defaults to `'first'` sticky to main #1, useful for UI debuggability.

View File

@ -86,6 +86,7 @@ export async function createN8NStack(config: N8NConfig = {}): Promise<N8NStack>
workerResourceQuota,
services: enabledServices = [],
external = false,
networkName,
} = config;
const log = createElapsedLogger('stack');
@ -115,7 +116,8 @@ export async function createN8NStack(config: N8NConfig = {}): Promise<N8NStack>
let network: StartedNetwork;
try {
const networkStart = performance.now();
network = await new Network().start();
const uuid = networkName ? { nextUuid: () => networkName } : undefined;
network = await new Network(uuid).start();
telemetry.recordNetwork(Math.round(performance.now() - networkStart));
} catch (error) {
const message = error instanceof Error ? error.message : String(error);

View File

@ -1,45 +0,0 @@
#!/usr/bin/env tsx
/**
* Standalone script to start the n8n sandbox service (API + runner) using the
* testcontainers-based sandbox service definition. Creates a named Docker
* network so that separately-started n8n containers can join it.
*
* Usage: pnpm tsx packages/testing/containers/start-sandbox.ts [--network <name>]
*/
import { parseArgs } from 'node:util';
import { Network } from 'testcontainers';
import type { Uuid } from 'testcontainers';
import { sandbox } from './services/sandbox';
const { values } = parseArgs({
options: { network: { type: 'string', default: 'n8n-eval-net' } },
strict: false,
});
const networkName = values.network ?? 'n8n-eval-net';
const projectName = 'n8n-sandbox-ci';
class FixedName implements Uuid {
constructor(private readonly name: string) {}
nextUuid() {
return this.name;
}
}
async function main() {
console.log(`Creating network "${networkName}"...`);
const network = await new Network(new FixedName(networkName)).start();
console.log('Starting sandbox service...');
const result = await sandbox.start(network, projectName);
console.log(`Sandbox API URL: ${result.meta.apiUrl}`);
console.log(`Network: ${network.getName()}`);
console.log('Sandbox service is ready');
}
main().catch((error) => {
console.error(error);
process.exit(1);
});