Skip to content

Commit bd2edec

Browse files
committed
CLI DX: preview auto-deploys on anvil when manifest is 0x0
1 parent 1b28542 commit bd2edec

1 file changed

Lines changed: 52 additions & 5 deletions

File tree

packages/cli/src/index.ts

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1585,16 +1585,63 @@ program
15851585
.description('Serve the generated static UI locally (no Python required)')
15861586
.option('--port <n>', 'Port to listen on', '3000')
15871587
.option('--host <host>', 'Host to bind (default: 127.0.0.1)', '127.0.0.1')
1588-
.action((buildDir: string, opts: { port: string; host: string }) => {
1588+
.option('--no-deploy', 'Do not auto-deploy when the manifest has a placeholder 0x0 address')
1589+
.option('--no-start-anvil', 'Do not start anvil automatically (anvil chain only)')
1590+
.action(async (buildDir: string, opts: { port: string; host: string; deploy: boolean; startAnvil: boolean }) => {
1591+
let anvilChild: ReturnType<typeof spawn> | null = null;
15891592
try {
1593+
const resolvedBuildDir = path.resolve(buildDir);
1594+
const manifestPath = path.join(resolvedBuildDir, 'manifest.json');
1595+
const zeroAddress = '0x0000000000000000000000000000000000000000';
1596+
1597+
// If the manifest is still at the placeholder address, auto-deploy on anvil by default.
1598+
if (opts.deploy && fs.existsSync(manifestPath)) {
1599+
const manifest = readJsonFile(manifestPath) as any;
1600+
const deployments = Array.isArray(manifest?.deployments) ? manifest.deployments : [];
1601+
const d = deployments.find((x: any) => x && x.role === 'primary') ?? deployments[0] ?? null;
1602+
const addr = String(d?.deploymentEntrypointAddress ?? '');
1603+
const chainId = Number(d?.chainId ?? NaN);
1604+
1605+
if (addr && addr.toLowerCase() === zeroAddress && Number.isFinite(chainId)) {
1606+
const chainNameFromId = chainId === anvil.id ? ('anvil' as const) : chainId === sepolia.id ? ('sepolia' as const) : null;
1607+
if (chainNameFromId === 'anvil') {
1608+
const { chainName, chain } = resolveKnownChain('anvil');
1609+
const rpcUrl = resolveRpcUrl(chainName, chain, undefined);
1610+
console.log(`Manifest is not deployed (0x0). Deploying automatically to ${chainName}...`);
1611+
const ensured = await ensureAnvilRunning(rpcUrl, { start: Boolean(opts.startAnvil), expectedChainId: chain.id });
1612+
anvilChild = ensured.child;
1613+
await deployBuildDir(resolvedBuildDir, { chain: 'anvil', role: 'primary' });
1614+
console.log('Auto-deploy complete.');
1615+
console.log('');
1616+
}
1617+
}
1618+
}
1619+
15901620
const port = Number(opts.port);
1591-
const { server } = startUiSiteServer({ buildDir, host: opts.host, port });
1592-
process.on('SIGINT', () => {
1593-
server.close(() => process.exit(0));
1594-
});
1621+
const { server } = startUiSiteServer({ buildDir: resolvedBuildDir, host: opts.host, port });
1622+
1623+
const cleanup = () => {
1624+
try {
1625+
server.close(() => {});
1626+
} catch {}
1627+
if (anvilChild) {
1628+
try {
1629+
anvilChild.kill('SIGTERM');
1630+
} catch {}
1631+
}
1632+
process.exit(0);
1633+
};
1634+
1635+
process.on('SIGINT', cleanup);
1636+
process.on('SIGTERM', cleanup);
15951637
} catch (e: any) {
15961638
console.error(String(e?.message ?? e));
15971639
process.exitCode = 1;
1640+
if (anvilChild) {
1641+
try {
1642+
anvilChild.kill('SIGTERM');
1643+
} catch {}
1644+
}
15981645
}
15991646
});
16001647

0 commit comments

Comments
 (0)