Skip to content

Conversation

@Ethax22
Copy link

@Ethax22 Ethax22 commented Jan 2, 2026

Description

This PR adds comprehensive CI/CD pipeline improvements for the RunAnywhere SDKs project, addressing critical issues identified in the existing workflow setup. All workflows follow best practices and are configured to run on push and pull requests to the main branch.

Type of Change

  • New feature
  • Bug fix
  • Documentation update
  • Refactoring

Changes Made

GitHub Actions Workflows

iOS SDK CI (.github/workflows/ios-sdk.yml)

  • SwiftLint for code quality
  • Swift Package Manager build and test
  • Xcode 15.2 standardized across workflows
  • Upload build artifacts

Android SDK CI (.github/workflows/android-sdk.yml)

  • Fixed SDK path from runanywhere-android to runanywhere-kotlin
  • Fixed JDK version from 11 to 17
  • Detekt static analysis
  • Android Lint
  • Gradle build and test
  • JaCoCo code coverage reporting

React Native SDK CI (.github/workflows/react-native-sdk.yml)

  • ESLint for JavaScript/TypeScript
  • TypeScript type checking
  • Nitrogen binding generation verification
  • iOS and Android native module builds

Flutter SDK CI (.github/workflows/flutter-sdk.yml)

  • Dart analyzer
  • Dart format checks
  • iOS and Android build verification

Integration Tests (.github/workflows/integration-tests.yml)

  • Builds and tests all example apps
  • Validates SDK integration with example apps

Release Artifacts (.github/workflows/release-artifacts.yml)

  • Automated artifact generation on tag creation
  • XCFrameworks for iOS
  • AARs and JARs for Android

Infrastructure Improvements

  • Dependabot (.github/dependabot.yml)

    • Automated dependency updates for npm, pub, Gradle, and GitHub Actions
    • Security vulnerability scanning
  • Pre-commit Hooks (.pre-commit-config.yaml)

    • Re-enabled Android linting hooks
    • Fixed paths for Android SDK (runanywhere-kotlin)
    • YAML validation, trailing whitespace, end-of-file fixes
  • Release Scripts

    • scripts/release_android_sdk.sh - Automated Android releases
    • scripts/release_ios_sdk.sh - Existing iOS release script
  • Build Configuration

    • sdk/runanywhere-kotlin/build.gradle.kts - Added JaCoCo for code coverage

Testing

  • Tests pass locally (where applicable)
  • Workflows tested via local scripts (scripts/test-cicd-local.ps1)
  • Verified workflow syntax (all YAML files validated)
  • Checked path configurations (Android SDK paths corrected)
  • Verified branch naming follows conventions (feature/cicd-pipeline-improvements)

Note: Some code errors exist in the codebase (React Native SDK TypeScript errors, Android build issues) - these are expected and will be addressed in follow-up PRs. The CI/CD pipeline correctly detects these issues, proving the pipeline is working as intended.

Labels

Please add the appropriate label(s):

  • CI/CD - CI/CD improvements
  • Android SDK - Android workflow fixes and improvements
  • iOS SDK - iOS workflow improvements
  • React Native SDK - React Native workflow
  • Flutter SDK - Flutter workflow

Checklist

Following Contributing Guidelines:

  • Code follows project style guidelines
  • Self-review completed
  • Documentation updated (workflow files are self-documenting with comments)
  • Commit messages follow Conventional Commits format
  • PR is focused on one feature (CI/CD improvements)
  • Clear description provided (what, why, and how)
  • All CI checks will run automatically (GitHub Actions)

Related Issues

Addresses CI/CD pipeline issues identified in the project analysis:

  • Android workflow broken (incorrect paths, JDK version)
  • Missing CI workflows for React Native and Flutter SDKs
  • Missing integration tests workflow
  • Missing release automation
  • Pre-commit hooks disabled for Android

Screenshots

N/A - Infrastructure changes only (GitHub Actions workflows, configuration files)

Additional Notes

  • All workflows are configured to run on push and pull requests to main branch
  • Workflows use path-based triggers to optimize CI runs (only run when relevant files change)
  • Pre-commit hooks are configured but may require Zig compiler on Windows (optional for local development)
  • The pipeline correctly identifies existing code issues, demonstrating it's working as intended
<!-- ELLIPSIS_HIDDEN -->

----

> [!IMPORTANT]
> Adds comprehensive CI/CD pipeline, integration tests, and release automation for all SDKs.
> 
>   - **CI/CD Workflows**:
>     - Adds workflows for iOS, Android, React Native, and Flutter SDKs in `.github/workflows/`.
>     - Integration tests for all example apps in `integration-tests.yml`.
>     - Release automation for iOS and Android artifacts in `release-artifacts.yml`.
>   - **Infrastructure**:
>     - Adds `.github/dependabot.yml` for automated dependency updates.
>     - Re-enables Android linting in `.pre-commit-config.yaml`.
>     - Updates `scripts/release_android_sdk.sh` and `scripts/release_ios_sdk.sh` for automated releases.
>   - **Build Configuration**:
>     - Updates `sdk/runanywhere-kotlin/build.gradle.kts` to include JaCoCo for code coverage.
>     - Fixes Android SDK path from `runanywhere-android` to `runanywhere-kotlin`.
> 
> <sup>This description was created by </sup>[<img alt="Ellipsis" src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=RunanywhereAI%2Frunanywhere-sdks&utm_source=github&utm_medium=referral)<sup> for eb160e05517488491ecc103157d1f8b249a6c5cc. You can [customize](https://app.ellipsis.dev/RunanywhereAI/settings/summaries) this summary. It will automatically update as commits are pushed.</sup>

<!-- ELLIPSIS_HIDDEN -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Enabled automated dependency updates across JavaScript, Dart, Android, and CI.
  * Added CI workflows for Kotlin/Android, Flutter, React Native, integration tests, and release-artifact publishing.
  * Added Kotlin SDK code coverage reporting.

* **Chores**
  * Upgraded CI to JDK 17 and standardized CI/tooling environments.
  * Improved pre-commit hooks and Android linting.
  * Added release automation and helper scripts for SDK releases.

<sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- greptile_comment -->

<h3>Greptile Summary</h3>


- Adds comprehensive CI/CD pipeline infrastructure for all SDKs (iOS, Android, React Native, Flutter) with linting, testing, and automated release workflows
- Fixes critical Android SDK CI issues by correcting paths from `runanywhere-android` to `runanywhere-kotlin` and upgrading from JDK 11 to JDK 17
- Implements infrastructure improvements including Dependabot for automated dependency updates, enhanced pre-commit hooks, and JaCoCo code coverage reporting

<h3>Important Files Changed</h3>


| Filename | Overview |
|----------|----------|
| `.github/workflows/release-artifacts.yml` | New automated release workflow that may fail due to missing framework paths and dependency setup |
| `scripts/release_android_sdk.sh` | New Android release script with hardcoded GitHub repository URL that doesn't match actual repo |
| `.github/workflows/integration-tests.yml` | New integration testing workflow with outdated Flutter version and potential iOS version conflicts |

<h3>Confidence score: 3/5</h3>


- This PR has significant implementation issues that could cause CI failures and broken release processes
- Score lowered due to hardcoded incorrect GitHub URLs in release scripts, outdated dependency versions, missing framework paths in iOS builds, and potential iOS version conflicts in workflows
- Pay close attention to `scripts/release_android_sdk.sh` for URL corrections and `.github/workflows/release-artifacts.yml` for build dependency setup

<h3>Sequence Diagram</h3>

```mermaid
sequenceDiagram
    participant User
    participant GitHub
    participant "iOS SDK CI"
    participant "Android SDK CI"
    participant "React Native CI"
    participant "Flutter CI"
    participant "Integration Tests"

    User->>GitHub: "Create pull request to main"
    GitHub->>GitHub: "Trigger workflows based on changed paths"
    
    par iOS SDK Workflow
        GitHub->>+"iOS SDK CI": "Start ios-sdk.yml workflow"
        "iOS SDK CI"->>"iOS SDK CI": "Setup Xcode 15.2"
        "iOS SDK CI"->>"iOS SDK CI": "Run SwiftLint"
        "iOS SDK CI"->>"iOS SDK CI": "Swift Package Manager build"
        "iOS SDK CI"->>"iOS SDK CI": "Run tests"
        "iOS SDK CI"->>GitHub: "Upload build artifacts"
        "iOS SDK CI"->>-GitHub: "Report success/failure"
    
    and Android SDK Workflow
        GitHub->>+"Android SDK CI": "Start android-sdk.yml workflow"
        "Android SDK CI"->>"Android SDK CI": "Setup JDK 17"
        "Android SDK CI"->>"Android SDK CI": "Run Detekt analysis"
        "Android SDK CI"->>"Android SDK CI": "Run Android Lint"
        "Android SDK CI"->>"Android SDK CI": "Build JVM and Android targets"
        "Android SDK CI"->>"Android SDK CI": "Generate JaCoCo coverage"
        "Android SDK CI"->>GitHub: "Upload coverage reports"
        "Android SDK CI"->>-GitHub: "Report success/failure"
    
    and React Native Workflow
        GitHub->>+"React Native CI": "Start react-native-sdk.yml workflow"
        "React Native CI"->>"React Native CI": "Setup Node.js 18"
        "React Native CI"->>"React Native CI": "Run ESLint"
        "React Native CI"->>"React Native CI": "TypeScript type checking"
        "React Native CI"->>"React Native CI": "Build iOS and Android modules"
        "React Native CI"->>-GitHub: "Report success/failure"
    
    and Flutter Workflow
        GitHub->>+"Flutter CI": "Start flutter-sdk.yml workflow"
        "Flutter CI"->>"Flutter CI": "Setup Flutter 3.38.1"
        "Flutter CI"->>"Flutter CI": "Run Dart analyzer"
        "Flutter CI"->>"Flutter CI": "Check code formatting"
        "Flutter CI"->>"Flutter CI": "Build iOS and Android targets"
        "Flutter CI"->>-GitHub: "Report success/failure"
    end
    
    GitHub->>+"Integration Tests": "Start integration-tests.yml workflow"
    "Integration Tests"->>"Integration Tests": "Build and test Android example app"
    "Integration Tests"->>"Integration Tests": "Build and test iOS example app"
    "Integration Tests"->>"Integration Tests": "Build and test React Native app"
    "Integration Tests"->>"Integration Tests": "Build and test Flutter app"
    "Integration Tests"->>-GitHub: "Report integration results"
    
    GitHub->>User: "Display CI status checks on PR"

Context used:

  • Context from dashboard - CLAUDE.md (source)

- Add Android SDK CI workflow with linting, tests, and coverage
- Add React Native SDK CI workflow with ESLint and type checking
- Add Flutter SDK CI workflow with Dart analysis
- Add integration tests workflow for all example apps
- Add release artifacts generation workflow
- Fix Android workflow paths and JDK version
- Enable Android linting in pre-commit
- Add Dependabot for security scanning
- Add Android release automation script
- Standardize Xcode versions across workflows
- Add JaCoCo code coverage for Android SDK
…coding error)

>> - Add Android SDK CI workflow with linting, tests, and coverage
>> - Add React Native SDK CI workflow with ESLint and type checking
>> - Add Flutter SDK CI workflow with Dart analysis
>> - Add integration tests workflow for all example apps
>> - Add release artifacts generation workflow
>> - Fix Android workflow paths and JDK version
>> - Enable Android linting in pre-commit
>> - Add Dependabot for security scanning
>> - Add Android release automation script
>> - Standardize Xcode versions across workflows
>> - Add JaCoCo code coverage for Android SDK
@coderabbitai
Copy link

coderabbitai bot commented Jan 2, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds Dependabot config, multiple CI workflows (Kotlin/Android, Flutter, React Native, integration, release artifacts), Gradle/Jacoco coverage and unit-test resource support for the Kotlin SDK, pre-commit Android lint hooks and enhanced TODO checks, updated lint/release scripts, and path migrations from sdk/runanywhere-androidsdk/runanywhere-kotlin.

Changes

Cohort / File(s) Summary
Dependabot
.github/dependabot.yml
New Dependabot configuration enabling weekly updates for npm (react-native), pub (flutter), gradle (kotlin), and github-actions with PR limits, labels, and commit-message formatting.
New CI Workflows
.github/workflows/...
\ .github/workflows/react-native-sdk.yml`, ` .github/workflows/flutter-sdk.yml`, ` .github/workflows/android-sdk.yml`, ` .github/workflows/integration-tests.yml`, ` .github/workflows/release-artifacts.yml``
Added multiple platform-specific CI workflows and a release-artifacts workflow; review runner selection (macOS vs Linux), JDK 17, cache/gradle wrapper handling, continue-on-error usage, artifact uploads, and tag-based release logic.
App CI Update
.github/workflows/android-app.yml
Updated workflow paths to sdk/runanywhere-kotlin/**, bumped to Temurin JDK 17, adjusted Gradle wrapper and cache/artifact paths.
Kotlin SDK Build & Coverage
sdk/runanywhere-kotlin/build.gradle.kts
Applied jacoco (toolVersion 0.8.11), added jacocoTestReport aggregating JVM and Android unit test exec data, and enabled testOptions.unitTests.isIncludeAndroidResources = true.
Pre-commit & TODO Hook
.pre-commit-config.yaml, `scripts/check-todos-hook.sh`
TODO hook now supports per-file processing (pass_filenames), skips deleted files, reports per-file missing-issue TODOs; added android-sdk-lint and android-app-lint local hooks targeting Kotlin paths.
Lint Script
scripts/lint-android.sh
Switched targets and report paths to sdk/runanywhere-kotlin, adjusted output separators and symbols.
Release Automation
scripts/release_android_sdk.sh, scripts/release_ios_sdk.sh
Added release_android_sdk.sh (interactive/CI-friendly bump, changelog, tag, GH release). release_ios_sdk.sh tightened preflight checks, introduced worktree-based BuildToken handling, and improved messaging.
Misc — CI permissions & triggers
.github/workflows/* (various)
Standardized JDK 17 usage, Gradle cache/execute-permission handling, artifact retention/conditional uploads, and path migrations across workflows.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

kotlin-sdk, ios-sdk

Suggested reviewers

  • sanchitmonga22

Poem

🐰
I hop through CI, nudging tags and trees,
Bumping versions with deft little sneeze,
Lint and tests dance under moonlight,
Artifacts bundled snug and tight,
Dependabot hums — all green, with ease.

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding a comprehensive CI/CD pipeline for all SDKs.
Description check ✅ Passed The description is well-structured, comprehensive, and covers all required sections including description, type of change, testing, labels, and checklist.

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 987c043 and aa43ec6.

📒 Files selected for processing (3)
  • .github/workflows/flutter-sdk.yml
  • .github/workflows/integration-tests.yml
  • .github/workflows/react-native-sdk.yml
🚧 Files skipped from review as they are similar to previous changes (3)
  • .github/workflows/integration-tests.yml
  • .github/workflows/flutter-sdk.yml
  • .github/workflows/react-native-sdk.yml

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link

@ellipsis-dev ellipsis-dev bot left a comment

Choose a reason for hiding this comment

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

Caution

Changes requested ❌

Reviewed everything up to eb160e0 in 3 minutes and 49 seconds. Click for details.
  • Reviewed 2256 lines of code in 13 files
  • Skipped 0 files when reviewing.
  • Skipped posting 17 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. .github/dependabot.yml:1
  • Draft comment:
    Dependabot configuration is well structured and covers multiple ecosystems effectively.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
2. .github/workflows/android-app.yml:7
  • Draft comment:
    Updated paths from 'runanywhere-android' to 'runanywhere-kotlin' ensure directory consistency.
  • Reason this comment was not posted:
    Comment did not seem useful. Confidence is useful = 0% <= threshold 50% This comment is purely informative, as it simply states that paths were updated for consistency. It does not provide any actionable feedback or suggestions for improvement.
3. .github/workflows/android-sdk.yml:67
  • Draft comment:
    The Android SDK CI workflow is comprehensive; review the use of 'continue-on-error' in the code coverage step to ensure failures aren’t unintentionally masked.
  • Reason this comment was not posted:
    Confidence changes required: 50% <= threshold 50% None
4. .github/workflows/flutter-sdk.yml:52
  • Draft comment:
    Ensure the selected Xcode version (Xcode_16.1.app) in the iOS build step is intentional and consistent with other workflows.
  • Reason this comment was not posted:
    Confidence changes required: 50% <= threshold 50% None
5. .github/workflows/integration-tests.yml:55
  • Draft comment:
    The integration tests workflow covers multiple SDKs; consider adding more detailed logging for steps marked with 'continue-on-error' to aid troubleshooting.
  • Reason this comment was not posted:
    Confidence changes required: 30% <= threshold 50% None
6. .github/workflows/react-native-sdk.yml:42
  • Draft comment:
    The React Native SDK CI workflow uses 'continue-on-error' for generating Nitrogen bindings; verify that any binding failures won’t adversely affect overall quality.
  • Reason this comment was not posted:
    Confidence changes required: 30% <= threshold 50% None
7. .github/workflows/release-artifacts.yml:57
  • Draft comment:
    Release artifacts workflow is well defined; ensure the 90-day retention for artifacts aligns with project requirements.
  • Reason this comment was not posted:
    Confidence changes required: 10% <= threshold 50% None
8. .pre-commit-config.yaml:26
  • Draft comment:
    Android lint hooks now reference the updated 'sdk/runanywhere-kotlin' directory; configuration looks correct.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
9. scripts/check-todos-hook.sh:1
  • Draft comment:
    The TODO check script is concise and effective; no changes are necessary.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
10. scripts/lint-android.sh:30
  • Draft comment:
    Updated Android lint script now points to the correct 'sdk/runanywhere-kotlin' path; changes are accurate.
  • Reason this comment was not posted:
    Confidence changes required: 0% <= threshold 50% None
11. scripts/release_android_sdk.sh:28
  • Draft comment:
    The Android release script is comprehensive; consider adding additional error handling during worktree cleanup to ensure robustness.
  • Reason this comment was not posted:
    Confidence changes required: 30% <= threshold 50% None
12. sdk/runanywhere-kotlin/build.gradle.kts:192
  • Draft comment:
    The added JaCoCo configuration for code coverage is a solid improvement; verify that the exclude patterns remain valid as the codebase evolves.
  • Reason this comment was not posted:
    Confidence changes required: 10% <= threshold 50% None
13. scripts/release_ios_sdk.sh:211
  • Draft comment:
    The emoji text appears garbled here ('ΓÜá∩╕Å'). It seems like an encoding issue. Consider using a standard emoji like '⚠️' as originally intended.
  • Reason this comment was not posted:
    Comment was on unchanged code.
14. scripts/release_ios_sdk.sh:212
  • Draft comment:
    The emoji text appears garbled here as well ('ΓÜá∩╕Å') and should be corrected to '⚠️' or a similar clear indicator.
  • Reason this comment was not posted:
    Comment was on unchanged code.
15. scripts/release_ios_sdk.sh:281
  • Draft comment:
    Typo: The warning message contains garbled characters (ΓÜá∩╕Å) which appear to be a mis-encoded symbol (likely intended to be ⚠️). Please fix the encoding so the correct symbol is displayed.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 30% vs. threshold = 50% The comment claims there are garbled characters (ΓÜá∩╕Å) that should be the warning emoji (⚠️). Looking at the diff, I can see the author made an intentional change to the checkmark character on line 19, changing from ✓ to ✔. This suggests they are paying attention to Unicode characters. The garbled characters appear in the actual string content on lines 211, 212, 281, and 512. However, I need to consider: 1) This could be a real encoding issue in the source file, 2) This could be an artifact of how the diff is being displayed to me, 3) The print_warning function itself uses the correct ⚠ symbol on line 21. If the source file truly has garbled characters, this would be a valid issue. But I cannot be 100% certain this isn't just a display artifact in the diff viewer. I'm seeing garbled characters in the diff, but this could be an encoding issue with how the diff is being presented to me rather than an actual problem in the source file. The author clearly made intentional Unicode character changes (line 19), so they may have intentionally used these characters. Without being able to verify the actual file encoding or see how it renders in a terminal, I cannot be certain this is a real issue. While there's uncertainty about whether this is a display artifact, the presence of garbled characters in multiple locations (lines 211, 212, 281, 512) combined with the fact that the print_warning function definition correctly uses ⚠ suggests this could be a legitimate encoding issue. However, the author made intentional Unicode changes elsewhere in the same commit, which suggests they would have noticed if these were actually garbled in their editor. This comment is speculative because I cannot verify whether the garbled characters are real or just a display artifact. The author made intentional Unicode changes in this same diff, suggesting they would have caught obvious encoding issues. Without strong evidence this is a real problem, I should delete this comment.
16. scripts/release_ios_sdk.sh:511
  • Draft comment:
    Typo: This print_warning line shows a long sequence of garbled characters (ΓòÉΓòÉ...). It looks like a mis-encoded separator or decorative element. Please update with the intended text or symbol.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 20% vs. threshold = 50% The comment suggests this is garbled/mis-encoded text that should be fixed. However, looking at the context, lines 511 and 513 both have the same repeating character pattern, and they surround line 512 which has an important warning message. This strongly suggests it's intentional - the author is trying to create a visual box or banner to draw attention to the warning. The character might not render properly in all terminals, but that doesn't make it a "typo" or bug. The comment assumes this is an error without considering it might be intentional formatting. The diff shows this was deliberately added as part of the changes. Without clear evidence this is breaking functionality or was unintended, I should not keep this comment. Could this actually be a real encoding issue that happened during the commit? Maybe the author intended to use a different character (like equals signs or dashes) and it got corrupted? The fact that it renders as garbled text in the diff viewer might indicate a real problem. While encoding issues are possible, the fact that the exact same pattern appears on both line 511 and 513, symmetrically surrounding the warning message, strongly indicates this is intentional formatting. If it were a corruption, it would be unlikely to corrupt in exactly the same way twice. Additionally, the author clearly intended to create visual emphasis here. Even if the character choice is questionable, calling it a "typo" and asking them to fix it without strong evidence of a bug is not appropriate per the review guidelines. This comment should be deleted. The "garbled" characters appear to be intentional decorative formatting to create a visual separator/box around an important warning message. There's no strong evidence this is a bug or typo - it's more likely a stylistic choice that may not render well in all contexts. The comment is speculative about what the "intended" text should be.
17. scripts/release_ios_sdk.sh:512
  • Draft comment:
    Typo: The warning message on this line also displays garbled characters (ΓÜá∩╕Å) instead of the intended symbol (likely ⚠️). Please correct the encoding.
  • Reason this comment was not posted:
    Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 0% vs. threshold = 50% The comment is pointing out what appears to be a legitimate encoding issue with garbled characters instead of emoji. However, looking at the diff carefully, line 512 is not actually changed - it's just shown as context. The diff only shows indentation changes (whitespace changes) throughout the file. The garbled characters were already present in the old version of the file and were not introduced or modified by this PR. Since the comment is about unchanged code (the actual text content of the warning message), it violates the rule that comments should only be about changes made by the diff. Could the garbled characters have been introduced by the diff itself or the way the file was saved? Perhaps the PR author changed the file encoding which caused these characters to appear garbled? However, I don't see any evidence in the diff that the actual character content changed - only indentation changed. Even if there was an encoding change, the diff would show the line as changed (with the old content on the left and new content on the right). Since line 512 doesn't appear as a changed line in the diff (it's not prefixed with + or -), the garbled characters were already there before this PR. The comment is about pre-existing code, not about changes made in this PR. This comment should be deleted because it's about unchanged code. The garbled characters on line 512 were already present before this PR - the diff only shows indentation changes, not changes to the actual text content of the warning messages.

Workflow ID: wflow_zz4JwwNGgCoTsZsS

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.


# Final reminder to insert build token
print_warning "ΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉ"
print_warning "⚠️ FINAL REMINDER: Insert build token into Supabase!"
Copy link

Choose a reason for hiding this comment

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

Final warning messages contain unexpected encoding artifacts; please fix these to ensure clear output.

Suggested change
print_warning "⚠️ FINAL REMINDER: Insert build token into Supabase!"
print_warning "FINAL REMINDER: Insert build token into Supabase!"

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: 12

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/check-todos-hook.sh (1)

8-27: Critical: Regex pattern requires -P flag for negative lookahead.

The negative lookahead (?!.*#[0-9]+) requires Perl-compatible regex (PCRE), but the command uses -E (extended regex) instead of -P. Without the -P flag, the pattern won't work as intended and the hook will fail to catch TODOs without issue references.

This is a pre-existing bug, but since this PR focuses on CI/CD improvements, it's critical to fix this hook to ensure it functions correctly.

🔎 Proposed fix
-if grep -rEn "(//|/\*|#)\s*(TODO|FIXME|HACK|XXX|BUG|REFACTOR|OPTIMIZE)(?!.*#[0-9]+)" \
+if grep -rPn "(//|/\*|#)\s*(TODO|FIXME|HACK|XXX|BUG|REFACTOR|OPTIMIZE)(?!.*#[0-9]+)" \

Alternatively, if PCRE support is not available on all systems, rewrite using a two-step approach with extended regex:

-if grep -rEn "(//|/\*|#)\s*(TODO|FIXME|HACK|XXX|BUG|REFACTOR|OPTIMIZE)(?!.*#[0-9]+)" \
+if grep -rEn "(//|/\*|#)\s*(TODO|FIXME|HACK|XXX|BUG|REFACTOR|OPTIMIZE)" \
     --include="*.swift" \
     --include="*.kt" \
     --include="*.java" \
@@ -30,7 +30,8 @@
     grep -v ".build/" | \
     grep -v "build/" | \
     grep -v "DerivedData/" | \
-    grep -v "scripts/check-todos-hook.sh"; then
+    grep -v "scripts/check-todos-hook.sh" | \
+    grep -vE "#[0-9]+"; then

Note: The second approach finds all TODOs and then filters out those that contain issue references.

🧹 Nitpick comments (7)
.github/workflows/react-native-sdk.yml (1)

20-50: Consider adding dependency caching for faster builds.

The workflow caches yarn dependencies but not CocoaPods or Gradle dependencies. Adding caching for these would significantly speed up build times.

🔎 Example CocoaPods caching for iOS job
     - name: Install dependencies
       working-directory: ./sdk/runanywhere-react-native
       run: yarn install --frozen-lockfile

+    - name: Cache CocoaPods
+      uses: actions/cache@v4
+      with:
+        path: sdk/runanywhere-react-native/ios/Pods
+        key: ${{ runner.os }}-pods-${{ hashFiles('sdk/runanywhere-react-native/ios/Podfile.lock') }}
+        restore-keys: |
+          ${{ runner.os }}-pods-
+
     - name: Build iOS

Example Gradle caching for Android job:

     - name: Install dependencies
       working-directory: ./sdk/runanywhere-react-native
       run: yarn install --frozen-lockfile

+    - name: Cache Gradle
+      uses: actions/cache@v4
+      with:
+        path: |
+          ~/.gradle/caches
+          ~/.gradle/wrapper
+        key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
+        restore-keys: |
+          ${{ runner.os }}-gradle-
+
     - name: Build Android

Also applies to: 57-84, 91-115

.github/dependabot.yml (1)

42-52: Consider adding Swift Package Manager ecosystem for iOS SDK.

The iOS SDK at sdk/runanywhere-swift uses Swift Package Manager but isn't covered by Dependabot. You could add:

  # Enable version updates for Swift (iOS SDK)
  - package-ecosystem: "swift"
    directory: "/sdk/runanywhere-swift"
    schedule:
      interval: "weekly"
    open-pull-requests-limit: 5
    labels:
      - "dependencies"
      - "ios"
    commit-message:
      prefix: "chore"
      include: "scope"
sdk/runanywhere-kotlin/build.gradle.kts (1)

200-201: Hard dependency on testDebugUnitTest may fail if task doesn't exist.

The dependsOn("jvmTest", "testDebugUnitTest") assumes testDebugUnitTest always exists. While lines 214-217 handle execution data conditionally, the hard dependsOn will fail if the task is absent.

Consider making the dependency conditional:

🔎 Proposed fix
 tasks.register<org.gradle.testing.jacoco.tasks.JacocoReport>("jacocoTestReport") {
-    dependsOn("jvmTest", "testDebugUnitTest")
+    dependsOn("jvmTest")
+    
+    // Conditionally depend on Android unit tests if available
+    tasks.findByName("testDebugUnitTest")?.let { dependsOn(it) }
.github/workflows/release-artifacts.yml (3)

24-27: Quote VERSION variable to prevent word splitting.

The static analysis tool flagged SC2086. While unlikely to cause issues here, quoting ensures robustness.

Proposed fix
     - name: Extract version from tag
       id: version
       run: |
-        VERSION=${GITHUB_REF#refs/tags/ios/v}
+        VERSION="${GITHUB_REF#refs/tags/ios/v}"
         echo "version=$VERSION" >> $GITHUB_OUTPUT
         echo "Version: $VERSION"

82-85: Quote VERSION variable for consistency.

Same as the iOS job—quote the variable to prevent potential word splitting.

Proposed fix
     - name: Extract version from tag
       id: version
       run: |
-        VERSION=${GITHUB_REF#refs/tags/android/v}
+        VERSION="${GITHUB_REF#refs/tags/android/v}"
         echo "version=$VERSION" >> $GITHUB_OUTPUT
         echo "Version: $VERSION"

98-121: Reconsider if: always() for artifact uploads and release attachment.

Using if: always() means these steps run even if the build fails, potentially uploading incomplete artifacts or causing the release step to fail with missing files. Consider using if: success() (default) or checking specific step outcomes.

Proposed fix
     - name: Upload JAR artifact
       uses: actions/upload-artifact@v4
-      if: always()
       with:
         name: android-jar-${{ steps.version.outputs.version }}
         path: sdk/runanywhere-kotlin/build/libs/*.jar
         retention-days: 90

     - name: Upload AAR artifact
       uses: actions/upload-artifact@v4
-      if: always()
       with:
         name: android-aar-${{ steps.version.outputs.version }}
         path: sdk/runanywhere-kotlin/build/outputs/aar/*.aar
         retention-days: 90

     - name: Attach artifacts to GitHub Release
       uses: softprops/action-gh-release@v2
-      if: always()
       with:
         files: |
           sdk/runanywhere-kotlin/build/libs/*.jar
           sdk/runanywhere-kotlin/build/outputs/aar/*.aar
       env:
         GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
scripts/release_android_sdk.sh (1)

215-233: Indentation issue and missing directory restoration on failure.

Line 216 has inconsistent indentation. More critically, if the build or test fails, the script exits without returning to the original directory (the cd - on line 232 won't execute). Consider using a subshell or trap to ensure cleanup.

Based on learnings, consider using ./scripts/sdk.sh for Kotlin SDK operations if available, as it handles configuration and build complexity.

Proposed fix using subshell
 run_tests() {
     if [[ $SKIP_BUILD -eq 1 ]]; then
         print_warning "Skipping build check (--skip-build flag)"
         return
     fi

     print_header "Building and Testing"

     print_info "Running Gradle build..."
-        cd "$SDK_DIR" || { print_error "Failed to change to $SDK_DIR"; exit 1; }
-    if ./gradlew build --no-daemon; then
-        print_success "Build successful"
-    else
-        print_error "Build failed"
-        exit 1
-    fi
-
-    print_info "Running tests..."
-    if ./gradlew test --no-daemon; then
-        print_success "All tests passed"
-    else
-        print_error "Tests failed"
-        exit 1
-    fi
-
-    cd - >/dev/null
+    (
+        cd "$SDK_DIR" || { print_error "Failed to change to $SDK_DIR"; exit 1; }
+        if ! ./gradlew build --no-daemon; then
+            print_error "Build failed"
+            exit 1
+        fi
+        print_success "Build successful"
+
+        print_info "Running tests..."
+        if ! ./gradlew test --no-daemon; then
+            print_error "Tests failed"
+            exit 1
+        fi
+        print_success "All tests passed"
+    )
 }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 420b89c and eb160e0.

📒 Files selected for processing (13)
  • .github/dependabot.yml
  • .github/workflows/android-app.yml
  • .github/workflows/android-sdk.yml
  • .github/workflows/flutter-sdk.yml
  • .github/workflows/integration-tests.yml
  • .github/workflows/react-native-sdk.yml
  • .github/workflows/release-artifacts.yml
  • .pre-commit-config.yaml
  • scripts/check-todos-hook.sh
  • scripts/lint-android.sh
  • scripts/release_android_sdk.sh
  • scripts/release_ios_sdk.sh
  • sdk/runanywhere-kotlin/build.gradle.kts
🧰 Additional context used
📓 Path-based instructions (1)
sdk/runanywhere-kotlin/**/*.gradle.kts

📄 CodeRabbit inference engine (CLAUDE.md)

sdk/runanywhere-kotlin/**/*.gradle.kts: Kotlin version must be 2.1.21 or later for the Kotlin Multiplatform SDK.
JVM target must be 17 or later for Kotlin Multiplatform SDK.
Android minSdk must be 24 or later for Kotlin Multiplatform SDK.

Files:

  • sdk/runanywhere-kotlin/build.gradle.kts
🧠 Learnings (16)
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/androidMain/**/*.kt : Use platform-specific optimizations in their respective source directories: `androidMain/` for Android optimizations, `jvmMain/` for JVM optimizations.

Applied to files:

  • scripts/lint-android.sh
  • .github/workflows/android-sdk.yml
  • sdk/runanywhere-kotlin/build.gradle.kts
  • .github/workflows/android-app.yml
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/jvmMain/**/*.kt : Use platform-specific optimizations in their respective source directories: `androidMain/` for Android optimizations, `jvmMain/` for JVM optimizations.

Applied to files:

  • scripts/lint-android.sh
  • .github/workflows/android-sdk.yml
  • sdk/runanywhere-kotlin/build.gradle.kts
  • .github/workflows/android-app.yml
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/*.kt : Always use data classes and structured types (enums, sealed classes) instead of strings for models and configuration.

Applied to files:

  • scripts/lint-android.sh
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/*.kt : Use coroutines and suspend functions instead of async/await patterns for asynchronous operations.

Applied to files:

  • scripts/lint-android.sh
  • sdk/runanywhere-kotlin/build.gradle.kts
  • .github/workflows/android-app.yml
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/*.kt : Use `expect/actual` ONLY for platform-specific implementations, not for business logic. Put all business logic in `commonMain/`.

Applied to files:

  • scripts/lint-android.sh
  • sdk/runanywhere-kotlin/build.gradle.kts
  • .github/workflows/android-app.yml
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/*.kt : Use sealed classes for type-safe error handling in Kotlin code.

Applied to files:

  • scripts/lint-android.sh
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/*.gradle.kts : Android minSdk must be 24 or later for Kotlin Multiplatform SDK.

Applied to files:

  • scripts/lint-android.sh
  • sdk/runanywhere-kotlin/build.gradle.kts
  • .github/workflows/android-app.yml
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Use `./scripts/sdk.sh` for all Kotlin SDK operations instead of calling Gradle directly. It handles configuration and build complexity.

Applied to files:

  • scripts/lint-android.sh
  • scripts/release_android_sdk.sh
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/*.gradle.kts : Kotlin version must be 2.1.21 or later for the Kotlin Multiplatform SDK.

Applied to files:

  • scripts/lint-android.sh
  • sdk/runanywhere-kotlin/build.gradle.kts
  • .github/workflows/android-app.yml
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/*.gradle.kts : JVM target must be 17 or later for Kotlin Multiplatform SDK.

Applied to files:

  • scripts/lint-android.sh
  • sdk/runanywhere-kotlin/build.gradle.kts
  • .github/workflows/android-app.yml
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/*.kt : Use the `ModuleRegistry` provider pattern for extensibility and plugin architecture instead of hard-coded dependencies.

Applied to files:

  • sdk/runanywhere-kotlin/build.gradle.kts
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/components/**/*.kt : Implement proper component lifecycle management with initialization, state tracking, and cleanup in BaseComponent.

Applied to files:

  • sdk/runanywhere-kotlin/build.gradle.kts
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/*.kt : Use lazy initialization for service dependencies to avoid memory pressure and allow garbage collection.

Applied to files:

  • sdk/runanywhere-kotlin/build.gradle.kts
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Run pre-commit hooks for code quality enforcement before committing code.

Applied to files:

  • .pre-commit-config.yaml
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/*.kt : Use Flow instead of AsyncSequence for reactive streams in Kotlin Multiplatform code.

Applied to files:

  • .github/workflows/android-app.yml
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/*.kt : All business logic, protocols, interfaces, and structures MUST be defined in `commonMain/` for Kotlin Multiplatform projects. Platform-specific implementations must use clear prefixes like `AndroidTTSService.kt`, `JvmTTSService.kt`, etc.

Applied to files:

  • .github/workflows/android-app.yml
🧬 Code graph analysis (1)
scripts/release_android_sdk.sh (2)
scripts/release_ios_sdk.sh (13)
  • print_error (20-20)
  • print_header (18-18)
  • print_info (22-22)
  • print_warning (21-21)
  • print_success (19-19)
  • sedi (34-42)
  • validate_preconditions (85-148)
  • get_current_version (151-157)
  • calculate_new_version (160-186)
  • run_tests (302-325)
  • update_version_references (239-271)
  • main (357-530)
  • create_github_release (328-354)
sdk/runanywhere-swift/Sources/RunAnywhere/Foundation/Logging/Services/LogBatcher.swift (1)
  • add (45-54)
🪛 actionlint (1.7.9)
.github/workflows/release-artifacts.yml

24-24: shellcheck reported issue in this script: SC2086:info:2:28: Double quote to prevent globbing and word splitting

(shellcheck)


82-82: shellcheck reported issue in this script: SC2086:info:2:28: Double quote to prevent globbing and word splitting

(shellcheck)


115-115: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Greptile Review
🔇 Additional comments (23)
scripts/check-todos-hook.sh (1)

1-1: Good portability improvement!

The change from #!/bin/bash to #!/usr/bin/env bash improves portability by locating bash through the PATH environment variable rather than assuming a hardcoded location. This is a best practice for shell scripts.

.github/workflows/react-native-sdk.yml (1)

82-82: No action needed. iPhone 16 with iOS 18.1 simulators are available in GitHub Actions macOS runners with Xcode 16, and the destination specification is supported.

scripts/lint-android.sh (2)

32-32: LGTM! Path migration to runanywhere-kotlin is consistent.

The SDK path and report paths are correctly updated to reflect the migration from runanywhere-android to runanywhere-kotlin. This aligns with the broader repository changes and the pre-commit hook configuration.

Also applies to: 41-41, 52-52


56-56: Visual output updates look good.

The separator characters and status indicators are updated consistently throughout the script.

Also applies to: 84-84, 88-90

.github/workflows/android-app.yml (2)

26-30: JDK 17 upgrade aligns with coding guidelines.

The upgrade from JDK 11 to JDK 17 with Temurin distribution is correct per the coding guidelines requiring JVM target 17 or later for the Kotlin Multiplatform SDK.


42-49: Build order and permissions are correctly configured.

The workflow correctly grants execute permissions to both Gradle wrappers and builds the SDK before the example app, ensuring proper dependency resolution.

.github/workflows/integration-tests.yml (3)

55-58: The continue-on-error: true on tests is intentional.

Per the PR description, known code errors exist and CI is expected to detect them. This configuration allows the workflow to complete while still surfacing test failures in the logs.


114-116: yarn.lock file path is valid. The file exists at sdk/runanywhere-react-native/yarn.lock, confirming the cache configuration will work correctly.


143-147: Version 3.38.1 is valid and legitimate.

Flutter 3.38.1 was released to the stable channel on November 13, 2025, and is an appropriate choice for a workflow running in January 2026. No issue with this version specification.

Likely an incorrect or invalid review comment.

.github/workflows/flutter-sdk.yml (2)

24-28: Flutter version 3.38.1 needs verification (same as integration-tests.yml).

This is the same Flutter version flagged in the integration-tests workflow. Pending verification of whether this version exists.


42-67: Build jobs correctly depend on analyze-and-format.

The job dependency ensures code quality checks pass before attempting platform builds. The continue-on-error: true on builds allows the workflow to complete even with expected build issues.

.github/dependabot.yml (1)

1-52: Well-structured Dependabot configuration.

The configuration covers npm, pub, gradle, and github-actions ecosystems with appropriate schedules, PR limits, and labels.

sdk/runanywhere-kotlin/build.gradle.kts (2)

184-189: Good addition of Android test resources.

Enabling isIncludeAndroidResources = true allows unit tests to access Android resources, which is useful for testing resource-dependent code.


192-198: No action required. Kotlin version in gradle/libs.versions.toml is 2.1.21, which meets the ≥2.1.21 requirement for the Kotlin Multiplatform SDK.

.github/workflows/android-sdk.yml (2)

20-41: Solid CI setup with JDK 17 and Gradle caching.

The workflow correctly configures JDK 17 (per coding guidelines), implements Gradle caching for faster builds, and grants execute permissions to the Gradle wrapper.


43-70: Comprehensive lint, build, and test sequence.

The workflow correctly orders steps: static analysis (Detekt, Lint) → builds (JVM, Android) → tests (JVM, Android) → coverage. The continue-on-error: true on JaCoCo allows the workflow to complete even if coverage generation fails.

.pre-commit-config.yaml (1)

36-43: LGTM!

The Android App Lint hook correctly references local.properties relative to its working directory and appropriately skips when prerequisites are missing.

scripts/release_android_sdk.sh (4)

136-142: LGTM!

The version extraction logic correctly parses the version from build.gradle.kts with a sensible fallback.


253-259: Consider whether --latest flag is appropriate for multi-SDK repository.

The --latest flag marks this release as the repository's latest. Since the repo contains both iOS and Android SDKs, this could cause the "latest" badge to alternate between platforms. Consider removing --latest or using platform-specific release strategies.


44-78: LGTM!

CLI argument parsing is robust with proper validation for required values and helpful usage information.


333-343: Direct push to main will fail if the branch is protected; ensure branch protection rules allow force-free pushes or document this prerequisite.

The script has set -euo pipefail (line 6), so git commands that fail will cause the script to exit immediately. However, if main is protected and requires PRs or status checks, git push origin main (line 335) will fail without recovery. Either document that branch protection must allow direct pushes from this script's identity, or implement alternative handling for protected branches.

scripts/release_ios_sdk.sh (2)

492-497: LGTM!

Good security practice: the build token is only printed when running interactively (-t 1 checks for TTY), preventing accidental exposure in CI logs.


438-479: LGTM!

The worktree-based approach for creating release tags with BuildToken.swift is well-designed. It ensures the token file only exists in release tags while keeping main clean, with proper cleanup afterward.

Comment on lines 61 to 62
- name: Select Xcode version
run: sudo xcode-select -s /Applications/Xcode_16.1.app
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's view the workflow file to understand the full context
cat -n .github/workflows/react-native-sdk.yml | sed -n '55,85p'

Repository: RunanywhereAI/runanywhere-sdks

Length of output: 1187


🌐 Web query:

GitHub Actions macos-latest Xcode 16.1 availability 2025

💡 Result:

Short answer: Yes — Xcode 16.1 is available on GitHub-hosted macOS images in 2025, and macos-latest will point to macos-15 (which includes Xcode 16.1) when that switch happens.

Details:

  • On Jan 6, 2025 GitHub replaced Xcode 16.0 with Xcode 16.2 on macOS-14 images (they advised upgrading to 16.1/16.2). [1]
  • The macOS-15 images include Xcode 16.1 (and other 16.x minors); GitHub announced macos-latest will use macos-15 starting August 2025, so macos-latest will include Xcode 16.1 after that change. [2][3]

If you need to target Xcode 16.1 immediately, pin the runner to a macOS image that lists 16.1 (or use the setup-xcode action to select an installed Xcode version). [4]

Sources:
[1] GitHub Changelog — Xcode 16.2 will replace Xcode 16.0 in macOS-14 images (Jan 6, 2025).
[2] actions/runner-images — macOS-15: Add Xcode 16.1 final version.
[3] actions/runner-images — macos-latest will use macos-15 in August 2025.
[4] setup-xcode / xcode-select actions (use to choose installed Xcode versions).


🌐 Web query:

iOS simulator iPhone 16 OS 18.1 availability macos-latest

💡 Result:

Short answer: Yes — the iOS 18.x simulator runtime (e.g. iphonesimulator18.1 / iphonesimulator18.2) is provided on current GitHub-hosted macOS runner images when the installed Xcode includes the iOS 18 SDK (Xcode 16.1/16.2+). Use a macOS runner with an Xcode 16.x image (macos-14 or macos-15 images include Xcode 16.x variants), or install the simulator runtime at job start with xcodebuild -downloadPlatform iOS. [1][2][3]

References

  • Apple Xcode / SDK support (Xcode 16.1 lists iOS 18.1). [1]
  • actions/runner-images release notes showing iOS 18 simulator (iphonesimulator18.2) on macOS images with Xcode 16.2. [2]
  • GitHub Actions changelog / image policy noting Xcode 16.x on macOS images. [3]

If you want, tell me which runner label you’re using (macos-latest, macos-14, or macos-15) and I’ll confirm the exact installed Xcode and available simulator identifier for that image.


🏁 Script executed:

# Check the full build-ios job definition, including the runner specification
cat -n .github/workflows/react-native-sdk.yml | sed -n '50,90p'

Repository: RunanywhereAI/runanywhere-sdks

Length of output: 1462


Fix hard-coded Xcode version that is unavailable on macos-latest runners.

The workflow fails on the current macos-latest runner (macOS-14) because Xcode 16.1 is not installed—only Xcode 16.0 and 16.2 are available. Xcode 16.1 is present only on macOS-15 images. Either pin the runner to macos-15, use actions/setup-xcode@v2 to install an available Xcode version, or switch to a version that exists on the runner. Note that continue-on-error: true on line 84 silently masks the build failure.

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Additional Comments (9)

  1. .github/dependabot.yml, line 52 (link)

    syntax: missing newline at end of file

  2. .github/workflows/flutter-sdk.yml, line 27 (link)

    logic: Flutter version 3.38.1 appears to be invalid - latest stable Flutter versions follow semantic versioning like 3.24.x

  3. scripts/release_android_sdk.sh, line 260 (link)

    logic: The hardcoded GitHub URL uses 'RunanywhereAI/sdks' but should match the actual repository name 'RunanywhereAI/runanywhere-sdks'

  4. scripts/release_android_sdk.sh, line 353 (link)

    logic: GitHub URL in release verification message should match actual repository name 'RunanywhereAI/runanywhere-sdks'

  5. .github/workflows/release-artifacts.yml, line 49-54 (link)

    logic: XCFramework creation assumes specific archive structure that may not match SPM builds. Consider verifying the framework paths exist before attempting to create XCFramework. Should there be verification that the framework files exist at the expected paths before attempting to create the XCFramework?

  6. .github/workflows/release-artifacts.yml, line 32-46 (link)

    logic: iOS builds missing dependency resolution step. SPM packages typically need swift package resolve or similar before building.

  7. .github/workflows/release-artifacts.yml, line 115-116 (link)

    logic: GitHub Release creation will run even if artifact builds fail due to if: always(). Consider using if: success() to only create releases for successful builds.

  8. .github/workflows/integration-tests.yml, line 146 (link)

    syntax: Flutter version '3.38.1' appears to be invalid - Flutter versions don't go that high. Should likely be '3.24.1' or similar

  9. .github/workflows/integration-tests.yml, line 88 (link)

    logic: iPhone 16 with OS 18.1 may not be available in CI environment. Consider using a more conservative simulator like iPhone 15 with iOS 17.x

13 files reviewed, 9 comments

Edit Code Review Agent Settings | Greptile

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: 3

♻️ Duplicate comments (2)
scripts/release_ios_sdk.sh (2)

77-80: Past review issue addressed.

Unknown arguments now correctly exit with an error instead of continuing. This prevents unexpected behavior from typos.


510-513: Past UTF-8 issues addressed.

The box-drawing characters are now properly rendered Unicode (═) instead of corrupted sequences.

🧹 Nitpick comments (11)
scripts/check-todos-hook.sh (1)

35-35: Refine the GitHub issue reference pattern.

The pattern #[0-9]+ will match any hash followed by digits anywhere in the line, not just GitHub issue references. This could inadvertently filter out TODOs that mention numbers in other contexts (e.g., "TODO: Fix bug in section #3 of the algorithm"). Consider anchoring the pattern to comment syntax or using word boundaries.

🔎 Proposed refinement
-    grep -vE "#[0-9]+"; then
+    grep -vE "(//|/\*|#)\s*(TODO|FIXME|HACK|XXX|BUG|REFACTOR|OPTIMIZE)[^#]*#[0-9]+"; then

This ensures the pattern matches comment markers followed by the TODO keyword and then a GitHub issue reference later in the line.

.github/workflows/release-artifacts.yml (3)

24-27: Quote the variable expansion to prevent word splitting.

The shellcheck warning is valid: $GITHUB_REF should be quoted to prevent globbing and word splitting, even though in practice GitHub Actions sets this variable to a controlled value.

🔎 Proposed fix
       run: |
-        VERSION="${GITHUB_REF#refs/tags/ios/v}"
+        VERSION="${GITHUB_REF##refs/tags/ios/v}"
         echo "version=$VERSION" >> $GITHUB_OUTPUT
         echo "Version: $VERSION"

Note: Also changed # to ## for greedy prefix removal, which is more robust.


101-104: Quote the variable expansion to prevent word splitting.

Same shellcheck issue as the iOS job: quote $GITHUB_REF for safety.

🔎 Proposed fix
       run: |
-        VERSION="${GITHUB_REF#refs/tags/android/v}"
+        VERSION="${GITHUB_REF##refs/tags/android/v}"
         echo "version=$VERSION" >> $GITHUB_OUTPUT
         echo "Version: $VERSION"

133-141: Consider checking build step outcomes explicitly.

Using if: success() checks that all previous steps succeeded, but doesn't distinguish between build failures and other step failures. If the JDK setup or checkout fails, the artifacts won't exist, but the condition won't tell you why.

Alternative approach
     - name: Attach artifacts to GitHub Release
       uses: softprops/action-gh-release@v2
-      if: success()
+      if: success() && hashFiles('sdk/runanywhere-kotlin/build/libs/*.jar') != ''
       with:

This adds an explicit check that the artifact files exist before attempting to attach them.

scripts/release_android_sdk.sh (3)

213-231: Consider using ./scripts/sdk.sh instead of direct Gradle invocation.

Based on learnings, Kotlin SDK operations should use ./scripts/sdk.sh rather than calling Gradle directly, as it handles configuration and build complexity.

🔎 Proposed change
     print_info "Running Gradle build..."
     (
         cd "$SDK_DIR" || { print_error "Failed to change to $SDK_DIR"; exit 1; }
-        if ! ./gradlew build --no-daemon; then
+        if ! ../../scripts/sdk.sh build; then
             print_error "Build failed"
             exit 1
         fi
         print_success "Build successful"

         print_info "Running tests..."
-        if ! ./gradlew test --no-daemon; then
+        if ! ../../scripts/sdk.sh test; then
             print_error "Tests failed"
             exit 1
         fi

Verify that scripts/sdk.sh supports build and test commands before making this change.

Based on learnings, the Kotlin SDK should use the sdk.sh wrapper script for operations.


135-142: Version extraction pattern may be fragile.

The grep pattern assumes version = "X.Y.Z" format with specific spacing and quotes. If the build.gradle.kts format changes (e.g., using single quotes or different spacing), the extraction will fail silently and fall back to "0.1.0".

More robust approach
 get_current_version() {
     if [[ -f "$BUILD_FILE" ]]; then
-        grep -E "^\s*version\s*=" "$BUILD_FILE" | sed -E 's/.*version\s*=\s*"([^"]+)".*/\1/' | head -1
+        local version
+        version=$(grep -E "^\s*version\s*=\s*[\"']" "$BUILD_FILE" | sed -E "s/.*version[[:space:]]*=[[:space:]]*[\"']([^\"']+)[\"'].*/\1/" | head -1)
+        if [[ -z "$version" ]]; then
+            print_error "Could not extract version from $BUILD_FILE"
+            exit 1
+        fi
+        echo "$version"
     else
         echo "0.1.0"  # Fallback
     fi
 }

This accepts both single and double quotes, and fails explicitly if version extraction fails rather than silently using a fallback.


186-195: Maven coordinate pattern may be overly broad.

The regex com\.runanywhere\.sdk:[^:]*:[0-9]*\.[0-9]*\.[0-9]* will match any Maven coordinate under the com.runanywhere.sdk group, potentially updating unintended dependencies if multiple SDK artifacts are referenced.

More specific pattern
     # Update root README.md (if it has Android version references)
     if [[ -f "$README_ROOT" ]]; then
-        sedi "s/com\.runanywhere\.sdk:[^:]*:[0-9]*\.[0-9]*\.[0-9]*/com.runanywhere.sdk:runanywhere-kotlin:$new_version/g" "$README_ROOT" || true
+        sedi "s/com\.runanywhere\.sdk:runanywhere-kotlin:[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}/com.runanywhere.sdk:runanywhere-kotlin:$new_version/g" "$README_ROOT" || true
         print_success "Updated $README_ROOT"
     fi

This specifically targets the runanywhere-kotlin artifact and uses bounded repetition for more precise matching.

.github/workflows/react-native-sdk.yml (1)

79-83: Consider using dynamic simulator selection for resilience.

The hardcoded destination 'platform=iOS Simulator,name=iPhone 16,OS=18.1' works with Xcode 16.2 on macos-latest, which includes the iPhone 16 simulator with iOS 18.1. However, hardcoding simulator names reduces resilience to future Xcode version changes. The build step has continue-on-error: true, but it's better to use xcrun simctl to detect available simulators and select one dynamically, or list the first available iPhone simulator instead of depending on a specific model.

.pre-commit-config.yaml (1)

36-43: Inconsistent path style for local.properties.

The SDK lint hook uses ./local.properties while this hook uses local.properties (without ./). While functionally equivalent, consider using the same style for consistency.

Proposed fix
       - id: android-app-lint
         name: Android App Lint
-        entry: bash -c 'cd examples/android/RunAnywhereAI && if [ -f "./gradlew" ] && [ -n "$ANDROID_HOME" -o -f "local.properties" ]; then ./gradlew :app:lint --quiet; else echo "Skipping Android lint (no gradle or SDK)"; exit 0; fi'
+        entry: bash -c 'cd examples/android/RunAnywhereAI && if [[ -f "./gradlew" ]] && [[ -n "$ANDROID_HOME" || -f "./local.properties" ]]; then ./gradlew :app:lint --quiet; else echo "Skipping Android lint (no gradle or SDK)"; exit 0; fi'
         language: system
         files: ^examples/android/RunAnywhereAI/.*\.(kt|kts|java|xml)$
         pass_filenames: false
scripts/release_ios_sdk.sh (2)

206-233: Past UTF-8 issues addressed; indentation inconsistency in generated file.

The corrupted UTF-8 characters have been replaced with ASCII "WARNING:". However, the generated Swift file has inconsistent indentation: the static let is indented with 8 spaces while Swift convention is 4 spaces inside an enum.

Proposed fix for indentation
 enum BuildToken {
-        /// Development mode build token
-        /// Generated at: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
-        static let token = "$build_token"
+    /// Development mode build token
+    /// Generated at: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
+    static let token = "$build_token"
 }

476-479: Worktree cleanup could leave orphaned branch on failure.

If git worktree remove fails, the script exits (due to set -e) before deleting the branch, leaving an orphaned release branch. Consider using a trap for cleanup.

Proposed fix with trap-based cleanup
+    # Set up cleanup trap
+    cleanup_worktree() {
+        if [[ -d "$worktree_dir" ]]; then
+            git worktree remove "$worktree_dir" --force 2>/dev/null || true
+        fi
+        git branch -D "$release_branch" 2>/dev/null || true
+    }
+    trap cleanup_worktree EXIT
+
     # Create worktree
     git worktree add -b "$release_branch" "$worktree_dir"

Then remove the explicit cleanup at the end and let the trap handle it.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eb160e0 and 8100524.

📒 Files selected for processing (9)
  • .github/workflows/android-sdk.yml
  • .github/workflows/flutter-sdk.yml
  • .github/workflows/integration-tests.yml
  • .github/workflows/react-native-sdk.yml
  • .github/workflows/release-artifacts.yml
  • .pre-commit-config.yaml
  • scripts/check-todos-hook.sh
  • scripts/release_android_sdk.sh
  • scripts/release_ios_sdk.sh
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/android-sdk.yml
  • .github/workflows/flutter-sdk.yml
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/androidMain/**/*.kt : Use platform-specific optimizations in their respective source directories: `androidMain/` for Android optimizations, `jvmMain/` for JVM optimizations.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/*.kt : Use coroutines and suspend functions instead of async/await patterns for asynchronous operations.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/jvmMain/**/*.kt : Use platform-specific optimizations in their respective source directories: `androidMain/` for Android optimizations, `jvmMain/` for JVM optimizations.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/*.gradle.kts : Kotlin version must be 2.1.21 or later for the Kotlin Multiplatform SDK.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/*.kt : Use the `ModuleRegistry` provider pattern for extensibility and plugin architecture instead of hard-coded dependencies.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/*.kt : Use Flow instead of AsyncSequence for reactive streams in Kotlin Multiplatform code.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/components/**/*.kt : Implement proper component lifecycle management with initialization, state tracking, and cleanup in BaseComponent.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Use `./scripts/sdk.sh` for all Kotlin SDK operations instead of calling Gradle directly. It handles configuration and build complexity.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/*.gradle.kts : JVM target must be 17 or later for Kotlin Multiplatform SDK.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/*.gradle.kts : Android minSdk must be 24 or later for Kotlin Multiplatform SDK.
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-swift/**/Package.swift : Swift minimum version must be 5.9 or later for iOS SDK.

Applied to files:

  • .github/workflows/react-native-sdk.yml
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-swift/**/Package.swift : iOS minimum deployment target must be 13.0 or later for Swift SDK.

Applied to files:

  • .github/workflows/react-native-sdk.yml
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Run pre-commit hooks for code quality enforcement before committing code.

Applied to files:

  • scripts/check-todos-hook.sh
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Use `./scripts/sdk.sh` for all Kotlin SDK operations instead of calling Gradle directly. It handles configuration and build complexity.

Applied to files:

  • scripts/release_android_sdk.sh
🪛 actionlint (1.7.9)
.github/workflows/release-artifacts.yml

24-24: shellcheck reported issue in this script: SC2086:info:2:28: Double quote to prevent globbing and word splitting

(shellcheck)


101-101: shellcheck reported issue in this script: SC2086:info:2:28: Double quote to prevent globbing and word splitting

(shellcheck)

🔇 Additional comments (23)
.github/workflows/release-artifacts.yml (2)

76-82: LGTM! Upload condition properly checks build success.

The artifact upload now correctly conditions on the build step's success, preventing incomplete artifacts from being uploaded. This addresses the previous review concern.


134-134: LGTM! Action updated to v2.

The workflow now uses softprops/action-gh-release@v2, addressing the previous static analysis concern about the outdated v1 runner.

.github/workflows/react-native-sdk.yml (4)

39-42: LGTM! TypeScript errors won't block downstream jobs.

The continue-on-error: true flag ensures that known TypeScript issues are detected but don't fail the workflow, aligning with the PR objectives.


53-55: LGTM! Native build jobs run independently.

Removing the needs: lint-and-build dependency allows the iOS build job to run in parallel and detect platform-specific issues even when lint/type checks fail. This is the correct approach for comprehensive CI coverage.


111-127: Good fallback handling for missing Gradle wrapper.

The workflow now gracefully handles the missing gradlew by attempting to generate it or skipping the build with a warning. This addresses the previous concern about build failures.


61-62: No action needed — Xcode 16.2 is available on GitHub-hosted macOS runners.

Xcode 16.2 is available on current macos-latest runners (macOS 15). GitHub confirmed Xcode 16.2 rolled out to macOS-14 images starting January 6, 2025, and is included in macOS-15 images. The workflow's xcode-select command is safe and will not fail due to unavailability.

.github/workflows/integration-tests.yml (2)

68-69: Verify Xcode 16.1 availability on macos-latest.

As noted in other workflows, Xcode 16.1 may not be available on current macos-latest (macOS-14) runners. GitHub replaced Xcode 16.0 with 16.2 in January 2025, and Xcode 16.1 is primarily available on macOS-15 images.

Consider pinning to macos-15 if Xcode 16.1 is required, or updating to Xcode 16.2:

Alternative approaches

Option 1: Pin to macOS-15

   ios-app:
     name: Test iOS Example App
-    runs-on: macos-latest
+    runs-on: macos-15

Option 2: Use Xcode 16.2

     - name: Select Xcode version
-      run: sudo xcode-select -s /Applications/Xcode_16.1.app
+      run: sudo xcode-select -s /Applications/Xcode_16.2.app

56-58: Appropriate use of continue-on-error for integration tests.

Using continue-on-error: true on integration test steps is appropriate, as it allows the workflow to complete and report results even when tests fail, providing visibility into all test outcomes.

scripts/release_android_sdk.sh (4)

1-7: LGTM! Good script structure and safety settings.

The script uses set -euo pipefail for robust error handling and includes clear documentation. The structure follows the iOS release script pattern, providing consistency across SDKs.


28-37: Excellent portable sed wrapper.

The sedi function properly handles GNU vs BSD sed differences, ensuring the script works on both Linux and macOS. This is a best practice for cross-platform shell scripts.


80-133: Comprehensive precondition validation.

The validation checks all necessary prerequisites: git repository state, clean working tree, correct branch, GitHub CLI availability and authentication, and build file existence. This prevents partial releases and provides clear error messages.


233-259: Good changelog extraction with appropriate fallback.

The script extracts release notes from the CHANGELOG and provides a sensible fallback if parsing fails. The GitHub CLI invocation is clean and uses appropriate flags.

.pre-commit-config.yaml (3)

23-24: LGTM!

Enabling pass_filenames: true with types: [text] allows the TODO checker to process only changed files, improving efficiency over checking all files.


26-34: Path fix looks good; minor shell operator concern.

The ./local.properties path is now correct (addressing the prior review). However, the -o operator inside [ ] is deprecated. Consider using || with [[ ]] for clarity and POSIX compliance.

Also, based on learnings, the project recommends using ./scripts/sdk.sh for Kotlin SDK operations instead of calling Gradle directly. Verify if lint should go through that script.

Optional improvement for shell syntax
       - id: android-sdk-lint
         name: Android SDK Lint
-        entry: bash -c 'cd sdk/runanywhere-kotlin && if [ -f "./gradlew" ] && [ -n "$ANDROID_HOME" -o -f "./local.properties" ]; then ./gradlew lint --quiet; else echo "Skipping Android lint (no gradle or SDK)"; exit 0; fi'
+        entry: bash -c 'cd sdk/runanywhere-kotlin && if [[ -f "./gradlew" ]] && [[ -n "$ANDROID_HOME" || -f "./local.properties" ]]; then ./gradlew lint --quiet; else echo "Skipping Android lint (no gradle or SDK)"; exit 0; fi'
         language: system
         files: ^sdk/runanywhere-kotlin/.*\.(kt|kts|java|xml)$
         pass_filenames: false

70-75: LGTM!

Skipping platform-specific lint hooks in CI is appropriate since these require local toolchains (Android SDK, SwiftLint) that may not be available. The dedicated CI workflows handle this linting instead.

scripts/release_ios_sdk.sh (8)

34-42: LGTM!

The sedi function correctly handles GNU vs BSD sed differences. The version detection approach is reliable.


159-186: LGTM!

The version calculation logic correctly handles semantic versioning with proper reset of minor/patch components on major/minor bumps.


238-271: LGTM!

Version reference updates are comprehensive, covering VERSION file, READMEs, and CHANGELOG with proper sed patterns.


273-299: LGTM!

The SQL output for manual token insertion is clear and well-formatted. The security-sensitive information is appropriately highlighted.


301-325: LGTM!

Build verification is appropriate for pre-release validation. The TODO for adding tests is noted.


327-354: LGTM!

GitHub release creation is well-implemented with proper security note about not exposing the build token. The CHANGELOG extraction approach is reasonable for standard Keep a Changelog format.


492-497: Good security practice: masking token in CI.

Checking for interactive terminal (-t 1) before printing the token prevents accidental exposure in CI logs.


356-530: Well-structured release workflow.

The worktree-based approach for including BuildToken.swift only in release tags is a clean security pattern. The main branch stays clean while SPM users get the token via tags.

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

♻️ Duplicate comments (1)
scripts/release_ios_sdk.sh (1)

144-147: Fix syntax error in psql availability check.

Static analysis (SC1073/SC1072) indicates a parse error. The command substitution inside [[ ]] is incorrect - ! command -v psql >/dev/null should not be wrapped in the test brackets this way.

🔎 Proposed fix
     # Check for psql if DATABASE_URL is set
-    if [[ -n "${DATABASE_URL:-}" && ! command -v psql >/dev/null ]]; then
+    if [[ -n "${DATABASE_URL:-}" ]] && ! command -v psql >/dev/null; then
         print_warning "DATABASE_URL is set but psql not found (will print SQL for manual execution)"
     fi
🧹 Nitpick comments (4)
.github/workflows/react-native-sdk.yml (1)

75-91: Quote variables to prevent word splitting.

The simulator detection script has unquoted variable expansions that could cause issues with device names containing spaces. Static analysis flagged SC2086 on lines 77.

🔎 Proposed fix
     - name: Detect available iOS simulator
       id: detect-simulator
       run: |
         # Try to find an iPhone simulator with iOS 18.x runtime
-        SIMULATOR=$(xcrun simctl list devices available | grep -i "iPhone" | grep -i "iOS 18" | head -1 | sed -E 's/.*\(([^)]+)\).*/\1/' || echo "")
+        SIMULATOR="$(xcrun simctl list devices available | grep -i "iPhone" | grep -i "iOS 18" | head -1 | sed -E 's/.*\(([^)]+)\).*/\1/' || echo "")"
         if [[ -z "$SIMULATOR" ]]; then
           # Fallback to hardcoded value
           SIMULATOR="iPhone 16"
-          echo "Using fallback simulator: $SIMULATOR"
+          echo "Using fallback simulator: ${SIMULATOR}"
         else
-          echo "Detected simulator: $SIMULATOR"
+          echo "Detected simulator: ${SIMULATOR}"
         fi
         echo "simulator=$SIMULATOR" >> $GITHUB_OUTPUT
scripts/release_android_sdk.sh (1)

80-133: Consider adding SDK directory existence check.

The iOS release script checks for both Package.swift and $SDK_DIR directory at the start. This script only checks for $BUILD_FILE. Consider adding a check for the SDK directory to provide a clearer error message if run from the wrong location.

🔎 Proposed fix
 validate_preconditions() {
     print_header "Validating Preconditions"

+    # Must run at repo root
+    if [[ ! -d "$SDK_DIR" ]]; then
+        print_error "SDK directory not found: $SDK_DIR"
+        print_info "Must run from repository root"
+        exit 1
+    fi
+    print_success "Running from repository root"
+
     # Check if we're in a git repository
scripts/check-todos-hook.sh (1)

47-83: Consider adding additional directory exclusions.

The fallback search excludes common directories but might benefit from additional exclusions like vendor/, Pods/, and .dart_tool/ to avoid scanning third-party code.

🔎 Proposed fix
         grep -v ".git/" | \
         grep -v "node_modules/" | \
         grep -v ".build/" | \
         grep -v "build/" | \
         grep -v "DerivedData/" | \
+        grep -v "vendor/" | \
+        grep -v "Pods/" | \
+        grep -v ".dart_tool/" | \
         grep -v "scripts/check-todos-hook.sh" | \
.github/workflows/release-artifacts.yml (1)

133-144: Consider using find instead of ls for artifact counting.

Static analysis flags SC2012: ls can have issues with non-alphanumeric filenames. While unlikely for build artifacts, using find is more robust.

🔎 Proposed fix
     - name: Check artifacts exist
       id: check-artifacts
       run: |
-        JAR_FOUND=$(ls sdk/runanywhere-kotlin/build/libs/*.jar 2>/dev/null | wc -l)
-        AAR_FOUND=$(ls sdk/runanywhere-kotlin/build/outputs/aar/*.aar 2>/dev/null | wc -l)
+        JAR_FOUND=$(find sdk/runanywhere-kotlin/build/libs -name "*.jar" 2>/dev/null | wc -l)
+        AAR_FOUND=$(find sdk/runanywhere-kotlin/build/outputs/aar -name "*.aar" 2>/dev/null | wc -l)
         echo "jar_count=$JAR_FOUND" >> $GITHUB_OUTPUT
         echo "aar_count=$AAR_FOUND" >> $GITHUB_OUTPUT
-        if [ "$JAR_FOUND" -eq 0 ] && [ "$AAR_FOUND" -eq 0 ]; then
+        if [ "${JAR_FOUND}" -eq 0 ] && [ "${AAR_FOUND}" -eq 0 ]; then
           echo "Warning: No artifacts found to attach"
           exit 1
         fi
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8100524 and 30e2c3c.

📒 Files selected for processing (7)
  • .github/workflows/integration-tests.yml
  • .github/workflows/react-native-sdk.yml
  • .github/workflows/release-artifacts.yml
  • .pre-commit-config.yaml
  • scripts/check-todos-hook.sh
  • scripts/release_android_sdk.sh
  • scripts/release_ios_sdk.sh
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/androidMain/**/*.kt : Use platform-specific optimizations in their respective source directories: `androidMain/` for Android optimizations, `jvmMain/` for JVM optimizations.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/jvmMain/**/*.kt : Use platform-specific optimizations in their respective source directories: `androidMain/` for Android optimizations, `jvmMain/` for JVM optimizations.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/*.gradle.kts : Kotlin version must be 2.1.21 or later for the Kotlin Multiplatform SDK.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/*.kt : Use coroutines and suspend functions instead of async/await patterns for asynchronous operations.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/*.kt : Use the `ModuleRegistry` provider pattern for extensibility and plugin architecture instead of hard-coded dependencies.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/*.kt : Use Flow instead of AsyncSequence for reactive streams in Kotlin Multiplatform code.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Use `./scripts/sdk.sh` for all Kotlin SDK operations instead of calling Gradle directly. It handles configuration and build complexity.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/components/**/*.kt : Implement proper component lifecycle management with initialization, state tracking, and cleanup in BaseComponent.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/*.gradle.kts : Android minSdk must be 24 or later for Kotlin Multiplatform SDK.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/*.gradle.kts : JVM target must be 17 or later for Kotlin Multiplatform SDK.
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Run pre-commit hooks for code quality enforcement before committing code.

Applied to files:

  • scripts/check-todos-hook.sh
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Use `./scripts/sdk.sh` for all Kotlin SDK operations instead of calling Gradle directly. It handles configuration and build complexity.

Applied to files:

  • scripts/release_android_sdk.sh
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-swift/**/Package.swift : Swift minimum version must be 5.9 or later for iOS SDK.

Applied to files:

  • .github/workflows/react-native-sdk.yml
  • .github/workflows/integration-tests.yml
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-swift/**/Package.swift : iOS minimum deployment target must be 13.0 or later for Swift SDK.

Applied to files:

  • .github/workflows/react-native-sdk.yml
  • .github/workflows/integration-tests.yml
🧬 Code graph analysis (1)
scripts/release_android_sdk.sh (1)
scripts/release_ios_sdk.sh (13)
  • print_error (20-20)
  • print_header (18-18)
  • print_info (22-22)
  • print_warning (21-21)
  • print_success (19-19)
  • sedi (34-42)
  • validate_preconditions (91-154)
  • get_current_version (157-163)
  • calculate_new_version (166-192)
  • run_tests (308-331)
  • update_version_references (245-277)
  • main (363-551)
  • create_github_release (334-360)
🪛 actionlint (1.7.9)
.github/workflows/react-native-sdk.yml

77-77: shellcheck reported issue in this script: SC2086:info:10:32: Double quote to prevent globbing and word splitting

(shellcheck)


77-77: shellcheck reported issue in this script: SC2086:info:13:34: Double quote to prevent globbing and word splitting

(shellcheck)

.github/workflows/release-artifacts.yml

24-24: shellcheck reported issue in this script: SC2086:info:2:28: Double quote to prevent globbing and word splitting

(shellcheck)


101-101: shellcheck reported issue in this script: SC2086:info:2:28: Double quote to prevent globbing and word splitting

(shellcheck)


135-135: shellcheck reported issue in this script: SC2012:info:1:13: Use find instead of ls to better handle non-alphanumeric filenames

(shellcheck)


135-135: shellcheck reported issue in this script: SC2012:info:2:13: Use find instead of ls to better handle non-alphanumeric filenames

(shellcheck)


135-135: shellcheck reported issue in this script: SC2086:info:3:32: Double quote to prevent globbing and word splitting

(shellcheck)


135-135: shellcheck reported issue in this script: SC2086:info:4:32: Double quote to prevent globbing and word splitting

(shellcheck)

🪛 Shellcheck (0.11.0)
scripts/release_ios_sdk.sh

[error] 145-145: Couldn't parse this test expression. Fix to allow more checks.

(SC1073)


[error] 145-145: Expected test to end here (don't wrap commands in []/[[]]). Fix any mentioned problems and try again.

(SC1072)

🔇 Additional comments (23)
.github/workflows/integration-tests.yml (4)

1-16: LGTM! Well-structured workflow triggers.

The path-based triggers appropriately scope the workflow to SDK, examples, and workflow file changes, preventing unnecessary CI runs.


17-58: LGTM! Android integration test job is well-configured.

The job correctly sets up JDK 17 (as per learnings), implements proper Gradle caching, and follows the correct build order (SDK first, then example app). The continue-on-error: true on tests appropriately allows CI to report issues without blocking.


60-101: LGTM! iOS job correctly configured with available simulator runtime.

The iOS 18.1 simulator is available on macos-latest with Xcode 16.1, addressing the previous review concern about iOS 17.2 unavailability.


103-133: LGTM! React Native integration test job.

The job properly installs SDK dependencies first, builds the SDK, then validates the example app. The continue-on-error on type checking aligns with PR objectives noting known TypeScript errors.

.github/workflows/react-native-sdk.yml (2)

1-52: LGTM! Lint and build job properly configured.

The job correctly sets up Node.js, installs dependencies with frozen lockfile, and runs linting/type checking. The continue-on-error: true on TypeScript type check and Nitrogen bindings appropriately handles known issues per PR objectives.


103-144: LGTM! Android build job with appropriate fallbacks.

The job correctly handles the missing Gradle wrapper scenario by attempting to generate it, and gracefully skips the build with a warning if unavailable. JDK 17 aligns with the learnings requirement.

scripts/release_android_sdk.sh (5)

1-78: LGTM! Well-structured CLI argument parsing and configuration.

The script follows the iOS release script pattern with proper color definitions, portable sed wrapper, and comprehensive CLI argument handling including validation for missing --bump values.


135-159: LGTM! Robust version extraction.

The function handles both single and double-quoted version strings and validates the semver format, providing clear error messages on failure.


223-265: LGTM! Correctly uses sdk.sh wrapper per learnings.

The function appropriately prefers ./scripts/sdk.sh for Kotlin SDK operations as specified in the learnings, with a fallback to direct Gradle invocation when the wrapper is unavailable.


267-293: LGTM! GitHub release creation.

The function correctly extracts release notes from CHANGELOG with a fallback, and the tag format android/v* aligns with the release-artifacts.yml workflow triggers.


295-392: LGTM! Well-organized release flow.

The main function provides clear step-by-step progress with user confirmations, proper ordering (validate → test → commit → push main → tag → release), and helpful next steps guidance.

scripts/check-todos-hook.sh (2)

7-11: LGTM! Clear pattern definitions.

The TODO pattern captures common markers (TODO, FIXME, HACK, XXX, BUG, REFACTOR, OPTIMIZE) with various comment styles. The issue reference pattern requires #[0-9]+ format.


12-46: LGTM! Efficient per-file TODO checking.

The per-file processing correctly skips deleted files, filters by supported extensions, and provides consolidated error output with actionable guidance.

.github/workflows/release-artifacts.yml (3)

1-32: LGTM! Workflow triggers and version extraction.

The workflow correctly triggers on platform-specific tags and extracts versions using parameter expansion.


33-82: LGTM! XCFramework build with proper validation.

The build process correctly creates archives for both iOS and iOS Simulator with distribution settings, validates framework existence before XCFramework creation, and conditionally uploads only on success.


145-153: LGTM! Release attachment correctly configured.

The step uses the updated softprops/action-gh-release@v2 and only runs when both the build succeeded and artifacts exist.

.pre-commit-config.yaml (3)

16-24: LGTM! TODO hook updated for per-file processing.

The pass_filenames: true and types: [text] configuration enables efficient per-file TODO checking, aligning with the updated check-todos-hook.sh script.


26-43: LGTM! Android lint hooks with corrected paths.

The hooks correctly check for ./local.properties (addressing the past review), use appropriate conditionals for SDK availability, and gracefully skip when prerequisites are missing.


69-75: LGTM! Appropriate CI skip configuration.

The platform-specific lint hooks are correctly skipped in CI environments where the required tools (Android SDK, SwiftLint) may not be available. The dedicated CI workflows handle these checks instead.

scripts/release_ios_sdk.sh (4)

55-61: LGTM! Proper --bump argument validation.

The validation correctly checks for both missing values and flag-like arguments (starting with -), addressing the past review concern about shift 2 failing on missing arguments.


444-500: LGTM! Secure worktree-based release process.

The worktree approach elegantly ensures BuildToken.swift is only present in release tags, not in the main branch. The cleanup trap properly handles both success and error cases, and the security model is well-documented.


205-242: LGTM! Well-documented BuildToken.swift generation.

The generated file includes comprehensive security documentation explaining the token's purpose, lifecycle, and security model. The UTF-8 encoding issues from previous reviews have been addressed.


531-550: LGTM! Clear final reminders with security guidance.

The final summary provides clear operational guidance including the required Supabase SQL insertion, security reminders about token confidentiality, and links to the release. The box-drawing characters render correctly.

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: 5

🧹 Nitpick comments (4)
.github/workflows/integration-tests.yml (2)

42-58: Consider adding Gradle cache to improve build performance.

The Android app job is missing Gradle caching for the example app build steps, which will cause longer build times and unnecessary downloads on every run. While the SDK build has cache configured (lines 32-40), the example app at ./examples/android/RunAnywhereAI would benefit from the same optimization.

🔎 Proposed improvement

The existing cache configuration (lines 32-40) already covers both locations via the wildcard patterns, so this is actually working correctly. No changes needed—the cache key uses **/*.gradle* which will include the example app's Gradle files.


130-133: Type check command includes redundant fallback.

Line 132 runs yarn typecheck || npx tsc --noEmit with a fallback to npx tsc --noEmit. If yarn typecheck is properly configured in package.json to run TypeScript's type checker, the fallback is redundant and may cause confusion about which command is actually running. The continue-on-error: true already handles failures gracefully.

🔎 Proposed simplification
     - name: Type check example app
       working-directory: ./examples/react-native/RunAnywhereAI
-      run: yarn typecheck || npx tsc --noEmit
+      run: yarn typecheck
       continue-on-error: true
.github/workflows/flutter-sdk.yml (1)

24-32: Consider adding Flutter pub cache for faster dependency resolution.

The workflow doesn't cache Flutter pub dependencies, which means packages are downloaded fresh on every run. Adding cache for the .pub-cache directory would speed up the flutter pub get steps across all three jobs.

🔎 Proposed enhancement

Add this step after "Set up Flutter" in each job:

    - name: Cache Flutter dependencies
      uses: actions/cache@v4
      with:
        path: |
          ~/.pub-cache
        key: ${{ runner.os }}-flutter-pub-${{ hashFiles('**/pubspec.lock') }}
        restore-keys: |
          ${{ runner.os }}-flutter-pub-
.github/workflows/react-native-sdk.yml (1)

88-90: Hard-coded OS version may cause simulator compatibility issues.

The iOS version is hard-coded to 18.1 without verification that this runtime is actually available on the runner. If the detected simulator doesn't support iOS 18.1, the xcodebuild command will fail. Consider detecting the OS version from the available simulator runtime or using a more robust fallback strategy.

🔎 Proposed enhancement
         echo "simulator=$SIMULATOR" >> $GITHUB_OUTPUT
         # Determine OS version (default to 18.1)
-        OS_VERSION="18.1"
+        # Extract OS version from the detected simulator runtime
+        OS_VERSION="$(xcrun simctl list runtimes | grep -i "iOS" | grep -E "iOS [0-9]+\.[0-9]+" | head -1 | sed -E 's/.*iOS ([0-9]+\.[0-9]+).*/\1/' || echo '18.1')"
+        echo "Using OS version: ${OS_VERSION}"
         echo "os_version=$OS_VERSION" >> $GITHUB_OUTPUT
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 30e2c3c and 987c043.

📒 Files selected for processing (7)
  • .github/workflows/flutter-sdk.yml
  • .github/workflows/integration-tests.yml
  • .github/workflows/react-native-sdk.yml
  • .github/workflows/release-artifacts.yml
  • scripts/check-todos-hook.sh
  • scripts/release_android_sdk.sh
  • scripts/release_ios_sdk.sh
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/*.gradle.kts : Kotlin version must be 2.1.21 or later for the Kotlin Multiplatform SDK.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/androidMain/**/*.kt : Use platform-specific optimizations in their respective source directories: `androidMain/` for Android optimizations, `jvmMain/` for JVM optimizations.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/*.kt : Use coroutines and suspend functions instead of async/await patterns for asynchronous operations.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/*.kt : Use the `ModuleRegistry` provider pattern for extensibility and plugin architecture instead of hard-coded dependencies.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/jvmMain/**/*.kt : Use platform-specific optimizations in their respective source directories: `androidMain/` for Android optimizations, `jvmMain/` for JVM optimizations.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/*.gradle.kts : Android minSdk must be 24 or later for Kotlin Multiplatform SDK.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/*.kt : Use Flow instead of AsyncSequence for reactive streams in Kotlin Multiplatform code.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/*.gradle.kts : JVM target must be 17 or later for Kotlin Multiplatform SDK.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-kotlin/**/src/**/components/**/*.kt : Implement proper component lifecycle management with initialization, state tracking, and cleanup in BaseComponent.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Use `./scripts/sdk.sh` for all Kotlin SDK operations instead of calling Gradle directly. It handles configuration and build complexity.
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Run pre-commit hooks for code quality enforcement before committing code.

Applied to files:

  • scripts/check-todos-hook.sh
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-swift/**/Package.swift : iOS minimum deployment target must be 13.0 or later for Swift SDK.

Applied to files:

  • .github/workflows/integration-tests.yml
  • .github/workflows/react-native-sdk.yml
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-swift/**/Package.swift : Swift minimum version must be 5.9 or later for iOS SDK.

Applied to files:

  • .github/workflows/integration-tests.yml
  • .github/workflows/react-native-sdk.yml
📚 Learning: 2025-11-26T22:49:40.358Z
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Use `./scripts/sdk.sh` for all Kotlin SDK operations instead of calling Gradle directly. It handles configuration and build complexity.

Applied to files:

  • scripts/release_android_sdk.sh
🧬 Code graph analysis (1)
scripts/release_android_sdk.sh (1)
scripts/release_ios_sdk.sh (6)
  • print_error (20-20)
  • print_header (18-18)
  • print_info (22-22)
  • print_success (19-19)
  • print_warning (21-21)
  • sedi (34-42)
🪛 actionlint (1.7.9)
.github/workflows/react-native-sdk.yml

77-77: shellcheck reported issue in this script: SC2086:info:10:32: Double quote to prevent globbing and word splitting

(shellcheck)


77-77: shellcheck reported issue in this script: SC2086:info:13:34: Double quote to prevent globbing and word splitting

(shellcheck)

.github/workflows/release-artifacts.yml

24-24: shellcheck reported issue in this script: SC2086:info:2:28: Double quote to prevent globbing and word splitting

(shellcheck)


101-101: shellcheck reported issue in this script: SC2086:info:2:28: Double quote to prevent globbing and word splitting

(shellcheck)


135-135: shellcheck reported issue in this script: SC2086:info:3:32: Double quote to prevent globbing and word splitting

(shellcheck)


135-135: shellcheck reported issue in this script: SC2086:info:4:32: Double quote to prevent globbing and word splitting

(shellcheck)

🔇 Additional comments (22)
scripts/check-todos-hook.sh (3)

1-11: LGTM on pattern definitions.

The TODO patterns are well-defined to match common comment styles and task keywords. The issue reference pattern correctly requires # followed by digits.


12-46: Per-file processing logic is sound.

The staged-file filtering correctly skips deleted files and restricts checks to source code extensions. The found_todos flag ensures the error header is printed only once before listing all violations.


47-86: Fallback repository-wide search is well-structured.

The exclude list comprehensively covers common build artifacts and vendored directories. Self-exclusion of the script (line 77) prevents false positives from the embedded patterns.

scripts/release_android_sdk.sh (7)

1-19: LGTM on script setup and helpers.

The script uses set -euo pipefail for robust error handling, and the colorized output helpers match the iOS release script pattern for consistency.


44-78: CLI argument handling is robust.

The --bump option correctly validates that a value is provided before shifting. Unknown arguments now properly exit with an error (unlike the original iOS script issue that was fixed).


80-141: Precondition validation is thorough.

All essential checks are covered: repository location, git state, branch verification, GitHub CLI presence and authentication, and build file existence.


143-167: Version extraction handles multiple formats.

The function correctly handles both double and single-quoted version strings in build.gradle.kts, with proper semver validation.


275-301: GitHub release creation is well-implemented.

The tag naming convention android/v$new_version correctly aligns with the release-artifacts.yml workflow trigger pattern. Release notes extraction from CHANGELOG with fallback is a good practice.


356-397: Release flow is comprehensive.

The main function follows a clear step-by-step process: validate → test → update versions → commit → push → tag → release. This matches the iOS script pattern for consistency across SDKs.


240-273: No changes needed — the sdk.sh path is correct.

The script properly checks for ./scripts/sdk.sh after changing to $SDK_DIR (which is sdk/runanywhere-kotlin). This correctly resolves to sdk/runanywhere-kotlin/scripts/sdk.sh, where sdk.sh actually exists. The code already follows the recommended pattern of preferring the sdk.sh wrapper over direct gradlew calls when available.

Likely an incorrect or invalid review comment.

.github/workflows/release-artifacts.yml (4)

1-8: LGTM on workflow triggers.

The tag-based triggers (ios/v* and android/v*) correctly align with the release scripts' tag naming conventions.


33-82: iOS XCFramework build is well-structured.

The build step properly validates that both iOS and Simulator frameworks exist before creating the XCFramework (lines 53-65). The upload is correctly conditioned on build success (line 78), addressing the previous review concern.


93-115: Android build setup aligns with requirements.

JDK 17 with Temurin distribution matches the Kotlin SDK requirements (per learnings: "JVM target must be 17 or later"). The separate JAR and AAR builds ensure both artifact types are produced.


133-153: Artifact verification and release attachment are well-implemented.

The check-artifacts step validates that at least one artifact exists before attempting to attach to the release, preventing empty release attachments.

Minor note: Static analysis flagged potential word-splitting on variable expansion in the find commands (lines 136-137), but these are in a controlled context and not a practical concern here.

scripts/release_ios_sdk.sh (5)

55-64: --bump argument validation is correct.

The validation properly checks for missing or flag-like values (line 56) and provides clear usage guidance before exiting. This addresses the previous review concern.


144-147: psql command check is now correct.

The condition properly uses command -v psql >/dev/null instead of the incorrect $(command -v psql) pattern. This addresses the previous review concern.


212-242: BuildToken.swift generation is secure and well-documented.

The generated file includes comprehensive documentation about the security model, with proper ASCII characters replacing the previously corrupted UTF-8. The token format bt_<uuid>_<timestamp> provides both uniqueness and traceability.


444-500: Worktree-based release flow is well-designed.

Using a git worktree ensures BuildToken.swift is only included in release tags, keeping the main branch clean. The cleanup trap (line 464) ensures proper resource cleanup even on errors.


531-549: Final messaging is clear and secure.

The box-drawing characters are now proper UTF-8 (═), and the security reminders appropriately warn against exposing the build token in public release notes.

.github/workflows/integration-tests.yml (2)

55-58: Verify that continue-on-error aligns with CI objectives.

The example app tests are marked as non-fatal (continue-on-error: true). While the PR objectives mention "known code errors remain" and this is intentional for the CI setup phase, ensure that this flag is removed once the code issues are resolved. Non-fatal test failures can mask regressions in the example app that demonstrate SDK integration.


71-73: Swift build lacks error handling and build configuration.

The Swift SDK build step runs without specifying a configuration (debug/release) and doesn't use continue-on-error: true like the corresponding steps in other jobs. If the SDK build fails, the entire iOS integration test job fails, which may not align with the stated goal of detecting issues across all platforms.

🔎 Proposed fix
     - name: Build SDK first
       working-directory: ./sdk/runanywhere-swift
-      run: swift build
+      run: swift build -c debug
+      continue-on-error: true
⛔ Skipped due to learnings
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-swift/**/Package.swift : Swift minimum version must be 5.9 or later for iOS SDK.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-swift/**/Package.swift : iOS minimum deployment target must be 13.0 or later for Swift SDK.
.github/workflows/react-native-sdk.yml (1)

61-62: Fix Xcode version selection: Xcode 16.2 is no longer available on macos-latest.

The workflow specifies Xcode 16.2, but as of January 2026, GitHub Actions' macOS 15 (Sonoma) runner—which macos-latest now uses—only includes Xcode 16.4 and later. Xcode 16.3 and older were deprecated on January 12, 2026. The xcode-select step (lines 61–62) will fail with "No such file or directory" and halt the build-ios job. Either upgrade to an available Xcode version (e.g., 16.4+) or add continue-on-error: true to this step if using the system default is acceptable.

⛔ Skipped due to learnings
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-swift/**/Package.swift : Swift minimum version must be 5.9 or later for iOS SDK.
Learnt from: CR
Repo: RunanywhereAI/runanywhere-sdks PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T22:49:40.358Z
Learning: Applies to sdk/runanywhere-swift/**/Package.swift : iOS minimum deployment target must be 13.0 or later for Swift SDK.

@shubhammalhotra28
Copy link
Contributor

Thanks! @Ethax22
We're updating our architecture a bit - so will wait on this PR a bit, to cross verify all the deployments/tagrets built within the YAML files as a part of CI/CD changes

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.

2 participants