2025-05-06 20:20:02 +00:00
|
|
|
import { existsSync } from "node:fs";
|
|
|
|
|
import { spawn } from "bun";
|
|
|
|
|
import { logger } from "./logger";
|
|
|
|
|
|
2025-05-08 12:42:45 +00:00
|
|
|
export type LogLevel = "info" | "debug" | "error" | "warn";
|
|
|
|
|
|
2025-05-06 20:20:02 +00:00
|
|
|
export const runShellCommandWithLogger = async (
|
|
|
|
|
command: string,
|
test: 🐳 Add docker support for datahaven nodes (#71)
> [!NOTE]
> This is `Part 3` of the ongoing _Docker Series._
## New Additions:
- Launching Datahaven network will spin up containers, as opposed to
native binaries
- `stop:docker` script to kill all dh containers
- `e2e` test suite for datahaven solochain network
- Contains reference test file that uses papi for storage queries,
submitting exts, runtime calls (good job on that facu and tobi)
- Added new utils:
- `waitForLog()` to wait for log lines in docker container logs
- `createPapiConnectors()` helper for test cases to build and connect to
dh network
- `getPapiSigner()` helper to return a papi compatible signer using our
prefunded accounts (alith by default)
- `sendTxn()` helper to submit txn and wait for block inclusion, instead
of finalization, which std library provides
## Changes:
> [!CAUTION]
> Launching native binaries for datahaven no longer supported.
- Datahaven binary location cli option changed to `-i,
--datahaven-image-tag`
- To locally run this you'll need a datahaven docker image handy, you'll
need to either:
- Point to remote dockerhub e.g. `moonsonglabs/datahaven:main` (must be
logged in and have permission)
- Build this locally with `bun build:docker:operator`
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Added end-to-end tests for the Datahaven solochain, including runtime
API queries, storage lookups, extrinsic submissions, and event
listening.
- Introduced CLI option to specify the Datahaven Docker image tag, with
a default value.
- Added CLI option to disable the Relayer.
- Provided new scripts to stop Docker containers associated with
Datahaven.
- Added utility functions for Docker log monitoring and container
startup checks.
- Introduced utilities for interacting with the Datahaven Polkadot API.
- **Improvements**
- Switched Datahaven network launch from local binaries to Docker
containers.
- Enhanced cache accuracy in build workflows by including Rust source
files in cache keys.
- Improved build performance with TypeScript incremental build options.
- Increased timeout for end-to-end tests for better reliability.
- Updated CLI version to 0.2.0.
- Modified Dockerfile build to enable the `fast-runtime` feature.
- Extended network launch summary to include relayer and container
details.
- **Bug Fixes**
- Fixed cleanup logic by tracking and preparing for forced removal of
Docker containers after tests.
- **Chores**
- Updated workflow steps for Docker image handling and network checks.
- Adjusted scripts and workflow logic for improved Docker and test
management.
- Removed top-level disk usage summaries from cleanup workflow for
streamlined reporting.
- Enhanced shell command utility to support asynchronous wait during
execution.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com>
2025-05-16 14:17:05 +00:00
|
|
|
options?: {
|
|
|
|
|
cwd?: string;
|
|
|
|
|
env?: object;
|
|
|
|
|
logLevel?: LogLevel;
|
|
|
|
|
waitFor?: (...args: unknown[]) => Promise<void>;
|
|
|
|
|
}
|
2025-05-06 20:20:02 +00:00
|
|
|
) => {
|
2025-05-08 12:42:45 +00:00
|
|
|
const { cwd = ".", env = {}, logLevel = "info" as LogLevel } = options || {};
|
2025-05-06 20:20:02 +00:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (!existsSync(cwd)) {
|
|
|
|
|
logger.error("❌ CWD does not exist:", cwd);
|
|
|
|
|
throw new Error("❌ CWD does not exist");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const proc = spawn(["sh", "-c", command], {
|
|
|
|
|
cwd,
|
|
|
|
|
stdout: "pipe",
|
|
|
|
|
stderr: "pipe",
|
|
|
|
|
env: {
|
|
|
|
|
...process.env,
|
|
|
|
|
...env
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const stdoutReader = proc.stdout.getReader();
|
|
|
|
|
const stderrReader = proc.stderr.getReader();
|
|
|
|
|
|
2025-06-12 08:24:03 +00:00
|
|
|
let stderrBuffer = "";
|
|
|
|
|
|
2025-05-06 20:20:02 +00:00
|
|
|
const readStream = async (
|
2025-06-12 08:24:03 +00:00
|
|
|
reader: typeof stdoutReader,
|
2025-05-08 12:42:45 +00:00
|
|
|
streamName: string,
|
|
|
|
|
logLevel: LogLevel
|
2025-05-06 20:20:02 +00:00
|
|
|
) => {
|
|
|
|
|
try {
|
|
|
|
|
while (true) {
|
|
|
|
|
const { done, value } = await reader.read();
|
|
|
|
|
if (done) break;
|
|
|
|
|
const text = new TextDecoder().decode(value);
|
|
|
|
|
const trimmedText = text.trim();
|
2025-05-08 12:42:45 +00:00
|
|
|
if (trimmedText) {
|
2025-05-18 23:31:46 +00:00
|
|
|
logger[logLevel](
|
|
|
|
|
trimmedText.includes("\n") ? `>_ \n${trimmedText}` : `>_ ${trimmedText}`
|
|
|
|
|
);
|
2025-05-08 12:42:45 +00:00
|
|
|
}
|
2025-05-06 20:20:02 +00:00
|
|
|
}
|
|
|
|
|
} catch (err) {
|
|
|
|
|
logger.error(`Error reading from ${streamName} stream:`, err);
|
|
|
|
|
} finally {
|
|
|
|
|
reader.releaseLock();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-06-12 08:24:03 +00:00
|
|
|
const readStderr = async () => {
|
|
|
|
|
try {
|
|
|
|
|
while (true) {
|
|
|
|
|
const { done, value } = await stderrReader.read();
|
|
|
|
|
if (done) break;
|
|
|
|
|
stderrBuffer += new TextDecoder().decode(value);
|
|
|
|
|
}
|
|
|
|
|
} catch (err) {
|
|
|
|
|
logger.error("Error reading from stderr stream:", err);
|
|
|
|
|
} finally {
|
|
|
|
|
stderrReader.releaseLock();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
await Promise.all([readStream(stdoutReader, "stdout", logLevel), readStderr()]);
|
2025-05-06 20:20:02 +00:00
|
|
|
|
test: 🐳 Add docker support for datahaven nodes (#71)
> [!NOTE]
> This is `Part 3` of the ongoing _Docker Series._
## New Additions:
- Launching Datahaven network will spin up containers, as opposed to
native binaries
- `stop:docker` script to kill all dh containers
- `e2e` test suite for datahaven solochain network
- Contains reference test file that uses papi for storage queries,
submitting exts, runtime calls (good job on that facu and tobi)
- Added new utils:
- `waitForLog()` to wait for log lines in docker container logs
- `createPapiConnectors()` helper for test cases to build and connect to
dh network
- `getPapiSigner()` helper to return a papi compatible signer using our
prefunded accounts (alith by default)
- `sendTxn()` helper to submit txn and wait for block inclusion, instead
of finalization, which std library provides
## Changes:
> [!CAUTION]
> Launching native binaries for datahaven no longer supported.
- Datahaven binary location cli option changed to `-i,
--datahaven-image-tag`
- To locally run this you'll need a datahaven docker image handy, you'll
need to either:
- Point to remote dockerhub e.g. `moonsonglabs/datahaven:main` (must be
logged in and have permission)
- Build this locally with `bun build:docker:operator`
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Added end-to-end tests for the Datahaven solochain, including runtime
API queries, storage lookups, extrinsic submissions, and event
listening.
- Introduced CLI option to specify the Datahaven Docker image tag, with
a default value.
- Added CLI option to disable the Relayer.
- Provided new scripts to stop Docker containers associated with
Datahaven.
- Added utility functions for Docker log monitoring and container
startup checks.
- Introduced utilities for interacting with the Datahaven Polkadot API.
- **Improvements**
- Switched Datahaven network launch from local binaries to Docker
containers.
- Enhanced cache accuracy in build workflows by including Rust source
files in cache keys.
- Improved build performance with TypeScript incremental build options.
- Increased timeout for end-to-end tests for better reliability.
- Updated CLI version to 0.2.0.
- Modified Dockerfile build to enable the `fast-runtime` feature.
- Extended network launch summary to include relayer and container
details.
- **Bug Fixes**
- Fixed cleanup logic by tracking and preparing for forced removal of
Docker containers after tests.
- **Chores**
- Updated workflow steps for Docker image handling and network checks.
- Adjusted scripts and workflow logic for improved Docker and test
management.
- Removed top-level disk usage summaries from cleanup workflow for
streamlined reporting.
- Enhanced shell command utility to support asynchronous wait during
execution.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com>
2025-05-16 14:17:05 +00:00
|
|
|
if (options?.waitFor) {
|
|
|
|
|
await options.waitFor();
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-12 08:24:03 +00:00
|
|
|
const exitCode = await proc.exited;
|
|
|
|
|
|
|
|
|
|
// Only log stderr if the command failed
|
|
|
|
|
if (exitCode !== 0) {
|
2025-07-16 16:51:07 +00:00
|
|
|
logger.error("❌ Command failed with exit code:", exitCode);
|
2025-06-12 08:24:03 +00:00
|
|
|
const trimmedStderr = stderrBuffer.trim();
|
|
|
|
|
if (trimmedStderr) {
|
2025-07-16 16:51:07 +00:00
|
|
|
logger.error("Stderr:");
|
2025-06-12 08:24:03 +00:00
|
|
|
logger.error(
|
|
|
|
|
trimmedStderr.includes("\n") ? `>_ \n${trimmedStderr}` : `>_ ${trimmedStderr}`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-05-06 20:20:02 +00:00
|
|
|
} catch (err) {
|
|
|
|
|
logger.error("❌ Error running shell command:", command, "in", cwd);
|
|
|
|
|
logger.error(err);
|
|
|
|
|
throw err;
|
|
|
|
|
}
|
|
|
|
|
};
|