源码快照 @ 2026-09-02 (source-only, 剔除非源码素材)
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
import { readFile, writeFile } from "node:fs/promises";
|
||||
import { resolve } from "node:path";
|
||||
import { parseArgs } from "node:util";
|
||||
|
||||
import {
|
||||
deleteSandboxes,
|
||||
parseConnectorE2eTestEnv,
|
||||
provisionDenSandbox,
|
||||
provisionDesktopSandbox,
|
||||
renderConnectorE2eTestEnv,
|
||||
startMockOnSandbox,
|
||||
} from "@openwork/hosts";
|
||||
import type { DesktopSandbox } from "@openwork/hosts";
|
||||
|
||||
const USAGE = `Usage:
|
||||
node scripts/provision-org-connector-two-members.ts --ref <branch-or-commit> [--reuse-a <id>] [--reuse-b <id>] [--reuse-den <id>] [--out org-connector-two-members.env]
|
||||
node scripts/provision-org-connector-two-members.ts --delete <envfile>
|
||||
node scripts/provision-org-connector-two-members.ts --help`;
|
||||
|
||||
function prefixed(prefix: string, observe?: (line: string) => void): (line: string) => void {
|
||||
return (line) => {
|
||||
observe?.(line);
|
||||
console.error(`[${prefix}] ${line}`);
|
||||
};
|
||||
}
|
||||
|
||||
async function deleteProvisioned(envFile: string): Promise<void> {
|
||||
const facts = parseConnectorE2eTestEnv(await readFile(envFile, "utf8"));
|
||||
await deleteSandboxes(facts.created);
|
||||
const created = new Set(facts.created);
|
||||
const leftAlone = [facts.sandboxA, facts.sandboxB].filter((sandbox) => !created.has(sandbox));
|
||||
console.log(`Deleted: ${facts.created.join(", ") || "(none)"}`);
|
||||
console.log(`Left alone: ${leftAlone.join(", ") || "(none recorded)"}`);
|
||||
}
|
||||
|
||||
async function provisionSpecEnv(options: {
|
||||
ref: string;
|
||||
reuseA?: string;
|
||||
reuseB?: string;
|
||||
reuseDen?: string;
|
||||
out: string;
|
||||
}): Promise<void> {
|
||||
const created: string[] = [];
|
||||
function recordCreated(sandbox: string): void {
|
||||
if (!created.includes(sandbox)) created.push(sandbox);
|
||||
}
|
||||
try {
|
||||
const denLog = prefixed("den", (line) => {
|
||||
const match = /Creating server sandbox:\s*(\S+)/.exec(line);
|
||||
if (match?.[1]) recordCreated(match[1]);
|
||||
});
|
||||
const den = await provisionDenSandbox({ ref: options.ref, reuse: options.reuseDen, log: denLog });
|
||||
if (den.created) recordCreated(den.sandbox);
|
||||
|
||||
const mock = await startMockOnSandbox({ sandbox: den.sandbox, log: prefixed("mock") });
|
||||
async function desktop(name: "a" | "b", reuse: string | undefined): Promise<DesktopSandbox> {
|
||||
const desktopLog = prefixed(name, (line) => {
|
||||
const match = /desktop sandbox created:\s*(\S+)/.exec(line);
|
||||
if (match?.[1]) recordCreated(match[1]);
|
||||
});
|
||||
const result = await provisionDesktopSandbox({ ref: options.ref, name, reuse, log: desktopLog });
|
||||
if (result.created) recordCreated(result.sandbox);
|
||||
return result;
|
||||
}
|
||||
const [desktopA, desktopB] = await Promise.all([
|
||||
desktop("a", options.reuseA),
|
||||
desktop("b", options.reuseB),
|
||||
]);
|
||||
|
||||
await writeFile(options.out, renderConnectorE2eTestEnv({
|
||||
denApiUrl: den.apiUrl,
|
||||
denWebUrl: den.webUrl,
|
||||
sandboxA: desktopA.sandbox,
|
||||
sandboxB: desktopB.sandbox,
|
||||
mockUrl: mock.url,
|
||||
ref: options.ref,
|
||||
created,
|
||||
}), "utf8");
|
||||
|
||||
console.log(`Wrote ${resolve(options.out)}`);
|
||||
console.log(`set -a; source ${options.out}; set +a`);
|
||||
console.log("pnpm --dir evals exec vitest run --config vitest.config.ts --project e2e specs/org-connector-two-members.e2e.test.ts");
|
||||
console.log(`node scripts/provision-org-connector-two-members.ts --delete ${options.out}`);
|
||||
} catch (error) {
|
||||
console.error(`Provisioning failed. Provision-created sandboxes so far: ${created.join(", ") || "(none)"}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function main(argv: string[]): Promise<void> {
|
||||
const { values } = parseArgs({
|
||||
args: argv,
|
||||
options: {
|
||||
ref: { type: "string" },
|
||||
"reuse-a": { type: "string" },
|
||||
"reuse-b": { type: "string" },
|
||||
"reuse-den": { type: "string" },
|
||||
out: { type: "string" },
|
||||
delete: { type: "string" },
|
||||
help: { type: "boolean", short: "h" },
|
||||
},
|
||||
strict: true,
|
||||
allowPositionals: false,
|
||||
});
|
||||
|
||||
if (values.help) {
|
||||
console.log(USAGE);
|
||||
return;
|
||||
}
|
||||
if (values.delete) {
|
||||
await deleteProvisioned(values.delete);
|
||||
return;
|
||||
}
|
||||
if (!values.ref) throw new Error(`--ref is required.\n\n${USAGE}`);
|
||||
await provisionSpecEnv({
|
||||
ref: values.ref,
|
||||
reuseA: values["reuse-a"],
|
||||
reuseB: values["reuse-b"],
|
||||
reuseDen: values["reuse-den"],
|
||||
out: values.out ?? "org-connector-two-members.env",
|
||||
});
|
||||
}
|
||||
|
||||
main(process.argv.slice(2)).catch((error: unknown) => {
|
||||
console.error(error instanceof Error ? error.message : String(error));
|
||||
process.exitCode = 1;
|
||||
});
|
||||
Reference in New Issue
Block a user