-
Notifications
You must be signed in to change notification settings - Fork 97
feat(ci): Add comprehensive CI/CD pipeline for all SDKs #258
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat(ci): Add comprehensive CI/CD pipeline for all SDKs #258
Conversation
- 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
|
Note Other AI code review bot(s) detectedCodeRabbit 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. 📝 WalkthroughWalkthroughAdds 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 Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
📜 Recent review detailsConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
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. Comment |
There was a problem hiding this 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
2256lines of code in13files - Skipped
0files when reviewing. - Skipped posting
17draft 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%<= threshold50%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%<= threshold50%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%<= threshold50%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%<= threshold50%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%<= threshold50%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%<= threshold50%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%<= threshold50%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%<= threshold50%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%<= threshold50%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%<= threshold50%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%<= threshold50%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%<= threshold50%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 by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
scripts/release_ios_sdk.sh
Outdated
|
|
||
| # Final reminder to insert build token | ||
| print_warning "ΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉ" | ||
| print_warning "⚠️ FINAL REMINDER: Insert build token into Supabase!" |
There was a problem hiding this comment.
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.
| print_warning "⚠️ FINAL REMINDER: Insert build token into Supabase!" | |
| print_warning "FINAL REMINDER: Insert build token into Supabase!" |
There was a problem hiding this 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-Pflag 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-Pflag, 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]+"; thenNote: 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 iOSExample 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 AndroidAlso 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-swiftuses 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 ontestDebugUnitTestmay fail if task doesn't exist.The
dependsOn("jvmTest", "testDebugUnitTest")assumestestDebugUnitTestalways exists. While lines 214-217 handle execution data conditionally, the harddependsOnwill 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: Reconsiderif: 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 usingif: 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.shfor 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
📒 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.yamlscripts/check-todos-hook.shscripts/lint-android.shscripts/release_android_sdk.shscripts/release_ios_sdk.shsdk/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.ymlsdk/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.ymlsdk/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.shsdk/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.shsdk/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.shsdk/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.shscripts/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.shsdk/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.shsdk/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/bashto#!/usr/bin/env bashimproves 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 torunanywhere-kotlinis consistent.The SDK path and report paths are correctly updated to reflect the migration from
runanywhere-androidtorunanywhere-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: Thecontinue-on-error: trueon 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 atsdk/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: trueon 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 = trueallows unit tests to access Android resources, which is useful for testing resource-dependent code.
192-198: No action required. Kotlin version ingradle/libs.versions.tomlis 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: trueon 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.propertiesrelative 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.ktswith a sensible fallback.
253-259: Consider whether--latestflag is appropriate for multi-SDK repository.The
--latestflag 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--latestor 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 tomainwill 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, ifmainis 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 1checks for TTY), preventing accidental exposure in CI logs.
438-479: LGTM!The worktree-based approach for creating release tags with
BuildToken.swiftis well-designed. It ensures the token file only exists in release tags while keepingmainclean, with proper cleanup afterward.
| - name: Select Xcode version | ||
| run: sudo xcode-select -s /Applications/Xcode_16.1.app |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additional Comments (9)
-
.github/dependabot.yml, line 52 (link)syntax: missing newline at end of file
-
.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
-
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'
-
scripts/release_android_sdk.sh, line 353 (link)logic: GitHub URL in release verification message should match actual repository name 'RunanywhereAI/runanywhere-sdks'
-
.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?
-
.github/workflows/release-artifacts.yml, line 32-46 (link)logic: iOS builds missing dependency resolution step. SPM packages typically need
swift package resolveor similar before building. -
.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 usingif: success()to only create releases for successful builds. -
.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
-
.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
There was a problem hiding this 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]+"; thenThis 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_REFshould 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_REFfor 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.shrather 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 fiVerify that
scripts/sdk.shsupportsbuildandtestcommands 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 thecom.runanywhere.sdkgroup, 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" fiThis specifically targets the
runanywhere-kotlinartifact 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 onmacos-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 hascontinue-on-error: true, but it's better to usexcrun simctlto 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 forlocal.properties.The SDK lint hook uses
./local.propertieswhile this hook useslocal.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: falsescripts/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 letis 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 removefails, the script exits (due toset -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
📒 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.yamlscripts/check-todos-hook.shscripts/release_android_sdk.shscripts/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: trueflag 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-builddependency 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
gradlewby 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-15if 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-15Option 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: trueon 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 pipefailfor 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
sedifunction 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: truewithtypes: [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.propertiespath is now correct (addressing the prior review). However, the-ooperator inside[ ]is deprecated. Consider using||with[[ ]]for clarity and POSIX compliance.Also, based on learnings, the project recommends using
./scripts/sdk.shfor 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
sedifunction 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.swiftonly in release tags is a clean security pattern. The main branch stays clean while SPM users get the token via tags.
There was a problem hiding this 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/nullshould 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_OUTPUTscripts/release_android_sdk.sh (1)
80-133: Consider adding SDK directory existence check.The iOS release script checks for both
Package.swiftand$SDK_DIRdirectory 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 repositoryscripts/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 usingfindinstead oflsfor artifact counting.Static analysis flags SC2012:
lscan have issues with non-alphanumeric filenames. While unlikely for build artifacts, usingfindis 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
📒 Files selected for processing (7)
.github/workflows/integration-tests.yml.github/workflows/react-native-sdk.yml.github/workflows/release-artifacts.yml.pre-commit-config.yamlscripts/check-todos-hook.shscripts/release_android_sdk.shscripts/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: trueon 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-erroron 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: trueon 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
--bumpvalues.
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.shfor 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@v2and 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: trueandtypes: [text]configuration enables efficient per-file TODO checking, aligning with the updatedcheck-todos-hook.shscript.
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--bumpargument validation.The validation correctly checks for both missing values and flag-like arguments (starting with
-), addressing the past review concern aboutshift 2failing 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.
There was a problem hiding this 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/RunAnywhereAIwould 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 --noEmitwith a fallback tonpx tsc --noEmit. Ifyarn typecheckis 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. Thecontinue-on-error: truealready 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-cachedirectory would speed up theflutter pub getsteps 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.1without 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
📒 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.ymlscripts/check-todos-hook.shscripts/release_android_sdk.shscripts/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_todosflag 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 pipefailfor robust error handling, and the colorized output helpers match the iOS release script pattern for consistency.
44-78: CLI argument handling is robust.The
--bumpoption 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_versioncorrectly aligns with therelease-artifacts.ymlworkflow 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 — thesdk.shpath is correct.The script properly checks for
./scripts/sdk.shafter changing to$SDK_DIR(which issdk/runanywhere-kotlin). This correctly resolves tosdk/runanywhere-kotlin/scripts/sdk.sh, wheresdk.shactually exists. The code already follows the recommended pattern of preferring thesdk.shwrapper over directgradlewcalls 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*andandroid/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-artifactsstep 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
findcommands (lines 136-137), but these are in a controlled context and not a practical concern here.scripts/release_ios_sdk.sh (5)
55-64:--bumpargument 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:psqlcommand check is now correct.The condition properly uses
command -v psql >/dev/nullinstead 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: truelike 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-latestnow uses—only includes Xcode 16.4 and later. Xcode 16.3 and older were deprecated on January 12, 2026. Thexcode-selectstep (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 addcontinue-on-error: trueto 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.
|
Thanks! @Ethax22 |
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
Changes Made
GitHub Actions Workflows
iOS SDK CI (
.github/workflows/ios-sdk.yml)Android SDK CI (
.github/workflows/android-sdk.yml)runanywhere-androidtorunanywhere-kotlinReact Native SDK CI (
.github/workflows/react-native-sdk.yml)Flutter SDK CI (
.github/workflows/flutter-sdk.yml)Integration Tests (
.github/workflows/integration-tests.yml)Release Artifacts (
.github/workflows/release-artifacts.yml)Infrastructure Improvements
Dependabot (
.github/dependabot.yml)Pre-commit Hooks (
.pre-commit-config.yaml)Release Scripts
scripts/release_android_sdk.sh- Automated Android releasesscripts/release_ios_sdk.sh- Existing iOS release scriptBuild Configuration
sdk/runanywhere-kotlin/build.gradle.kts- Added JaCoCo for code coverageTesting
scripts/test-cicd-local.ps1)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 improvementsAndroid SDK- Android workflow fixes and improvementsiOS SDK- iOS workflow improvementsReact Native SDK- React Native workflowFlutter SDK- Flutter workflowChecklist
Following Contributing Guidelines:
Related Issues
Addresses CI/CD pipeline issues identified in the project analysis:
Screenshots
N/A - Infrastructure changes only (GitHub Actions workflows, configuration files)
Additional Notes
mainbranchContext used:
dashboard- CLAUDE.md (source)