Skip to content

feat(sdk): add Rust code generation#669

Open
gaojunran wants to merge 6 commits into
jdx:mainfrom
gaojunran:feat/rust-sdk
Open

feat(sdk): add Rust code generation#669
gaojunran wants to merge 6 commits into
jdx:mainfrom
gaojunran:feat/rust-sdk

Conversation

@gaojunran
Copy link
Copy Markdown
Contributor

@gaojunran gaojunran commented Jun 6, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • Rust is now a supported target language for SDK generation (use --language rust with the generate sdk command).
    • Generated Rust SDKs include client code, type definitions, and runtime utilities for CLI execution.
  • Documentation

    • Updated CLI reference and SDK documentation to include Rust as a supported language with examples and usage details.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 6, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds complete Rust SDK generation support to the usage CLI tool. It introduces a new Rust code generator alongside existing TypeScript and Python generators, updates CLI interfaces and documentation to reflect Rust as a supported option, refactors argument/flag ordering logic in Python and TypeScript generators for consistency, and adds compilation tests.

Changes

Rust SDK Generation

Layer / File(s) Summary
CLI interface and reference updates
cli/src/cli/generate/sdk.rs, cli/assets/fig.ts, cli/usage.usage.kdl, docs/cli/reference/*, docs/cli/sdk.md
CLI argument parsing, completion specs, and reference documentation updated to recognize rust as a valid generate sdk --language choice. SDK docs now document Rust module structure, execution semantics via std::process::Command, and generated type examples.
SDK module architecture
lib/src/sdk/mod.rs
SDK module exports new rust submodule, extends SdkLanguage enum with Rust variant, and routes SdkLanguage::Rust to dedicated rust::generate() handler.
Rust types code generator
lib/src/sdk/rust/types.rs
Generates Rust type definitions: choice enums with Display/as_str, command/arg/flag structs with conditional Default derives, config structs from spec properties, field doc comments including help/env/defaults, and identifier utilities for sanitization and PascalCase conversion.
Rust runtime
lib/src/sdk/rust/runtime.rs
Embedded Rust source defining CLI runtime: CliResult capturing stdout/stderr/exit-code, CliError for IO/missing-binary errors, and CliRunner to spawn binaries via std::process::Command with UTF-8 lossy decoding.
Rust client code generator
lib/src/sdk/rust/client.rs
Generates Rust SDK client: command structs with subcommand fields, impl blocks with constructors/default_bin/exec() methods whose signatures vary based on args/flags/required-flag presence, argument building with double-dash rules, build_flag_args() for flag CLI tokens by arity/model, and alias methods.
Rust SDK orchestration and tests
lib/src/sdk/rust/mod.rs
Top-level generate() function assembles types.rs/client.rs/runtime.rs into SdkOutput, formats lib.rs with re-exports, and comprehensive test suite validating edge cases (required/optional args, flags, config, hidden commands, nested subcommands, double-dash automation, package-name override) via snapshot and containment assertions.
Python and TypeScript generator refactoring
lib/src/sdk/python/mod.rs, lib/src/sdk/typescript/wrappers.rs
Refactored argument and flag ordering in exec() generation: moved flag building earlier, restructured double-dash precomputation into command-arg scope, unified final run(cmd_args) call pattern. Changes ensure consistent ordering: detect phases → append flags → emit -- → add required-dash positionals → run.
Test updates
lib/tests/sdk_compile.rs
Enhanced full_spec() with new deploy rollback subcommand; removed npx_tsc_available() helper; added test_rust_sdk_compiles() to verify generated Rust SDK compiles via cargo check against temporary Cargo project.

Sequence Diagram(s)

sequenceDiagram
  participant CliArg as CLI --language
  participant Dispatch as generate dispatcher
  participant RustGen as rust::generate()
  participant TypesGen as types::render()
  participant ClientGen as client::render()
  participant RuntimeConst as RUNTIME_RS constant
  participant Output as SdkOutput

  CliArg->>Dispatch: SdkLanguage::Rust + SdkOptions
  Dispatch->>RustGen: call rust::generate(spec, opts)
  RustGen->>TypesGen: render(spec, pkg_name)
  TypesGen->>Output: types.rs string
  RustGen->>ClientGen: render(spec, pkg_name)
  ClientGen->>Output: client.rs string
  RustGen->>RuntimeConst: read RUNTIME_RS
  RuntimeConst->>Output: runtime.rs string
  RustGen->>Output: format lib.rs with re-exports
  Output->>Output: finalize SdkOutput
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • jdx/usage#623: Both PRs modify the generate sdk command's --language handling to extend the allowed language choices.

Poem

A rabbit hops through code so fine,
Type structures weaving, client design,
Rust runtime flows like burrows deep,
From spec to SDK, promises to keep. 🦀
CLI flags dance, and tests declare,
New language support beyond compare!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately summarizes the main change: adding Rust code generation support to the SDK, which is the primary focus across all modified files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 6, 2026

Codecov Report

❌ Patch coverage is 96.20743% with 49 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.16%. Comparing base (f1d6e61) to head (db8ce24).

Files with missing lines Patch % Lines
lib/src/sdk/rust/client.rs 89.54% 30 Missing and 11 partials ⚠️
lib/src/sdk/rust/types.rs 98.30% 5 Missing and 1 partial ⚠️
cli/src/cli/generate/sdk.rs 0.00% 1 Missing ⚠️
lib/src/sdk/rust/mod.rs 99.81% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #669      +/-   ##
==========================================
+ Coverage   79.31%   81.16%   +1.85%     
==========================================
  Files          56       59       +3     
  Lines       10487    11779    +1292     
  Branches    10487    11779    +1292     
==========================================
+ Hits         8318     9561    +1243     
- Misses       1409     1445      +36     
- Partials      760      773      +13     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Jun 6, 2026

Greptile Summary

This PR adds a full Rust SDK code-generator (lib/src/sdk/rust/) alongside the existing TypeScript and Python generators, producing types.rs, client.rs, runtime.rs, and lib.rs from a usage spec.

  • Previously reported issues (alias methods outside impl block, spurious }, flag ordering around --, use std::process::Command in client, missing Cargo.toml) are all resolved in this revision.
  • The compile-test lacks the tool_exists(\"cargo\") guard present in the analogous Python test, causing a panic instead of a graceful skip in environments without a Rust toolchain.
  • choice_variant_name does not guard against Self (the only PascalCase Rust reserved word), so a spec with a choice value of \"self\" would emit an uncompilable enum variant.

Confidence Score: 4/5

Safe to merge after adding the cargo availability guard to the compile test.

The core generators are sound and all previously flagged structural bugs are fixed. The compile test will panic rather than skip gracefully when cargo is not installed, which could block CI on non-Rust environments.

lib/tests/sdk_compile.rs needs the tool_exists("cargo") guard before invoking cargo check.

Important Files Changed

Filename Overview
lib/tests/sdk_compile.rs Replaces the TypeScript typecheck test with a cargo check compile test; missing tool_exists guard will panic instead of skip when the Rust toolchain is absent.
lib/src/sdk/rust/client.rs New Rust client code-generator; alias methods are correctly inside the impl block and -- separator ordering is correct.
lib/src/sdk/rust/types.rs New Rust types code-generator; choice_variant_name does not guard against Self from a choice value of self.
lib/src/sdk/rust/mod.rs Entry point for Rust SDK generation; emits all four output files correctly.
lib/src/sdk/rust/runtime.rs Static runtime string providing CliRunner, CliResult, and CliError.
lib/src/sdk/mod.rs Adds Rust variant to SdkLanguage enum and dispatches to rust::generate.

Reviews (7): Last reviewed commit: "fix(sdk): remove unused choice type impo..." | Re-trigger Greptile

Comment thread lib/src/sdk/rust/client.rs Outdated
Comment thread lib/src/sdk/rust/client.rs
Comment thread lib/src/sdk/rust/client.rs Outdated
Comment thread lib/tests/sdk_compile.rs
Comment thread lib/src/sdk/rust/client.rs Outdated
Comment thread lib/src/sdk/rust/client.rs Outdated
gaojunran and others added 4 commits June 7, 2026 00:29
…structor borrow-after-move

Flags are now inserted before the '--' separator instead of after it,
ensuring CLI parsers correctly recognize them as flags rather than
positional arguments. This fix applies to all three SDK generators
(Rust, Python, TypeScript).

Also fixes the non-root constructor to emit 'runner,' after
'runner.clone()' calls, preventing borrow-after-move compile errors
for nested subcommands.
- Use let cmd_args (no mut) when command has no args and no flags
- Only generate {Name}Flags struct when command has its own flags;
  commands that only inherit global flags use GlobalFlags directly
…rved keywords

- Filter out choice enum names from client.rs imports since they are
  only referenced in types.rs, not in client.rs
- Add missing Rust reserved keywords to sanitize_rs_ident: priv, do,
  try, become, final, typeof, unsized, virtual
- Remove 'default' which is not a reserved keyword in Rust
@gaojunran gaojunran marked this pull request as ready for review June 6, 2026 17:35
Copy link
Copy Markdown

@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

🧹 Nitpick comments (1)
lib/tests/sdk_compile.rs (1)

144-188: ⚡ Quick win

Add cargo availability check for consistency with Python test.

The Rust compilation test should verify cargo is available before running, matching the pattern used in the Python test (Line 95). Without this check, the test will panic with a confusing error if cargo is not installed.

🔧 Proposed fix to add cargo availability check
 #[test]
 fn test_rust_sdk_compiles() {
+    if !tool_exists("cargo") {
+        eprintln!("Skipping Rust SDK compilation test - cargo not found");
+        return;
+    }
+
     let spec = full_spec();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/tests/sdk_compile.rs` around lines 144 - 188, The test_rust_sdk_compiles
test should check that the "cargo" binary is available before invoking
Command::new("cargo") to avoid a confusing panic when cargo is missing; add an
availability check (e.g. call Command::new("cargo").arg("--version").output() or
.status() and test for Err or non-success) immediately before the existing
Command::new("cargo") invocation and if cargo is not found, print/elog a short
message and return/skip the test instead of continuing to run cargo check;
update the test_rust_sdk_compiles function (which uses usage::sdk::generate and
later builds the Command) to perform this pre-check.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/src/sdk/rust/types.rs`:
- Around line 461-463: escape_rs_string currently only handles backslash and
double-quote and fails to escape control/non-printable characters; change its
implementation to build a fully escaped string by iterating chars and using each
char's escape_default (e.g. s.chars().flat_map(|c|
c.escape_default()).collect::<String>()) and then ensure double quotes are
escaped (e.g. replace '"' with r#"\""#) so that control characters like \n, \r,
\t, \0 and other non-printables are emitted as valid Rust escapes when used by
the generator (function escape_rs_string, which is used to embed spec metadata
such as spec.about).

---

Nitpick comments:
In `@lib/tests/sdk_compile.rs`:
- Around line 144-188: The test_rust_sdk_compiles test should check that the
"cargo" binary is available before invoking Command::new("cargo") to avoid a
confusing panic when cargo is missing; add an availability check (e.g. call
Command::new("cargo").arg("--version").output() or .status() and test for Err or
non-success) immediately before the existing Command::new("cargo") invocation
and if cargo is not found, print/elog a short message and return/skip the test
instead of continuing to run cargo check; update the test_rust_sdk_compiles
function (which uses usage::sdk::generate and later builds the Command) to
perform this pre-check.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 97b0195e-3daf-425e-8d7c-c48d4598f82b

📥 Commits

Reviewing files that changed from the base of the PR and between f1d6e61 and 8bc4ed2.

⛔ Files ignored due to path filters (56)
  • lib/src/sdk/python/snapshots/usage__sdk__python__tests__python_client.snap is excluded by !**/*.snap
  • lib/src/sdk/python/snapshots/usage__sdk__python__tests__python_client_edge_cases.snap is excluded by !**/*.snap
  • lib/src/sdk/python/snapshots/usage__sdk__python__tests__python_count_flag_build.snap is excluded by !**/*.snap
  • lib/src/sdk/python/snapshots/usage__sdk__python__tests__python_deep_nesting.snap is excluded by !**/*.snap
  • lib/src/sdk/python/snapshots/usage__sdk__python__tests__python_double_dash_automatic.snap is excluded by !**/*.snap
  • lib/src/sdk/python/snapshots/usage__sdk__python__tests__python_exec_edge_cases.snap is excluded by !**/*.snap
  • lib/src/sdk/python/snapshots/usage__sdk__python__tests__python_flag_edge_cases-2.snap is excluded by !**/*.snap
  • lib/src/sdk/python/snapshots/usage__sdk__python__tests__python_flags_only_subcommand.snap is excluded by !**/*.snap
  • lib/src/sdk/python/snapshots/usage__sdk__python__tests__python_full_feature_client.snap is excluded by !**/*.snap
  • lib/src/sdk/python/snapshots/usage__sdk__python__tests__python_global_flags_flags_only.snap is excluded by !**/*.snap
  • lib/src/sdk/python/snapshots/usage__sdk__python__tests__python_multiple_aliases.snap is excluded by !**/*.snap
  • lib/src/sdk/python/snapshots/usage__sdk__python__tests__python_negate_flag_build.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_arg_defaults.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_boolean_flag_default_false.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_choice_collision.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_client.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_config_all_optional.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_config_boolean_default_false.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_config_props.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_config_string_with_default.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_count_flag_build.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_deep_nesting.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_double_dash_automatic.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_example_without_lang.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_flag_edge_cases-2.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_flag_edge_cases.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_flag_with_choices.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_flag_with_env.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_flags_only_subcommand.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_full_feature_client.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_full_feature_types.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_global_flags_flags_only.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_global_repeatable_flags.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_hyphenated_subcommands.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_lib.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_minimal.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_multiple_aliases.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_negate_flag_build.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_optional_arg_empty_flags.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_optional_variadic_arg.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_package_name_override.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_required_flag_type.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_runtime.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_types.snap is excluded by !**/*.snap
  • lib/src/sdk/rust/snapshots/usage__sdk__rust__tests__rust_var_value_flag_with_default.snap is excluded by !**/*.snap
  • lib/src/sdk/typescript/snapshots/usage__sdk__typescript__types__tests__deep_nesting.snap is excluded by !**/*.snap
  • lib/src/sdk/typescript/snapshots/usage__sdk__typescript__types__tests__flags_only_subcommand.snap is excluded by !**/*.snap
  • lib/src/sdk/typescript/snapshots/usage__sdk__typescript__types__tests__full_feature_client.snap is excluded by !**/*.snap
  • lib/src/sdk/typescript/snapshots/usage__sdk__typescript__types__tests__typescript_client.snap is excluded by !**/*.snap
  • lib/src/sdk/typescript/snapshots/usage__sdk__typescript__types__tests__typescript_client_edge_cases.snap is excluded by !**/*.snap
  • lib/src/sdk/typescript/snapshots/usage__sdk__typescript__types__tests__typescript_count_flag_build.snap is excluded by !**/*.snap
  • lib/src/sdk/typescript/snapshots/usage__sdk__typescript__types__tests__typescript_double_dash_automatic.snap is excluded by !**/*.snap
  • lib/src/sdk/typescript/snapshots/usage__sdk__typescript__types__tests__typescript_flag_edge_cases-2.snap is excluded by !**/*.snap
  • lib/src/sdk/typescript/snapshots/usage__sdk__typescript__types__tests__typescript_global_flags_flags_only.snap is excluded by !**/*.snap
  • lib/src/sdk/typescript/snapshots/usage__sdk__typescript__types__tests__typescript_multiple_aliases.snap is excluded by !**/*.snap
  • lib/src/sdk/typescript/snapshots/usage__sdk__typescript__types__tests__typescript_negate_flag_build.snap is excluded by !**/*.snap
📒 Files selected for processing (14)
  • cli/assets/fig.ts
  • cli/src/cli/generate/sdk.rs
  • cli/usage.usage.kdl
  • docs/cli/reference/commands.json
  • docs/cli/reference/generate/sdk.md
  • docs/cli/sdk.md
  • lib/src/sdk/mod.rs
  • lib/src/sdk/python/mod.rs
  • lib/src/sdk/rust/client.rs
  • lib/src/sdk/rust/mod.rs
  • lib/src/sdk/rust/runtime.rs
  • lib/src/sdk/rust/types.rs
  • lib/src/sdk/typescript/wrappers.rs
  • lib/tests/sdk_compile.rs

Comment thread lib/src/sdk/rust/types.rs
Comment on lines +461 to +463
pub fn escape_rs_string(s: &str) -> String {
s.replace('\\', r"\\").replace('"', r#"\""#)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Incomplete string escaping will generate invalid Rust code.

escape_rs_string only escapes backslash and double-quote, but does not handle control characters like newlines (\n), tabs (\t), or carriage returns (\r). When this function is used to embed spec metadata (lines 35, 41, 47) or other string content into generated Rust string literals, any control characters in the source will produce syntactically invalid Rust.

For example, if spec.about contains "A tool\nfor testing", the generated code would be:

pub const ABOUT: &str = "A tool
for testing";  // ❌ syntax error
🔧 Proposed fix to escape control characters
 pub fn escape_rs_string(s: &str) -> String {
-    s.replace('\\', r"\\").replace('"', r#"\""#)
+    s.replace('\\', r"\\")
+        .replace('"', r#"\""#)
+        .replace('\n', r"\n")
+        .replace('\r', r"\r")
+        .replace('\t', r"\t")
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/src/sdk/rust/types.rs` around lines 461 - 463, escape_rs_string currently
only handles backslash and double-quote and fails to escape
control/non-printable characters; change its implementation to build a fully
escaped string by iterating chars and using each char's escape_default (e.g.
s.chars().flat_map(|c| c.escape_default()).collect::<String>()) and then ensure
double quotes are escaped (e.g. replace '"' with r#"\""#) so that control
characters like \n, \r, \t, \0 and other non-printables are emitted as valid
Rust escapes when used by the generator (function escape_rs_string, which is
used to embed spec metadata such as spec.about).

@gaojunran
Copy link
Copy Markdown
Contributor Author

gaojunran commented Jun 6, 2026

@jdx ready for review! remaining comments are for add cargo cli existence check in ci and I don't think it's needed lol.

and coverage workflow fails strangely and may need a check

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 7, 2026

This PR currently has failing checks. If this continues for 7 days, it will be closed automatically.

This is warning day 1 of 7.

Please update the PR when you have a chance. Feel free to reopen or create a new PR if it is closed and you'd like to continue working on it.

This comment was generated by an automated workflow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant