Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(seed): leverage a local Fern CLI whenever you're using one in a seed script #4853

Merged
merged 10 commits into from
Oct 22, 2024

Conversation

armandobelardo
Copy link
Contributor

@armandobelardo armandobelardo commented Oct 11, 2024

Summary by CodeRabbit

  • New Features

    • Enhanced context management for the script runner in CLI commands.
    • Updated testing scripts for the Python SDK to conditionally run tests based on the test directory's existence.
  • Bug Fixes

    • Adjusted logic for starting Docker containers in the ScriptRunner class.
  • Documentation

    • Updated method signatures to reflect changes in parameters and functionality.

Copy link

coderabbitai bot commented Oct 13, 2024

Walkthrough

The pull request introduces several modifications across multiple files, primarily focusing on the ScriptRunner class and its integration within various commands. In cli.ts, the addTestCommand function has been updated to include a new parameter in the ScriptRunner instantiation, specifically taskContextFactory.create("script-runner"). Similarly, in runWithCustomFixture.ts, the runWithCustomFixture function has been adjusted to pass a taskContext object to the ScriptRunner constructor.

The ScriptRunner class itself has undergone significant changes, with its constructor now accepting an additional context parameter of type TaskContext. The method startContainers has been renamed to buildFernCli, which now returns an AbsoluteFilePath and includes updated logic for Docker container management, including a volume bind for the CLI. Additionally, the seed.yml file for the Python SDK has been modified to conditionally execute tests based on the presence of a test directory and to update the testing commands for Pydantic versions, reflecting ongoing issues in the testing framework. Overall, these changes enhance context handling and update testing procedures without altering the structure of command handling.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between d397d1b and a41e109.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • packages/seed/src/cli.ts (1 hunks)
  • packages/seed/src/commands/run/runWithCustomFixture.ts (1 hunks)
  • packages/seed/src/commands/test/ScriptRunner.ts (3 hunks)
  • seed/python-sdk/seed.yml (2 hunks)
🧰 Additional context used
🔇 Additional comments (5)
seed/python-sdk/seed.yml (2)

Line range hint 1-265: Summary of changes: Improved test execution process

The main changes in this file are focused on improving the test execution process for both Pydantic V1 and V2. The introduction of the FERN_NO_VERSION_REDIRECTION environment variable and the use of a Node.js script to run tests suggest a more standardized approach to testing across different Pydantic versions.

These changes appear to be part of a larger effort to enhance the testing infrastructure, potentially providing more consistent results across different environments. The rest of the configuration file remains unchanged, maintaining the existing structure for build scripts, publish settings, and fixture configurations.


238-238: LGTM! Verify the new test execution method.

The changes to the test execution command look good. The introduction of FERN_NO_VERSION_REDIRECTION=true and the use of a Node.js script to run tests appear to be intentional modifications to standardize the testing process.

To ensure the new test execution method works as expected, please run the following verification steps:

  1. Test with Pydantic V2:

  2. Test with Pydantic V1:

Verify that both commands execute successfully and produce the expected test results.

Also applies to: 249-249

packages/seed/src/cli.ts (1)

118-122: LGTM: Improved context management for ScriptRunner

The addition of a dedicated task context for the ScriptRunner enhances the granularity of context management within the testing framework. This change aligns well with the PR objective of leveraging a local Fern CLI in seed scripts.

packages/seed/src/commands/test/ScriptRunner.ts (2)

166-167: Ensure the CLI volume bind path is valid

The cliVolumeBind variable uses the path from absoluteFilePathToFernCli. Verify that this path exists and is accessible to Docker. In environments with different directory structures, this may cause issues. Consider adding checks or configurations to validate the path before usage.


41-47: Ensure all constructor calls include the new context parameter

The ScriptRunner constructor now requires an additional context: TaskContext parameter. Verify that all instances where ScriptRunner is instantiated have been updated to pass this new parameter to prevent runtime errors.

Run the following script to identify constructor calls that may need updating:

@@ -49,7 +49,7 @@ export async function runWithCustomFixture({
taskContextFactory,
skipScripts: true,
keepDocker: true,
scriptRunner: new ScriptRunner(workspace, false)
scriptRunner: new ScriptRunner(workspace, false, taskContext)
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Issue Detected: Missing taskContext in ScriptRunner Instantiation

The ScriptRunner instantiation in packages/seed/src/cli.ts does not include the taskContext parameter:

const scriptRunner = new ScriptRunner(

Please update this instantiation to include taskContext to ensure consistency and alignment with the PR objectives.

🔗 Analysis chain

LGTM. Please verify if this change fully addresses the PR objective.

The addition of taskContext to the ScriptRunner constructor looks good and doesn't introduce any obvious issues. However, I have a couple of suggestions:

  1. Could you verify if this change alone is sufficient to "leverage a local Fern CLI whenever you're using one in a seed script" as mentioned in the PR title? If not, are there additional changes needed?

  2. Consider adding a brief comment explaining the purpose of passing taskContext to the ScriptRunner. This would help future developers understand the intent behind this change.

To ensure this change is consistent across the codebase, please run the following script:

This will help identify any other locations where ScriptRunner is instantiated and might need a similar update.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for other instances of ScriptRunner instantiation
# that might need to be updated with the taskContext parameter.

# Search for ScriptRunner instantiations
rg --type typescript "new ScriptRunner\(" -g '!**/runWithCustomFixture.ts'

Length of output: 111


Script:

#!/bin/bash
# Description: Check for other instances of ScriptRunner instantiation
# that might need to be updated with the taskContext parameter.

# Search for ScriptRunner instantiations in TypeScript files, excluding runWithCustomFixture.ts
rg "new ScriptRunner\(" -g "*.ts" -g '!**/runWithCustomFixture.ts'

Length of output: 148


Script:

#!/bin/bash
# Description: Verify if the ScriptRunner instantiation in packages/seed/src/cli.ts includes the taskContext parameter.

# Search for the ScriptRunner instantiation in cli.ts
script_instantiation=$(rg "new ScriptRunner\(" packages/seed/src/cli.ts)

# Check if 'taskContext' is present in the instantiation
echo "$script_instantiation" | grep -q "taskContext"

if [ $? -eq 0 ]; then
  echo "taskContext parameter is present in ScriptRunner instantiation."
else
  echo "taskContext parameter is MISSING in ScriptRunner instantiation."
fi

Length of output: 372

private async startContainers(): Promise<void> {
private async buildFernCli(context: TaskContext): Promise<AbsoluteFilePath> {
await loggingExeca(context.logger, "pnpm", ["fern:build"]);
return join(AbsoluteFilePath.of(__dirname), RelativeFilePath.of("../../../packages/cli/cli/dist/prod"));
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Verify the correctness of the path resolution

The relative path used in buildFernCli may not resolve correctly in all environments. Ensure that the constructed path to the built CLI (../../../packages/cli/cli/dist/prod) is accurate and consider making it configurable or using environment variables to enhance portability.

Comment on lines 160 to 164
private async buildFernCli(context: TaskContext): Promise<AbsoluteFilePath> {
await loggingExeca(context.logger, "pnpm", ["fern:build"]);
return join(AbsoluteFilePath.of(__dirname), RelativeFilePath.of("../../../packages/cli/cli/dist/prod"));
}
Copy link

@coderabbitai coderabbitai bot Oct 13, 2024

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle possible failures in buildFernCli method

The pnpm fern:build command may fail, and currently, any errors thrown by loggingExeca are not being caught. To ensure robustness, consider adding error handling to catch and handle exceptions, providing clear error messages or taking remedial actions as needed.

Apply this diff to handle potential errors:

 private async buildFernCli(context: TaskContext): Promise<AbsoluteFilePath> {
-    await loggingExeca(context.logger, "pnpm", ["fern:build"]);
+    const buildCommand = await loggingExeca(context.logger, "pnpm", ["fern:build"], { reject: false });
+    if (buildCommand.failed) {
+        context.logger.error("Failed to build Fern CLI. See output below:");
+        context.logger.error(buildCommand.stdout);
+        context.logger.error(buildCommand.stderr);
+        throw new Error("Fern CLI build failed");
+    }
     return join(
         AbsoluteFilePath.of(__dirname),
         RelativeFilePath.of("../../../packages/cli/cli/dist/prod")
     );
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private async buildFernCli(context: TaskContext): Promise<AbsoluteFilePath> {
await loggingExeca(context.logger, "pnpm", ["fern:build"]);
return join(AbsoluteFilePath.of(__dirname), RelativeFilePath.of("../../../packages/cli/cli/dist/prod"));
}
private async buildFernCli(context: TaskContext): Promise<AbsoluteFilePath> {
const buildCommand = await loggingExeca(context.logger, "pnpm", ["fern:build"], { reject: false });
if (buildCommand.failed) {
context.logger.error("Failed to build Fern CLI. See output below:");
context.logger.error(buildCommand.stdout);
context.logger.error(buildCommand.stderr);
throw new Error("Fern CLI build failed");
}
return join(
AbsoluteFilePath.of(__dirname),
RelativeFilePath.of("../../../packages/cli/cli/dist/prod")
);
}

Copy link
Member

Choose a reason for hiding this comment

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

@armandobelardo great suggestion by the AI imo

Copy link

Choose a reason for hiding this comment

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

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between a41e109 and 1144581.

📒 Files selected for processing (2)
  • packages/seed/src/commands/test/ScriptRunner.ts (3 hunks)
  • seed/python-sdk/seed.yml (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • seed/python-sdk/seed.yml
🧰 Additional context used
🔇 Additional comments (2)
packages/seed/src/commands/test/ScriptRunner.ts (2)

1-1: LGTM: Constructor and import changes are consistent with new functionality.

The new imports and the updated constructor signature align well with the changes made to the class. The addition of the context parameter to both the constructor and the startContainers method call is consistent and necessary for the new functionality.

Also applies to: 41-47


Line range hint 1-178: Addressing past review comments

I've noticed that there were past review comments about error handling and path resolution. Our current review has addressed these concerns:

  1. We've suggested error handling improvements for both buildFernCli and startContainers methods.
  2. We've recommended making the CLI path more configurable, which partially addresses the path resolution concern.

These suggestions, if implemented, should resolve the issues raised in the past comments.

Comment on lines +166 to +178
private async startContainers(context: TaskContext): Promise<void> {
const absoluteFilePathToFernCli = await this.buildFernCli(context);
const cliVolumeBind = `${absoluteFilePathToFernCli}:/fern`;
// Start running a docker container for each script instance
for (const script of this.workspace.workspaceConfig.scripts ?? []) {
const startSeedCommand = await loggingExeca(undefined, "docker", ["run", "-dit", script.docker, "/bin/sh"]);
const startSeedCommand = await loggingExeca(undefined, "docker", [
"run",
"-dit",
"-v",
cliVolumeBind,
script.docker,
"/bin/sh"
]);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for Docker container startup.

The changes to use the local Fern CLI are good, but we should add error handling for the Docker container startup to improve robustness.

Consider adding error handling like this:

private async startContainers(context: TaskContext): Promise<void> {
    const absoluteFilePathToFernCli = await this.buildFernCli(context);
    const cliVolumeBind = `${absoluteFilePathToFernCli}:/fern`;
    for (const script of this.workspace.workspaceConfig.scripts ?? []) {
        const startSeedCommand = await loggingExeca(undefined, "docker", [
            "run",
            "-dit",
            "-v",
            cliVolumeBind,
            script.docker,
            "/bin/sh"
        ], { reject: false });
        if (startSeedCommand.failed) {
            context.logger.error("Failed to start Docker container. See output below:");
            context.logger.error(startSeedCommand.stdout);
            context.logger.error(startSeedCommand.stderr);
            throw new Error("Docker container startup failed");
        }
        const containerId = startSeedCommand.stdout;
        this.scripts.push({ ...script, containerId });
    }
}

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 1144581 and 2759f86.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (4)
  • packages/seed/src/cli.ts (1 hunks)
  • packages/seed/src/commands/run/runWithCustomFixture.ts (1 hunks)
  • packages/seed/src/commands/test/ScriptRunner.ts (3 hunks)
  • seed/python-sdk/seed.yml (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/seed/src/cli.ts
  • packages/seed/src/commands/run/runWithCustomFixture.ts
  • seed/python-sdk/seed.yml
🧰 Additional context used
🔇 Additional comments (3)
packages/seed/src/commands/test/ScriptRunner.ts (3)

1-1: LGTM: New imports added correctly.

The new imports (AbsoluteFilePath, join, and RelativeFilePath) from "@fern-api/fs-utils" are correctly added and will be used in the new buildFernCli method.


41-47: LGTM: Constructor updated correctly.

The constructor has been properly updated to include the new context parameter of type TaskContext. This change is consistent with the modifications in the startContainers method, and the context is correctly passed to startContainers.


166-178: ⚠️ Potential issue

Improve error handling in startContainers and verify path resolution.

The changes to use the local Fern CLI are good, but we should add error handling for the Docker container startup to improve robustness. Also, ensure that the path resolution for the CLI is correct across different environments.

  1. Add error handling:
private async startContainers(context: TaskContext): Promise<void> {
    const absoluteFilePathToFernCli = await this.buildFernCli(context);
    const cliVolumeBind = `${absoluteFilePathToFernCli}:/fern`;
    for (const script of this.workspace.workspaceConfig.scripts ?? []) {
        const startSeedCommand = await loggingExeca(undefined, "docker", [
            "run",
            "-dit",
            "-v",
            cliVolumeBind,
            script.docker,
            "/bin/sh"
        ], { reject: false });
        if (startSeedCommand.failed) {
            context.logger.error("Failed to start Docker container. See output below:");
            context.logger.error(startSeedCommand.stdout);
            context.logger.error(startSeedCommand.stderr);
            throw new Error("Docker container startup failed");
        }
        const containerId = startSeedCommand.stdout;
        this.scripts.push({ ...script, containerId });
    }
}
  1. Verify the correctness of the CLI path resolution:

This script verifies the existence of the CLI path and executable, ensuring that the path resolution is correct across different environments.

Comment on lines +160 to +164
private async buildFernCli(context: TaskContext): Promise<AbsoluteFilePath> {
const rootDir = join(AbsoluteFilePath.of(__dirname), RelativeFilePath.of("../../.."));
await loggingExeca(context.logger, "pnpm", ["fern:build"], { cwd: rootDir });
return join(rootDir, RelativeFilePath.of("packages/cli/cli/dist/prod"));
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add error handling to buildFernCli method.

While the method correctly builds the Fern CLI, it lacks error handling for potential build failures. Consider adding error handling to improve robustness.

Here's a suggested implementation with error handling:

private async buildFernCli(context: TaskContext): Promise<AbsoluteFilePath> {
    const rootDir = join(AbsoluteFilePath.of(__dirname), RelativeFilePath.of("../../.."));
    const result = await loggingExeca(context.logger, "pnpm", ["fern:build"], { cwd: rootDir, reject: false });
    if (result.failed) {
        context.logger.error("Failed to build Fern CLI. See output below:");
        context.logger.error(result.stdout);
        context.logger.error(result.stderr);
        throw new Error("Fern CLI build failed");
    }
    return join(rootDir, RelativeFilePath.of("packages/cli/cli/dist/prod"));
}

@dsinghvi dsinghvi merged commit 1fccec6 into main Oct 22, 2024
46 of 51 checks passed
@dsinghvi dsinghvi deleted the ab/local-cli branch October 22, 2024 20:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants