Skip to content

Conversation

@transphorm
Copy link
Member

@transphorm transphorm commented Sep 29, 2025

Summary by CodeRabbit

  • New Features

    • In-app feedback system and a Photo Picker screen added; app no longer forces portrait orientation.
  • Removed Features / UI Changes

    • Legacy NFC/passport‑reader screens and related passport‑reading flows removed.
  • Chores

    • Android app version bumped and toolchain updated (Java/packaging); CI workflows and caching improved for faster, more reliable builds.
  • Documentation

    • FAQ/docs expanded (Aadhaar coverage added); CONTRIBUTING guidance now references the staging branch.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 29, 2025

Walkthrough

Adds "staging" to CI/review branch lists and rewrites many CI workflows and local composite actions (caching, cloning, mobile setup). Introduces license-header tooling and FeedbackProvider in the app. Removes the entire legacy android-passport-reader (NFC) module and related resources and tests.

Changes

Cohort / File(s) Summary
Repo config & tooling
/.coderabbit.yaml, /.nvmrc, /.yarnrc.yml, /.prettierignore, /.watchmanconfig, /.husky/pre-commit, /.vscode/tasks.json, /.eslintignore, /.gitignore, /.cursorignore, /.cursorrules, /.gitleaks.toml, /.gitleaksignore, .gitguardian.yml, AGENTS.md, README.md
Add staging to branch lists; update ignore and secret-scan rules; add Prettier/Yarn/watchman settings; add license-header checks and VSCode tasks; bump Node spec; doc updates (Aadhaar, FAQ); remove NFC doc entries.
Local GitHub actions & cache
.github/actions/cache-built-deps/action.yml, .github/actions/clone-android-passport-nfc-reader/action.yml, .github/actions/mobile-setup/action.yml
New composite actions: built-deps cache, private repo clone (PAT-aware), and tightened mobile setup (yarn --inline-builds) plus separate Ruby bundler install.
Workflows — CI & caching
.github/workflows/* (circuits.yml, circuits-build.yml, common-ci.yml, workspace-ci.yml, mobile-ci.yml, mobile-e2e.yml, mobile-deploy*.yml, mobile-bundle-analysis.yml, mobile-sdk-demo-ci.yml, npm-publish.yml, qrcode-sdk-ci.yml, web.yml)
Convert many triggers to pull_request (add staging), add concurrency, unify Node/Yarn setup, introduce Yarn/build-deps caching, add built-deps cache/guard flows, runner changes, mobile/e2e/deploy rework (NDK bump, WIF/PlayStore flows, test_mode/build-only).
Jest / module mapping
app/jest.config.cjs
Add moduleNameMapper entries and expand transformIgnorePatterns to include additional packages and mobile-sdk-alpha mappings.
License & editor linting
app/.eslintrc.cjs, /.husky/pre-commit, .vscode/tasks.json
Disable ESLint header rule, extend resolver extensions, add license-header check to pre-commit and VSCode tasks.
App code
app/App.tsx, app/AGENTS.md, app/README.md
Wrap AppNavigation with <FeedbackProvider>; remove NFC checklist items; update app docs and Node/NDK requirements.
Android app config
app/android/app/build.gradle, app/android/app/src/main/AndroidManifest.xml
Enforce Java 17 toolchain/jvmTarget, bump versionCode/versionName, linker/packaging tweaks, update org.jmrtd dep, add PhotoPickerActivity & disabled ModuleDependencies service, set extractNativeLibs="false", remove MainActivity orientation lock.
Fastlane / deploy helpers
app/fastlane/Fastfile, app/fastlane/helpers.rb
Remove Slack integration usage; add ios/android build_only lanes; rework Android upload handling (skip_upload/test_mode, ADC/json_key_data handling).
Remove android-passport-reader module
app/android/android-passport-nfc-reader/** (formerly android-passport-reader) — many paths
Entire module removed: Gradle scripts/wrappers/settings, manifest(s), activities/fragments (CameraActivity, NfcActivity, SelectionActivity, PassportDetailsFragment, PassportPhotoFragment, SelectionFragment, NfcFragment), NFC core (PassportNFC, NFCDocumentTag, PassportNfcUtils, KeyStoreUtils, JMRTDSecurityProvider, MRTDTrustStore, CSCAMasterList, PKD/KeyStore CertStore classes), data models (Passport, PersonDetails, VerificationStatus, Additional*), UI layouts, drawables, fonts, assets, tests. (files and resource deletions are extensive)

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Runner as GitHub Runner
  participant CacheAction as cache-built-deps (composite)
  participant Cache as actions/cache
  participant Builder as Build Steps

  Runner->>CacheAction: invoke composite
  Note over CacheAction: restore built artifacts if present
  CacheAction->>Cache: restore paths: common/dist, packages/mobile-sdk-alpha/dist<br/>key: cache-version + hash(sources)
  Cache-->>CacheAction: outputs.cache-hit
  alt cache miss
    CacheAction->>Builder: run build-deps to produce dists
    Builder-->>CacheAction: artifacts created
    CacheAction->>Cache: save(paths..., key)
  else cache hit
    CacheAction->>Builder: skip build-deps
  end
Loading
sequenceDiagram
  autonumber
  participant App as App.tsx
  participant Root as RootProviders
  participant Feedback as FeedbackProvider
  participant Nav as AppNavigation

  App->>Root: initialize providers
  Root->>Feedback: wrap children with FeedbackProvider
  Feedback->>Nav: mount AppNavigation inside FeedbackProvider
  Nav->>Feedback: consume feedback context/events
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Suggested reviewers

  • aaronmgdr
  • remicolin

Pipelines hum and branches grow,
Staging wakes where checks will go.
NFC trunks fell from branch and bough,
Feedback threads the app for now.
Caches cradle builds — commit, merge, and wow. 🚀

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Title Check ⚠️ Warning The title “Update main: v2.6.8” is overly generic and does not clearly convey the substantive changes in this merge; it merely notes a version bump without summarizing the key updates or context of the release. Revise the title to succinctly describe the release update and primary changes—for example, “chore(release): bump version to v2.6.8 and merge staging into main”—so it reflects both the version bump and the merge context.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit's high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch staging

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

❤️ Share

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

@gitguardian
Copy link

gitguardian bot commented Sep 29, 2025

⚠️ GitGuardian has uncovered 11 secrets following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

🔎 Detected hardcoded secrets in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
20511340 Triggered Generic Private Key ec732da common/src/mock_certificates/sha256_rsa_130689_4096/mock_csca.key View secret
20511341 Triggered Generic Private Key ec732da common/src/mock_certificates/sha1_rsa_64321_4096/mock_csca.key View secret
20511342 Triggered Generic Private Key ec732da common/src/mock_certificates/sha256_rsa_107903_4096/mock_dsc.key View secret
20511343 Triggered Generic Private Key ec732da common/src/constants/mockCertificates.ts View secret
20511344 Triggered Generic Private Key ec732da common/src/mock_certificates/sha256_rsa_130689_4096/mock_dsc.key View secret
21022104 Triggered Generic Private Key 2df4dc4 common/src/mock_certificates/aadhaar/mockAadhaarCert.ts View secret
20511345 Triggered Generic Private Key ec732da common/src/mock_certificates/sha256_rsa_56611_4096/mock_dsc.key View secret
20511346 Triggered Generic Private Key ec732da common/src/mock_certificates/sha256_rsa_107903_4096/mock_csca.key View secret
20511347 Triggered Generic Private Key ec732da common/src/constants/mockCertificates.ts View secret
20511348 Triggered Generic Private Key ec732da common/src/mock_certificates/sha256_rsa_122125_4096/mock_csca.key View secret
20511349 Triggered Generic Private Key ec732da common/src/mock_certificates/sha256_rsa_56611_4096/mock_csca.key View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secrets safely. Learn here the best practices.
  3. Revoke and rotate these secrets.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 12

Caution

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

⚠️ Outside diff range comments (2)
.github/workflows/mobile-bundle-analysis.yml (2)

40-65: Replace direct cache actions with shared composite actions.

Per coding guidelines, use the shared composite caching actions from .github/actions instead of calling actions/cache directly. This ensures consistent cache key patterns and versioning across workflows.

Replace the direct cache calls with:

  • .github/actions/cache-yarn for Node modules
  • .github/actions/cache-bundler for Ruby gems
  • .github/actions/cache-gradle for Gradle

Example for Node modules:

-    - name: Cache Node Modules
-      uses: actions/cache@v4
-      with:
-        path: |
-          .yarn/cache
-          node_modules
-          app/node_modules
-        key: ${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn-${{ hashFiles('yarn.lock') }}
-        restore-keys: |
-          ${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn-
+    - name: Cache Yarn Dependencies
+      uses: ./.github/actions/cache-yarn
+      with:
+        cache-version: ${{ env.GH_CACHE_VERSION }}-node-${{ env.NODE_VERSION_SANITIZED }}

As per coding guidelines


103-126: Replace direct cache actions with shared composite actions.

Per coding guidelines, use the shared composite caching actions from .github/actions instead of calling actions/cache directly.

Replace the direct cache calls with:

  • .github/actions/cache-yarn for Node modules
  • .github/actions/cache-bundler for Ruby gems
  • .github/actions/cache-pods for CocoaPods

Example for CocoaPods:

-    - name: Cache CocoaPods
-      uses: actions/cache@v4
-      with:
-        path: app/ios/Pods
-        key: ${{ runner.os }}-pods-${{ hashFiles('app/ios/Podfile.lock') }}
-        restore-keys: |
-          ${{ runner.os }}-pods-
+    - name: Cache CocoaPods
+      uses: ./.github/actions/cache-pods
+      with:
+        cache-version: ${{ env.GH_CACHE_VERSION }}

As per coding guidelines

🧹 Nitpick comments (11)
app/android/app/build.gradle (1)

202-202: JMRTD bump safe; no advisories – consider upgrading to 0.8.1

  • GitHub vulnerability scan returned no security advisories for org.jmrtd:jmrtd across all versions.
  • Maven Central’s latest release is 0.8.1; review its changelog for breaking changes and upgrade if compatible.
  • Confirm your passport/NFC routines still function correctly after the update.
app/README.md (1)

69-69: Optional: Fix markdown lint issues for better documentation quality.

Static analysis identified minor markdown formatting issues:

  • Line 69: Bare URL without proper markdown link syntax
  • Line 113: Code fence missing language identifier

These are cosmetic improvements that enhance documentation standards.

Also applies to: 113-115

.github/workflows/workspace-ci.yml (2)

16-101: Consider using the cache-built-deps action to avoid redundant builds.

The build, type-check, and lint jobs each independently run yarn build after installing dependencies. Since this PR introduces the cache-built-deps composite action (in .github/actions/cache-built-deps/action.yml), you could optimize by:

  1. Running the build job first and saving built artifacts via cache-built-deps
  2. Having type-check and lint jobs restore from that cache instead of rebuilding

This would significantly reduce CI time for type-checking and linting.


124-139: Format-check logic will always pass the pre-format verification.

Lines 128-132 check if the working directory is clean before running yarn format. This check will always pass on a fresh checkout, making it redundant. The meaningful check should occur after running yarn format (lines 134-139), which is correct.

Consider removing the pre-format check or adding a comment explaining its purpose if there's a specific reason for it.

.github/workflows/circuits-build.yml (1)

113-138: Consider adding Yarn dependency caching.

This workflow lacks the Yarn dependency caching step that other workflows use. Per coding guidelines, consider adding the shared composite cache action before installing dependencies:

 - name: Read and sanitize Node.js version
   shell: bash
   run: |
     # ... existing code ...
 - name: Use Node.js
   uses: actions/setup-node@v4
   with:
     node-version: ${{ env.NODE_VERSION }}

 - name: Install Yarn
   run: npm i -g yarn

+- name: Cache Yarn dependencies
+  uses: ./.github/actions/cache-yarn
+  with:
+    path: |
+      .yarn/cache
+      node_modules
+      circuits/node_modules
+    cache-version: v1
+
 - name: Install dependencies
   uses: ./.github/actions/yarn-install
   with:
     working_directory: circuits

As per coding guidelines

.github/actions/clone-android-passport-nfc-reader/action.yml (1)

34-42: Consider stricter error handling for credential scrubbing.

The credential scrubbing step uses || true which silently ignores failures. While the repository will still function, a failed scrub leaves the PAT in the git config. Consider logging a warning if scrubbing fails:

           if git clone --depth 1 --quiet "https://${{ inputs.selfxyz_internal_pat }}@github.com/selfxyz/android-passport-nfc-reader.git"; then
             echo "✅ android-passport-nfc-reader cloned successfully"
             # Immediately scrub the credential from remote URL for security
-            git -C android-passport-nfc-reader remote set-url origin https://github.com/selfxyz/android-passport-nfc-reader.git || true
+            if ! git -C android-passport-nfc-reader remote set-url origin https://github.com/selfxyz/android-passport-nfc-reader.git; then
+              echo "⚠️  Warning: Failed to scrub credentials from git remote - PAT may still be in git config"
+            fi
           else
             echo "❌ Failed to clone android-passport-nfc-reader"
             echo "Please ensure a valid SELFXYZ internal PAT is provided to this action"
             exit 1
           fi
.github/workflows/mobile-ci.yml (2)

181-194: Pre-test verification is overly defensive and verbose.

The final verification block (lines 181-194) re-checks dependencies from the app directory perspective before running tests. Given that:

  • The cache-built-deps step runs first
  • A conditional build step follows on cache-miss
  • A force-build fallback (if retained) runs after that

...this additional verification is redundant and adds noise to the logs.

Simplify to a single assertion without the verbose logging:

       - name: Test
         run: |
-          # Final verification from app directory perspective
-          echo "Final verification before running tests (from app directory)..."
-          if [ ! -f "../packages/mobile-sdk-alpha/dist/cjs/index.cjs" ] || [ ! -f "../common/dist/cjs/index.cjs" ]; then
-            echo "❌ Dependencies still not found from app directory"
-            ls -la ../packages/mobile-sdk-alpha/dist/ || echo "mobile-sdk-alpha dist not found"
-            ls -la ../common/dist/ || echo "common dist not found"
-            exit 1
-          fi
-          echo "✅ All dependencies verified, running tests..."
-          # Run jest through yarn to avoid the build:deps step since CI already built dependencies
           yarn jest --passWithNoTests && node --test scripts/tests/*.cjs
         working-directory: ./app

308-329: Workspace resolution logic is good but should be centralized.

The "Resolve iOS workspace" step intelligently picks between OpenPassport.xcworkspace and Self.xcworkspace. This same logic is duplicated in mobile-e2e.yml (lines 376-388).

Extract this into a reusable composite action or shell script in .github/scripts/resolve-ios-workspace.sh to avoid drift between workflows.

.github/workflows/mobile-deploy.yml (2)

621-625: Workload Identity Federation configuration is hardcoded.

The project ID and service account are hardcoded in the workflow. If this repository is cloned or the GCP project changes, these values will be incorrect.

Move these to environment variables or repository secrets:

       - uses: "google-github-actions/auth@v2"
         with:
-          project_id: "plucky-tempo-454713-r0"
-          workload_identity_provider: "projects/852920390127/locations/global/workloadIdentityPools/gh-self/providers/github-by-repos"
-          service_account: "[email protected]"
+          project_id: ${{ secrets.GCP_PROJECT_ID }}
+          workload_identity_provider: ${{ secrets.GCP_WIF_PROVIDER }}
+          service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}

800-844: CMake installation added but not mentioned in summary.

The NDK installation step now also installs CMake 3.22.1 with retry logic. This is a significant change for native module builds but isn't clearly documented.

Consider splitting into separate steps for clarity:

-      - name: Install NDK and CMake
+      - name: Install NDK
         if: inputs.platform != 'ios' && steps.ndk-cache.outputs.cache-hit != 'true'
         run: |
           max_attempts=5
           attempt=1
-
-          # Install NDK
           while [ $attempt -le $max_attempts ]; do
             echo "Attempt $attempt of $max_attempts to install NDK..."
             if sdkmanager "ndk;${{ env.ANDROID_NDK_VERSION }}"; then
               echo "Successfully installed NDK"
-              break
+              break
             fi
             echo "Failed to install NDK on attempt $attempt"
             if [ $attempt -eq $max_attempts ]; then
               echo "All attempts to install NDK failed"
               exit 1
             fi
             # Exponential backoff: 2^attempt seconds
             wait_time=$((2 ** attempt))
             echo "Waiting $wait_time seconds before retrying..."
             sleep $wait_time
             attempt=$((attempt + 1))
           done
+
+      - name: Install CMake
+        if: inputs.platform != 'ios' && steps.ndk-cache.outputs.cache-hit != 'true'
+        run: |
+          max_attempts=5
+          attempt=1
-          # Install CMake (required for native module builds)
-          echo "Installing CMake..."
-          attempt=1
           while [ $attempt -le $max_attempts ]; do
             echo "Attempt $attempt of $max_attempts to install CMake..."
             if sdkmanager "cmake;3.22.1"; then
               echo "Successfully installed CMake"
               break
             fi
             # ... rest of retry logic
           done
-
.github/workflows/mobile-e2e.yml (1)

376-388: Workspace resolution duplicated from mobile-ci.yml.

This is the same logic flagged in mobile-ci.yml review. Centralize this into a reusable script.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 15a84e1 and 675c00e.

⛔ Files ignored due to path filters (26)
  • app/Gemfile.lock is excluded by !**/*.lock
  • app/android/android-passport-reader/app/src/main/res/font/roboto_bold.ttf is excluded by !**/*.ttf
  • app/android/android-passport-reader/app/src/main/res/font/roboto_bold_italic.ttf is excluded by !**/*.ttf
  • app/android/android-passport-reader/app/src/main/res/font/roboto_italic.ttf is excluded by !**/*.ttf
  • app/android/android-passport-reader/app/src/main/res/font/roboto_medium_italic.ttf is excluded by !**/*.ttf
  • app/android/android-passport-reader/app/src/main/res/font/roboto_regular.ttf is excluded by !**/*.ttf
  • app/android/android-passport-reader/app/src/main/res/mipmap-hdpi/ic_launcher.png is excluded by !**/*.png
  • app/android/android-passport-reader/app/src/main/res/mipmap-hdpi/ic_launcher_round.png is excluded by !**/*.png
  • app/android/android-passport-reader/app/src/main/res/mipmap-mdpi/ic_launcher.png is excluded by !**/*.png
  • app/android/android-passport-reader/app/src/main/res/mipmap-mdpi/ic_launcher_round.png is excluded by !**/*.png
  • app/android/android-passport-reader/app/src/main/res/mipmap-xhdpi/ic_launcher.png is excluded by !**/*.png
  • app/android/android-passport-reader/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png is excluded by !**/*.png
  • app/android/android-passport-reader/app/src/main/res/mipmap-xxhdpi/ic_launcher.png is excluded by !**/*.png
  • app/android/android-passport-reader/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png is excluded by !**/*.png
  • app/android/android-passport-reader/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png is excluded by !**/*.png
  • app/android/android-passport-reader/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png is excluded by !**/*.png
  • app/android/android-passport-reader/examples/passport_ireland.jpg is excluded by !**/*.jpg
  • app/android/android-passport-reader/gradle/wrapper/gradle-wrapper.jar is excluded by !**/*.jar
  • app/ios/Podfile.lock is excluded by !**/*.lock
  • app/src/images/512w.png is excluded by !**/*.png
  • app/src/images/blue_check.svg is excluded by !**/*.svg
  • app/src/images/icons/aadhaar.svg is excluded by !**/*.svg
  • app/src/images/icons/checkmark_gray.svg is excluded by !**/*.svg
  • app/src/images/icons/epassport.svg is excluded by !**/*.svg
  • app/src/images/logo_gray.svg is excluded by !**/*.svg
  • app/src/images/warning.svg is excluded by !**/*.svg
📒 Files selected for processing (107)
  • .coderabbit.yaml (1 hunks)
  • .cursor/rules/technical-specification.mdc (0 hunks)
  • .cursorignore (3 hunks)
  • .cursorrules (0 hunks)
  • .gitguardian.yml (1 hunks)
  • .github/actions/cache-built-deps/action.yml (1 hunks)
  • .github/actions/clone-android-passport-nfc-reader/action.yml (1 hunks)
  • .github/actions/mobile-setup/action.yml (2 hunks)
  • .github/workflows/circuits-build.yml (3 hunks)
  • .github/workflows/circuits.yml (2 hunks)
  • .github/workflows/common-ci.yml (3 hunks)
  • .github/workflows/contracts.yml (1 hunks)
  • .github/workflows/mobile-bundle-analysis.yml (4 hunks)
  • .github/workflows/mobile-ci.yml (9 hunks)
  • .github/workflows/mobile-deploy-auto.yml (2 hunks)
  • .github/workflows/mobile-deploy.yml (23 hunks)
  • .github/workflows/mobile-e2e.yml (10 hunks)
  • .github/workflows/mobile-sdk-demo-ci.yml (1 hunks)
  • .github/workflows/npm-publish.yml (5 hunks)
  • .github/workflows/qrcode-sdk-ci.yml (1 hunks)
  • .github/workflows/web.yml (2 hunks)
  • .github/workflows/workspace-ci.yml (1 hunks)
  • .gitignore (1 hunks)
  • .gitleaks.toml (1 hunks)
  • .gitleaksignore (1 hunks)
  • .husky/pre-commit (1 hunks)
  • .nvmrc (1 hunks)
  • .prettierignore (1 hunks)
  • .vscode/tasks.json (1 hunks)
  • .watchmanconfig (0 hunks)
  • .yarnrc.yml (1 hunks)
  • AGENTS.md (1 hunks)
  • README.md (1 hunks)
  • app/.eslintrc.cjs (4 hunks)
  • app/AGENTS.md (0 hunks)
  • app/App.tsx (3 hunks)
  • app/README.md (10 hunks)
  • app/android/android-passport-reader/.gitignore (0 hunks)
  • app/android/android-passport-reader/README.md (0 hunks)
  • app/android/android-passport-reader/app/.gitignore (0 hunks)
  • app/android/android-passport-reader/app/build.gradle (0 hunks)
  • app/android/android-passport-reader/app/src/androidTest/java/example/jllarraz/com/passportreader/ExampleInstrumentedTest.java (0 hunks)
  • app/android/android-passport-reader/app/src/main/AndroidManifest.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/assets/tessdata/eng.user-patterns (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/common/IntentData.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/common/PreferencesKeys.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/data/AdditionalDocumentDetails.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/data/AdditionalPersonDetails.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/data/Passport.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/data/PersonDetails.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/network/MasterListApi.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/network/MasterListService.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/activities/CameraActivity.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/activities/NfcActivity.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/activities/SelectionActivity.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/fragments/NfcFragment.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/fragments/PassportDetailsFragment.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/fragments/PassportPhotoFragment.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/fragments/SelectionFragment.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/validators/DateRule.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/validators/DocumentNumberRule.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/views/TouchImageView.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/utils/EACCredentials.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/utils/KeyStoreUtils.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/utils/NFCDocumentTag.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/utils/PassportNFC.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/utils/PassportNfcUtils.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/utils/StringUtils.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/FeatureStatus.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/JMRTDSecurityProvider.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/MRTDTrustStore.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/VerificationStatus.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/cert/CSCAMasterList.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/cert/KeyStoreCertStoreParameters.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/cert/KeyStoreCertStoreSpi.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/cert/PKDCertStoreParameters.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/cert/PKDMasterListCertStoreParameters.kt (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/drawable-v24/ic_launcher_foreground.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/drawable/ic_check_circle_outline.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/drawable/ic_close_circle_outline.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/drawable/ic_help_circle_outline.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/drawable/ic_launcher_background.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/drawable/ic_passport.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/drawable/ic_person.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/drawable/toggle_background_border.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/drawable/toggle_background_left.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/drawable/toggle_background_right.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/drawable/toggle_text_color.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/font/bold.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/font/medium.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/font/regular.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/layout/activity_nfc.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/layout/activity_photo.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/layout/fragment_nfc.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/layout/fragment_passport_details.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/layout/fragment_photo.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/layout/fragment_selection.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml (0 hunks)
  • app/android/android-passport-reader/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml (0 hunks)
  • app/android/android-passport-reader/app/src/test/java/example/jllarraz/com/passportreader/ExampleUnitTest.java (0 hunks)
  • app/android/android-passport-reader/build.gradle (0 hunks)
  • app/android/android-passport-reader/gradle.properties (0 hunks)
  • app/android/android-passport-reader/gradlew (0 hunks)
  • app/android/android-passport-reader/gradlew.bat (0 hunks)
  • app/android/android-passport-reader/settings.gradle (0 hunks)
  • app/android/app/build.gradle (5 hunks)
  • app/android/app/src/main/AndroidManifest.xml (2 hunks)
⛔ Files not processed due to max files limit (51)
  • app/android/app/src/main/java/com/proofofpassportapp/MainActivity.kt
  • app/android/app/src/main/java/com/proofofpassportapp/MainApplication.kt
  • app/android/app/src/main/java/com/proofofpassportapp/NativeLoggerBridgeModule.kt
  • app/android/app/src/main/java/com/proofofpassportapp/PhotoPickerActivity.java
  • app/android/app/src/main/java/com/proofofpassportapp/QRCodeScannerModule.java
  • app/android/app/src/main/java/com/proofofpassportapp/QRCodeScannerPackage.java
  • app/android/app/src/main/java/com/proofofpassportapp/utils/QrCodeDetectorProcessor.kt
  • app/android/app/src/main/res/values/styles.xml
  • app/android/build.gradle
  • app/android/gradle.properties
  • app/android/gradle/wrapper/gradle-wrapper.properties
  • app/android/react-native-passport-reader/android/build.gradle
  • app/android/react-native-passport-reader/android/src/main/java/io/tradle/nfc/APDULogger.kt
  • app/android/react-native-passport-reader/android/src/main/java/io/tradle/nfc/RNPassportReaderModule.kt
  • app/android/react-native-passport-reader/index.android.js
  • app/android/settings.gradle
  • app/babel.config.cjs
  • app/declarations.d.ts
  • app/docs/MOBILE_DEPLOYMENT.md
  • app/docs/TREE_SHAKING.md
  • app/docs/examples/tree-shaking/granular-circuits-example.ts
  • app/docs/examples/tree-shaking/level2-optimal-example.ts
  • app/docs/examples/tree-shaking/level3-migration-guide.ts
  • app/docs/examples/tree-shaking/level3-optimal-example.ts
  • app/docs/examples/tree-shaking/optimal-pattern-example.ts
  • app/env.sample
  • app/env.ts
  • app/fastlane/.env.secrets.example
  • app/fastlane/DEV.md
  • app/fastlane/Fastfile
  • app/fastlane/README.md
  • app/fastlane/test/helpers_test.rb
  • app/index.js
  • app/ios/.bundle/config
  • app/ios/CameraView.swift
  • app/ios/LiveMRZScannerView.swift
  • app/ios/MRZScanner.swift
  • app/ios/OpenPassport/Info.plist
  • app/ios/PassportReader.m
  • app/ios/PassportReader.swift
  • app/ios/PhotoLibraryQRScannerViewController.swift
  • app/ios/Podfile
  • app/ios/QRScannerBridge.m
  • app/ios/QRScannerBridge.swift
  • app/ios/Self.xcodeproj/project.pbxproj
  • app/ios/SelfAnalytics.swift
  • app/ios/scripts/pod-install-with-cache-fix.sh
  • app/jest.config.cjs
  • app/jest.setup.js
  • app/metro.config.cjs
  • app/package.json
💤 Files with no reviewable changes (72)
  • app/android/android-passport-reader/app/.gitignore
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/FeatureStatus.kt
  • app/android/android-passport-reader/app/src/main/res/drawable/ic_check_circle_outline.xml
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/cert/PKDMasterListCertStoreParameters.kt
  • app/android/android-passport-reader/gradlew
  • app/android/android-passport-reader/build.gradle
  • .cursorrules
  • app/android/android-passport-reader/app/src/main/assets/tessdata/eng.user-patterns
  • .cursor/rules/technical-specification.mdc
  • app/android/android-passport-reader/app/src/main/res/drawable/ic_launcher_background.xml
  • app/AGENTS.md
  • app/android/android-passport-reader/app/src/main/res/layout/fragment_nfc.xml
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/data/PersonDetails.kt
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/validators/DateRule.kt
  • app/android/android-passport-reader/app/src/main/res/layout/fragment_selection.xml
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/cert/PKDCertStoreParameters.kt
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/fragments/NfcFragment.kt
  • app/android/android-passport-reader/app/src/main/res/drawable/toggle_background_left.xml
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/activities/NfcActivity.kt
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/activities/SelectionActivity.kt
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/cert/KeyStoreCertStoreParameters.kt
  • app/android/android-passport-reader/settings.gradle
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/fragments/PassportPhotoFragment.kt
  • app/android/android-passport-reader/app/src/main/res/drawable/toggle_background_right.xml
  • app/android/android-passport-reader/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/network/MasterListApi.kt
  • app/android/android-passport-reader/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  • app/android/android-passport-reader/app/src/main/res/drawable/ic_close_circle_outline.xml
  • app/android/android-passport-reader/app/src/main/res/font/bold.xml
  • app/android/android-passport-reader/app/src/main/res/layout/fragment_photo.xml
  • app/android/android-passport-reader/app/src/main/res/drawable/ic_person.xml
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/activities/CameraActivity.kt
  • app/android/android-passport-reader/app/src/main/res/font/medium.xml
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/JMRTDSecurityProvider.kt
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/cert/KeyStoreCertStoreSpi.kt
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/validators/DocumentNumberRule.kt
  • app/android/android-passport-reader/app/src/main/res/drawable/ic_passport.xml
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/common/PreferencesKeys.kt
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/views/TouchImageView.kt
  • app/android/android-passport-reader/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
  • .watchmanconfig
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/VerificationStatus.kt
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/MRTDTrustStore.kt
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/data/Passport.kt
  • app/android/android-passport-reader/README.md
  • app/android/android-passport-reader/app/src/main/res/drawable/ic_help_circle_outline.xml
  • app/android/android-passport-reader/gradlew.bat
  • app/android/android-passport-reader/app/src/main/AndroidManifest.xml
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/common/IntentData.kt
  • app/android/android-passport-reader/app/src/main/res/layout/activity_photo.xml
  • app/android/android-passport-reader/app/src/main/res/font/regular.xml
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/data/AdditionalPersonDetails.kt
  • app/android/android-passport-reader/app/src/main/res/drawable/toggle_background_border.xml
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/fragments/SelectionFragment.kt
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/utils/PassportNfcUtils.kt
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/ui/fragments/PassportDetailsFragment.kt
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/utils/KeyStoreUtils.kt
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/data/AdditionalDocumentDetails.kt
  • app/android/android-passport-reader/gradle.properties
  • app/android/android-passport-reader/app/src/main/java/org/jmrtd/cert/CSCAMasterList.kt
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/utils/StringUtils.kt
  • app/android/android-passport-reader/app/src/main/res/layout/fragment_passport_details.xml
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/utils/NFCDocumentTag.kt
  • app/android/android-passport-reader/.gitignore
  • app/android/android-passport-reader/app/src/test/java/example/jllarraz/com/passportreader/ExampleUnitTest.java
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/utils/EACCredentials.kt
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/utils/PassportNFC.kt
  • app/android/android-passport-reader/app/src/androidTest/java/example/jllarraz/com/passportreader/ExampleInstrumentedTest.java
  • app/android/android-passport-reader/app/src/main/res/layout/activity_nfc.xml
  • app/android/android-passport-reader/app/build.gradle
  • app/android/android-passport-reader/app/src/main/res/drawable/toggle_text_color.xml
  • app/android/android-passport-reader/app/src/main/java/example/jllarraz/com/passportreader/network/MasterListService.kt
🧰 Additional context used
📓 Path-based instructions (5)
.github/workflows/**/*.{yml,yaml}

📄 CodeRabbit inference engine (AGENTS.md)

.github/workflows/**/*.{yml,yaml}: In GitHub Actions workflows, use shared composite caching actions from .github/actions (cache-yarn, cache-bundler, cache-gradle, cache-pods)
Do not call actions/cache directly; rely on the shared composite caching actions
When using cache actions, optionally pass cache-version (often with GH_CACHE_VERSION and tool version) for stable keys

Files:

  • .github/workflows/contracts.yml
  • .github/workflows/npm-publish.yml
  • .github/workflows/common-ci.yml
  • .github/workflows/mobile-bundle-analysis.yml
  • .github/workflows/qrcode-sdk-ci.yml
  • .github/workflows/workspace-ci.yml
  • .github/workflows/mobile-ci.yml
  • .github/workflows/circuits.yml
  • .github/workflows/mobile-sdk-demo-ci.yml
  • .github/workflows/web.yml
  • .github/workflows/mobile-deploy-auto.yml
  • .github/workflows/circuits-build.yml
  • .github/workflows/mobile-e2e.yml
  • .github/workflows/mobile-deploy.yml
**/*.{js,ts,tsx,jsx,sol,nr}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{js,ts,tsx,jsx,sol,nr}: NEVER log sensitive data including PII (names, DOB, passport numbers, addresses), credentials, tokens, API keys, private keys, or session identifiers.
ALWAYS redact/mask sensitive fields in logs using consistent patterns (e.g., ***-***-1234 for passport numbers, J*** D*** for names).

Files:

  • app/App.tsx
app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (app/AGENTS.md)

Type checking must pass before PRs (yarn types)

Files:

  • app/App.tsx
.nvmrc

📄 CodeRabbit inference engine (AGENTS.md)

Ensure Node.js 22.x is used as specified by the repository’s .nvmrc

Files:

  • .nvmrc
app/android/**/*

⚙️ CodeRabbit configuration file

app/android/**/*: Review Android-specific code for:

  • Platform-specific implementations
  • Performance considerations
  • Security best practices for mobile

Files:

  • app/android/app/src/main/AndroidManifest.xml
  • app/android/app/build.gradle
🧠 Learnings (43)
📓 Common learnings
Learnt from: CR
PR: selfxyz/self#0
File: app/AGENTS.md:0-0
Timestamp: 2025-09-22T11:10:57.879Z
Learning: Applies to app/android/**/*.{kt,java} : Document complex native Android module changes in the PR
Learnt from: CR
PR: selfxyz/self#0
File: .cursor/rules/mobile-sdk-migration.mdc:0-0
Timestamp: 2025-08-24T18:54:04.809Z
Learning: Update the app to consume the mobile-sdk-alpha package and replace local modules with SDK imports
Learnt from: CR
PR: selfxyz/self#0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-08-29T15:31:15.924Z
Learning: Applies to packages/mobile-sdk-alpha/{**/*.test.{ts,tsx},**/__tests__/**/*.{ts,tsx}} : Ensure parseNFCResponse() works with representative, synthetic NFC data
📚 Learning: 2025-08-29T15:31:15.924Z
Learnt from: CR
PR: selfxyz/self#0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-08-29T15:31:15.924Z
Learning: Use the root Prettier and EditorConfig settings for formatting consistency

Applied to files:

  • .prettierignore
📚 Learning: 2025-08-29T15:29:47.727Z
Learnt from: CR
PR: selfxyz/self#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:29:47.727Z
Learning: Applies to **/.prettierrc{,.json,.yaml,.yml,.js,.cjs} : Use Prettier configuration from the repository’s .prettierrc files

Applied to files:

  • .prettierignore
📚 Learning: 2025-08-29T15:29:47.727Z
Learnt from: CR
PR: selfxyz/self#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:29:47.727Z
Learning: Before committing, run repository checks (yarn nice, yarn lint, yarn build, contracts build, yarn types)

Applied to files:

  • .github/workflows/npm-publish.yml
  • .github/workflows/common-ci.yml
  • .github/workflows/mobile-e2e.yml
  • .github/workflows/mobile-deploy.yml
  • .husky/pre-commit
📚 Learning: 2025-08-26T14:41:41.821Z
Learnt from: shazarre
PR: selfxyz/self#936
File: app/src/screens/aesop/PassportOnboardingScreen.tsx:0-0
Timestamp: 2025-08-26T14:41:41.821Z
Learning: When verifying provider hierarchies in React Native apps, always check the main App.tsx file at the app root, not just navigation/index.tsx and layout files, as providers are often configured at the top-level App component.

Applied to files:

  • app/App.tsx
📚 Learning: 2025-08-26T14:49:11.190Z
Learnt from: shazarre
PR: selfxyz/self#936
File: app/src/screens/passport/PassportNFCScanScreen.tsx:28-31
Timestamp: 2025-08-26T14:49:11.190Z
Learning: The main App.tsx file is located at app/App.tsx (not in app/src), and it properly wraps the entire app with SelfClientProvider at the top of the provider hierarchy, enabling useSelfClient() hook usage throughout all navigation screens.

Applied to files:

  • app/App.tsx
📚 Learning: 2025-08-26T14:49:15.210Z
Learnt from: shazarre
PR: selfxyz/self#936
File: app/src/screens/passport/PassportNFCScanScreen.web.tsx:8-11
Timestamp: 2025-08-26T14:49:15.210Z
Learning: The main App.tsx file is located at app/App.tsx (at the app root), not at app/src/App.tsx, and contains the SelfClientProvider wrapping the entire application.

Applied to files:

  • app/App.tsx
📚 Learning: 2025-08-26T14:49:11.190Z
Learnt from: shazarre
PR: selfxyz/self#936
File: app/src/screens/passport/PassportNFCScanScreen.tsx:28-31
Timestamp: 2025-08-26T14:49:11.190Z
Learning: SelfClientProvider is wrapped in app/App.tsx, providing context for useSelfClient() hook usage throughout the React Native app navigation stacks.

Applied to files:

  • app/App.tsx
📚 Learning: 2025-09-22T11:10:22.019Z
Learnt from: CR
PR: selfxyz/self#0
File: .cursorrules:0-0
Timestamp: 2025-09-22T11:10:22.019Z
Learning: Use Yarn workspaces for monorepo management.

Applied to files:

  • AGENTS.md
📚 Learning: 2025-08-29T15:29:47.727Z
Learnt from: CR
PR: selfxyz/self#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:29:47.727Z
Learning: Use nvm and Corepack to set up the Yarn v4 monorepo before any other commands (nvm use; corepack enable; corepack prepare yarnstable --activate; yarn install)

Applied to files:

  • AGENTS.md
  • .github/workflows/common-ci.yml
  • .github/workflows/mobile-ci.yml
  • .github/workflows/circuits-build.yml
  • .github/workflows/mobile-e2e.yml
  • .github/actions/mobile-setup/action.yml
📚 Learning: 2025-09-22T11:10:22.019Z
Learnt from: CR
PR: selfxyz/self#0
File: .cursorrules:0-0
Timestamp: 2025-09-22T11:10:22.019Z
Learning: Test, build, and deploy scripts (`yarn test`, `yarn ios`, `yarn test:e2e:ios`, Fastlane, etc.) must be used for automation.

Applied to files:

  • AGENTS.md
  • .github/workflows/common-ci.yml
  • app/README.md
  • .github/workflows/mobile-ci.yml
  • .gitignore
  • .github/workflows/web.yml
  • .github/workflows/mobile-e2e.yml
  • .github/workflows/mobile-deploy.yml
  • .github/actions/mobile-setup/action.yml
📚 Learning: 2025-09-22T11:10:57.879Z
Learnt from: CR
PR: selfxyz/self#0
File: app/AGENTS.md:0-0
Timestamp: 2025-09-22T11:10:57.879Z
Learning: Optionally use Watchman and run yarn install at repo root

Applied to files:

  • AGENTS.md
📚 Learning: 2025-08-29T15:29:47.727Z
Learnt from: CR
PR: selfxyz/self#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:29:47.727Z
Learning: Applies to .github/workflows/**/*.{yml,yaml} : In GitHub Actions workflows, use shared composite caching actions from .github/actions (cache-yarn, cache-bundler, cache-gradle, cache-pods)

Applied to files:

  • .github/workflows/common-ci.yml
  • .github/workflows/workspace-ci.yml
  • .github/workflows/mobile-ci.yml
  • .github/workflows/circuits.yml
  • .github/actions/cache-built-deps/action.yml
  • .github/workflows/mobile-e2e.yml
  • .github/workflows/mobile-deploy.yml
📚 Learning: 2025-08-29T15:29:47.727Z
Learnt from: CR
PR: selfxyz/self#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:29:47.727Z
Learning: Applies to .github/workflows/**/*.{yml,yaml} : Do not call actions/cache directly; rely on the shared composite caching actions

Applied to files:

  • .github/workflows/common-ci.yml
  • .github/workflows/mobile-ci.yml
  • .github/actions/cache-built-deps/action.yml
  • .github/workflows/mobile-e2e.yml
  • .github/workflows/mobile-deploy.yml
📚 Learning: 2025-08-24T18:54:04.809Z
Learnt from: CR
PR: selfxyz/self#0
File: .cursor/rules/mobile-sdk-migration.mdc:0-0
Timestamp: 2025-08-24T18:54:04.809Z
Learning: Applies to packages/mobile-sdk-alpha/package.json : Expose a 'test:build' script in the SDK's package.json that runs build, test, types, and lint

Applied to files:

  • .github/workflows/common-ci.yml
  • app/README.md
  • .github/workflows/mobile-ci.yml
  • .github/workflows/mobile-sdk-demo-ci.yml
  • .github/workflows/web.yml
📚 Learning: 2025-08-29T15:29:47.727Z
Learnt from: CR
PR: selfxyz/self#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:29:47.727Z
Learning: Applies to .nvmrc : Ensure Node.js 22.x is used as specified by the repository’s .nvmrc

Applied to files:

  • .nvmrc
📚 Learning: 2025-09-22T11:10:57.879Z
Learnt from: CR
PR: selfxyz/self#0
File: app/AGENTS.md:0-0
Timestamp: 2025-09-22T11:10:57.879Z
Learning: Use Node.js 22.x with nvm and Yarn via Corepack

Applied to files:

  • .nvmrc
  • .github/workflows/mobile-ci.yml
📚 Learning: 2025-07-14T09:03:08.292Z
Learnt from: aaronmgdr
PR: selfxyz/self#763
File: app/.github/workflows/test-coverage.yml:0-0
Timestamp: 2025-07-14T09:03:08.292Z
Learning: Node.js 22 is supported by actions/setup-nodev4 and has been in Active LTS since October 2024. It works on Linux, macOS, and Windows runners (Windows issues were resolved after version 22.8.0).

Applied to files:

  • .nvmrc
📚 Learning: 2025-08-29T15:31:15.924Z
Learnt from: CR
PR: selfxyz/self#0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-08-29T15:31:15.924Z
Learning: Document API changes with examples, flag breaking changes, note performance and security implications for AI review

Applied to files:

  • app/README.md
📚 Learning: 2025-08-24T18:54:04.809Z
Learnt from: CR
PR: selfxyz/self#0
File: .cursor/rules/mobile-sdk-migration.mdc:0-0
Timestamp: 2025-08-24T18:54:04.809Z
Learning: Applies to packages/mobile-sdk-alpha/README.md : Document new/updated SDK modules and usage in packages/mobile-sdk-alpha/README.md

Applied to files:

  • app/README.md
📚 Learning: 2025-09-22T11:10:57.879Z
Learnt from: CR
PR: selfxyz/self#0
File: app/AGENTS.md:0-0
Timestamp: 2025-09-22T11:10:57.879Z
Learning: Applies to app/android/**/*.{kt,java} : Document complex native Android module changes in the PR

Applied to files:

  • app/README.md
  • app/android/app/src/main/AndroidManifest.xml
  • .github/workflows/mobile-e2e.yml
  • app/android/app/build.gradle
📚 Learning: 2025-09-22T11:10:57.879Z
Learnt from: CR
PR: selfxyz/self#0
File: app/AGENTS.md:0-0
Timestamp: 2025-09-22T11:10:57.879Z
Learning: Applies to app/ios/**/*.{m,mm,swift} : Document complex native iOS module changes in the PR

Applied to files:

  • app/README.md
📚 Learning: 2025-09-22T11:10:57.879Z
Learnt from: CR
PR: selfxyz/self#0
File: app/AGENTS.md:0-0
Timestamp: 2025-09-22T11:10:57.879Z
Learning: For Android development, use Android SDK/Emulator and JDK 17 with JAVA_HOME set

Applied to files:

  • app/README.md
📚 Learning: 2025-07-29T01:08:28.530Z
Learnt from: transphorm
PR: selfxyz/self#795
File: app/android/app/build.gradle:157-158
Timestamp: 2025-07-29T01:08:28.530Z
Learning: For this React Native project, the team prefers build flexibility over fail-fast behavior for release builds in app/android/app/build.gradle. They intentionally allow fallback to debug signing for local development runs, relying on Google Play Console validation to catch any improperly signed releases during upload.

Applied to files:

  • app/README.md
  • app/android/app/build.gradle
📚 Learning: 2025-08-29T15:29:47.727Z
Learnt from: CR
PR: selfxyz/self#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:29:47.727Z
Learning: Before PRs, ensure yarn build succeeds for all workspaces

Applied to files:

  • .github/workflows/workspace-ci.yml
  • .github/workflows/web.yml
  • .github/workflows/mobile-e2e.yml
📚 Learning: 2025-08-29T15:29:47.727Z
Learnt from: CR
PR: selfxyz/self#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:29:47.727Z
Learning: Applies to .github/workflows/**/*.{yml,yaml} : When using cache actions, optionally pass cache-version (often with GH_CACHE_VERSION and tool version) for stable keys

Applied to files:

  • .github/workflows/mobile-ci.yml
  • .github/actions/cache-built-deps/action.yml
  • .github/workflows/mobile-e2e.yml
  • .github/workflows/mobile-deploy.yml
📚 Learning: 2025-08-29T15:31:15.924Z
Learnt from: CR
PR: selfxyz/self#0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-08-29T15:31:15.924Z
Learning: Applies to packages/mobile-sdk-alpha/{**/*.test.{ts,tsx},**/__tests__/**/*.{ts,tsx}} : Test isPassportDataValid() with realistic synthetic passport data (never real user data)

Applied to files:

  • .gitleaksignore
  • .cursorignore
📚 Learning: 2025-08-29T15:31:15.924Z
Learnt from: CR
PR: selfxyz/self#0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-08-29T15:31:15.924Z
Learning: Applies to packages/mobile-sdk-alpha/{**/*.test.{ts,tsx},**/__tests__/**/*.{ts,tsx}} : Verify extractMRZInfo() using published sample MRZ strings (e.g., ICAO examples)

Applied to files:

  • .gitleaksignore
📚 Learning: 2025-08-29T15:31:15.924Z
Learnt from: CR
PR: selfxyz/self#0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-08-29T15:31:15.924Z
Learning: Applies to packages/mobile-sdk-alpha/{**/*.test.{ts,tsx},**/__tests__/**/*.{ts,tsx}} : Write integration tests that exercise the real validation logic (not mocks)

Applied to files:

  • .gitleaksignore
📚 Learning: 2025-08-29T15:31:15.924Z
Learnt from: CR
PR: selfxyz/self#0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-08-29T15:31:15.924Z
Learning: Applies to packages/mobile-sdk-alpha/**/*.{ts,tsx} : Avoid introducing circular dependencies

Applied to files:

  • .gitignore
  • app/.eslintrc.cjs
📚 Learning: 2025-08-29T15:31:15.924Z
Learnt from: CR
PR: selfxyz/self#0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-08-29T15:31:15.924Z
Learning: Applies to packages/mobile-sdk-alpha/{**/*.test.{ts,tsx},**/__tests__/**/*.{ts,tsx}} : Do NOT mock selfxyz/mobile-sdk-alpha in tests (avoid jest.mock('selfxyz/mobile-sdk-alpha') and replacing real functions with mocks)

Applied to files:

  • .gitignore
📚 Learning: 2025-08-29T15:31:15.924Z
Learnt from: CR
PR: selfxyz/self#0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-08-29T15:31:15.924Z
Learning: Applies to packages/mobile-sdk-alpha/{**/*.test.{ts,tsx},**/__tests__/**/*.{ts,tsx}} : Never use real user PII in tests; use only synthetic, anonymized, or approved test vectors

Applied to files:

  • .gitignore
📚 Learning: 2025-08-29T15:31:15.924Z
Learnt from: CR
PR: selfxyz/self#0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-08-29T15:31:15.924Z
Learning: Applies to packages/mobile-sdk-alpha/**/*.{ts,tsx} : Follow ESLint TypeScript-specific rules

Applied to files:

  • .gitignore
  • app/.eslintrc.cjs
📚 Learning: 2025-09-22T11:10:57.879Z
Learnt from: CR
PR: selfxyz/self#0
File: app/AGENTS.md:0-0
Timestamp: 2025-09-22T11:10:57.879Z
Learning: Applies to app/**/*.{ios,android,web}.{ts,tsx,js,jsx} : Explain platform-specific code paths in the PR description (files with .ios, .android, or .web extensions)

Applied to files:

  • .gitignore
  • .cursorignore
📚 Learning: 2025-08-29T15:31:15.924Z
Learnt from: CR
PR: selfxyz/self#0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-08-29T15:31:15.924Z
Learning: Applies to packages/mobile-sdk-alpha/**/*.{ts,tsx} : Use strict TypeScript type checking across the codebase

Applied to files:

  • .gitignore
  • app/.eslintrc.cjs
📚 Learning: 2025-08-29T15:31:15.924Z
Learnt from: CR
PR: selfxyz/self#0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-08-29T15:31:15.924Z
Learning: Applies to packages/mobile-sdk-alpha/{**/*.test.{ts,tsx},**/__tests__/**/*.{ts,tsx}} : Use actual imports from selfxyz/mobile-sdk-alpha in tests

Applied to files:

  • .gitignore
  • app/.eslintrc.cjs
📚 Learning: 2025-09-22T11:10:57.879Z
Learnt from: CR
PR: selfxyz/self#0
File: app/AGENTS.md:0-0
Timestamp: 2025-09-22T11:10:57.879Z
Learning: Applies to app/**/*.{ts,tsx} : Type checking must pass before PRs (yarn types)

Applied to files:

  • .gitignore
  • app/.eslintrc.cjs
📚 Learning: 2025-08-24T18:54:04.809Z
Learnt from: CR
PR: selfxyz/self#0
File: .cursor/rules/mobile-sdk-migration.mdc:0-0
Timestamp: 2025-08-24T18:54:04.809Z
Learning: Applies to packages/mobile-sdk-alpha/demo/** : Provide an in-SDK lightweight React Native demo under packages/mobile-sdk-alpha/demo/

Applied to files:

  • .github/workflows/mobile-sdk-demo-ci.yml
📚 Learning: 2025-08-29T15:31:15.924Z
Learnt from: CR
PR: selfxyz/self#0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-08-29T15:31:15.924Z
Learning: Run yarn nice, yarn types, and yarn test before commits and PRs

Applied to files:

  • .github/workflows/mobile-e2e.yml
📚 Learning: 2025-09-22T11:10:22.019Z
Learnt from: CR
PR: selfxyz/self#0
File: .cursorrules:0-0
Timestamp: 2025-09-22T11:10:22.019Z
Learning: Applies to tests/e2e/**/* : E2E testing must use Maestro for platform-specific flows.

Applied to files:

  • .github/workflows/mobile-e2e.yml
📚 Learning: 2025-09-22T11:10:57.879Z
Learnt from: CR
PR: selfxyz/self#0
File: app/AGENTS.md:0-0
Timestamp: 2025-09-22T11:10:57.879Z
Learning: Ensure app builds succeed for iOS, Android, and Web before PRs

Applied to files:

  • .github/workflows/mobile-e2e.yml
📚 Learning: 2025-09-22T11:10:22.019Z
Learnt from: CR
PR: selfxyz/self#0
File: .cursorrules:0-0
Timestamp: 2025-09-22T11:10:22.019Z
Learning: Applies to src/utils/**/*.{js,ts,tsx,jsx} : Shared utilities should be placed under `@/utils`.

Applied to files:

  • app/.eslintrc.cjs
📚 Learning: 2025-08-29T15:31:15.924Z
Learnt from: CR
PR: selfxyz/self#0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-08-29T15:31:15.924Z
Learning: Applies to packages/mobile-sdk-alpha/{**/*.test.{ts,tsx},**/__tests__/**/*.{ts,tsx}} : Ensure parseNFCResponse() works with representative, synthetic NFC data

Applied to files:

  • .cursorignore
🧬 Code graph analysis (1)
app/App.tsx (1)
app/src/providers/feedbackProvider.tsx (1)
  • FeedbackProvider (29-66)
🪛 actionlint (1.7.7)
.github/workflows/circuits-build.yml

19-19: label "128ram" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-2019", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "ubuntu-20.04", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)

.github/workflows/mobile-deploy.yml

180-180: input "key" is not defined in action "Cache Bundler" defined at "./.github/actions/cache-bundler". available inputs are "cache-version", "lock-file", "path"

(action)


181-181: input "restore-keys" is not defined in action "Cache Bundler" defined at "./.github/actions/cache-bundler". available inputs are "cache-version", "lock-file", "path"

(action)


730-730: input "key" is not defined in action "Cache Bundler" defined at "./.github/actions/cache-bundler". available inputs are "cache-version", "lock-file", "path"

(action)


731-731: input "restore-keys" is not defined in action "Cache Bundler" defined at "./.github/actions/cache-bundler". available inputs are "cache-version", "lock-file", "path"

(action)

🪛 markdownlint-cli2 (0.18.1)
app/README.md

69-69: Bare URL used

(MD034, no-bare-urls)


113-113: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

jobs:
build:
runs-on: ["self-hosted", "selfxyz-org", "ubuntu-22-04", "128ram"]
runs-on: ["128ram"]
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Verify self-hosted runner label configuration.

The static analysis tool flags "128ram" as an unknown runner label. If this is a self-hosted runner, ensure it's properly registered and consider adding it to your actionlint.yaml config to suppress this warning.


🏁 Script executed:

#!/bin/bash
# Check if actionlint.yaml exists and whether it declares self-hosted runner labels
if [ -f .github/actionlint.yaml ] || [ -f actionlint.yaml ]; then
  echo "=== actionlint.yaml configuration ==="
  fd -t f "actionlint.yaml" --exec cat {}
else
  echo "ℹ️  No actionlint.yaml found - self-hosted runner labels not configured"
fi

Length of output: 71


Add actionlint.yaml to declare the “128ram” self-hosted runner label
No actionlint.yaml found – create one (in .github/ or repo root) and include “128ram” under runners.self-hosted to suppress the unknown-label warning, and ensure the runner is registered in your GitHub settings.

🧰 Tools
🪛 actionlint (1.7.7)

19-19: label "128ram" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-2019", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "ubuntu-20.04", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)

🤖 Prompt for AI Agents
In .github/workflows/circuits-build.yml around line 19, the workflow uses a
self-hosted runner label "128ram" but there is no actionlint.yaml declaring that
label; create an actionlint.yaml file (in .github/ or repo root) with a
runners.self-hosted section that includes "128ram" to suppress the unknown-label
warning, and ensure the self-hosted runner with that label is registered in the
repository/organization settings.

Comment on lines 16 to 30
- name: Cache build artifacts
uses: actions/cache/save@v4
with:
path: common/dist
key: common-build-${{ runner.os }}-${{ github.sha }}
path: |
common/dist
packages/mobile-sdk-alpha/dist
key: build-deps-${{ runner.os }}-${{ hashFiles('common/**/*', 'packages/mobile-sdk-alpha/**/*', '!common/dist/**', '!packages/mobile-sdk-alpha/dist/**') }}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Consider using cache-built-deps composite action if available.

The workflow directly uses actions/cache/save for build artifacts. Per coding guidelines, prefer shared composite actions over direct actions/cache calls. Check if ./.github/actions/cache-built-deps exists (mentioned in AI summary) and use it for consistency.

As per coding guidelines


🏁 Script executed:

#!/bin/bash
# Check if cache-built-deps composite action exists
if [ -f .github/actions/cache-built-deps/action.yml ]; then
  echo "=== cache-built-deps action found ==="
  cat .github/actions/cache-built-deps/action.yml
else
  echo "ℹ️  No cache-built-deps composite action found"
fi

Length of output: 1164


Use shared cache-built-deps composite action for build artifacts
Replace the direct actions/cache/save@v4 step in .github/workflows/common-ci.yml with the ./.github/actions/cache-built-deps composite action, supplying the required cache-version (for example, ${{ env.GH_CACHE_VERSION }}) to handle both restore and save in one consistent step.

🤖 Prompt for AI Agents
In .github/workflows/common-ci.yml around lines 24 to 30, replace the direct
actions/cache/save@v4 step that saves build artifacts with a call to the local
composite action ./.github/actions/cache-built-deps; remove the uses:
actions/cache/save@v4 block and instead add a uses:
./.github/actions/cache-built-deps step, passing the required input
cache-version (for example cache-version: ${{ env.GH_CACHE_VERSION }}) and
ensure the composite action receives the same path(s) or is configured to handle
common/dist and packages/mobile-sdk-alpha/dist so it performs both restore and
save consistently.

Comment on lines 159 to 180
- name: Force Build Dependencies If Missing
run: |
# Force build if required files don't exist, regardless of cache status
if [ ! -f "packages/mobile-sdk-alpha/dist/cjs/index.cjs" ] || [ ! -f "common/dist/cjs/index.cjs" ]; then
echo "❌ Required dependency files missing, forcing rebuild..."
echo "Missing files:"
[ ! -f "packages/mobile-sdk-alpha/dist/cjs/index.cjs" ] && echo " - packages/mobile-sdk-alpha/dist/cjs/index.cjs"
[ ! -f "common/dist/cjs/index.cjs" ] && echo " - common/dist/cjs/index.cjs"
yarn workspace @selfxyz/mobile-app run build:deps
# Verify build completed successfully
if [ ! -f "packages/mobile-sdk-alpha/dist/cjs/index.cjs" ] || [ ! -f "common/dist/cjs/index.cjs" ]; then
echo "❌ Forced build failed - required files still missing"
ls -la packages/mobile-sdk-alpha/ || echo "packages/mobile-sdk-alpha not found"
ls -la packages/mobile-sdk-alpha/dist/ || echo "mobile-sdk-alpha dist not found"
ls -la common/ || echo "common not found"
ls -la common/dist/ || echo "common dist not found"
exit 1
fi
echo "✅ Forced build completed successfully"
else
echo "✅ All required dependency files exist"
fi
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Redundant force-build logic creates maintenance burden.

The "Force Build Dependencies If Missing" step (lines 159-180) duplicates the conditional build logic from lines 146-158. If the cache-built-deps action and the conditional build step work correctly, this force-build fallback should never execute. This redundancy suggests either:

  1. A lack of confidence in the cache mechanism, or
  2. An unresolved cache-miss edge case that should be fixed upstream

Consider removing lines 159-180 entirely and ensuring the cache-built-deps action reliability is addressed. If a fallback is truly needed, consolidate the verification and build into a single conditional step.

🤖 Prompt for AI Agents
.github/workflows/mobile-ci.yml lines 159-180 duplicate the conditional rebuild
that already exists at lines 146-158, creating redundant maintenance and masking
the real issue; remove this entire "Force Build Dependencies If Missing" block
and rely on the existing cache-built-deps and single conditional build step, or
if a fallback is truly required, merge the verification and rebuild logic into
the prior conditional step so there is only one clear check-and-build path and
no duplicated checks.

Comment on lines 145 to 170
publish-contracts:
needs: detect-changes
if: needs.detect-changes.outputs.contracts_changed == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
registry-url: "https://registry.npmjs.org"
- uses: actions/checkout@v4
- name: Install Dependencies
uses: ./.github/actions/yarn-install
- name: Build package
run: |
yarn workspace @selfxyz/contracts build
- name: Publish to npm
working-directory: contracts
run: |
yarn config set npmScopes.selfxyz.npmAuthToken ${{ secrets.NPM_TOKEN }}
yarn config set npmPublishAccess public
yarn npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove duplicate checkout action.

The job checks out the repository twice (lines 150 and 156). Remove the duplicate checkout at line 156.

Note: The publish-common job has the same issue (lines 122 and 128).

Apply this diff:

       - name: Set up Node.js
         uses: actions/setup-node@v4
         with:
           node-version-file: .nvmrc
           registry-url: "https://registry.npmjs.org"
-      - uses: actions/checkout@v4
       - name: Install Dependencies
         uses: ./.github/actions/yarn-install
📝 Committable suggestion

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

Suggested change
publish-contracts:
needs: detect-changes
if: needs.detect-changes.outputs.contracts_changed == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
registry-url: "https://registry.npmjs.org"
- uses: actions/checkout@v4
- name: Install Dependencies
uses: ./.github/actions/yarn-install
- name: Build package
run: |
yarn workspace @selfxyz/contracts build
- name: Publish to npm
working-directory: contracts
run: |
yarn config set npmScopes.selfxyz.npmAuthToken ${{ secrets.NPM_TOKEN }}
yarn config set npmPublishAccess public
yarn npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
publish-contracts:
needs: detect-changes
if: needs.detect-changes.outputs.contracts_changed == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
registry-url: "https://registry.npmjs.org"
- name: Install Dependencies
uses: ./.github/actions/yarn-install
- name: Build package
run: |
yarn workspace @selfxyz/contracts build
- name: Publish to npm
working-directory: contracts
run: |
yarn config set npmScopes.selfxyz.npmAuthToken ${{ secrets.NPM_TOKEN }}
yarn config set npmPublishAccess public
yarn npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
🤖 Prompt for AI Agents
.github/workflows/npm-publish.yml lines 145-170: the job defines
actions/checkout@v4 twice (at lines ~150 and ~156); remove the second duplicate
checkout step (the one at line ~156) so the repository is only checked out once
per job. Also apply the same change to the publish-common job (remove its second
checkout at lines ~122 and ~128) to eliminate duplicate checkout steps.

Comment on lines 101 to 106
// Header rule - DISABLED in favor of check-license-headers.mjs script
// 'header/header': [
// 'error',
// 'line',
// ' SPDX-License-Identifier: BUSL-1.1; Copyright (c) 2025 Social Connect Labs, Inc.; Licensed under BUSL-1.1 (see LICENSE); Apache-2.0 from 2029-06-11',
// ],
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Verify license header enforcement is maintained in the development workflow.

Disabling the ESLint header rule removes immediate feedback in IDEs. Ensure check-license-headers.mjs runs consistently in:

  1. Pre-commit hooks (e.g., husky)
  2. CI/CD pipelines
  3. Optionally as a lint-staged task

Without these safeguards, unlicensed files could slip through.

Run this script to confirm license checking is enforced:


🏁 Script executed:

#!/bin/bash
# Description: Verify license header checking is integrated into git hooks and CI

echo "=== Checking for pre-commit hooks ==="
if [ -f .husky/pre-commit ]; then
  echo "Pre-commit hook found, checking for license script:"
  cat .husky/pre-commit | grep -i "license" || echo "⚠️  No license check found in pre-commit hook"
else
  echo "⚠️  No .husky/pre-commit file found"
fi

echo -e "\n=== Checking for license script ==="
fd -t f "check-license-headers" || echo "⚠️  check-license-headers.mjs not found"

echo -e "\n=== Checking CI workflows for license checks ==="
fd -e yml -e yaml . .github/workflows/ --exec grep -l "license" {} \; || echo "⚠️  No license checks in CI workflows"

echo -e "\n=== Checking package.json for license scripts ==="
cat package.json | jq -r '.scripts | to_entries[] | select(.key | contains("license")) | "\(.key): \(.value)"' || echo "⚠️  No license scripts in package.json"

Length of output: 781


Add license-header check to CI workflows

Pre-commit and local scripts cover developers’ machines, but your CI pipelines (.github/workflows/mobile-ci.yml, mobile-e2e.yml, mobile-deploy.yml) currently don’t run node scripts/check-license-headers.mjs --check. Include that step in each workflow to enforce headers before merges.

🤖 Prompt for AI Agents
In app/.eslintrc.cjs around lines 101 to 106 the license header rule is disabled
and the CI workflows do not run the repository's license-header checker; add a
job step to each CI workflow file (.github/workflows/mobile-ci.yml,
mobile-e2e.yml, mobile-deploy.yml) that runs node
scripts/check-license-headers.mjs --check (fail the job on non-zero exit) early
in the job (before build/test) so header violations are caught, and ensure the
runner has node set up (or reuse existing setup-node step) so the script can
execute.

// Warn on common issues but don't block development

'no-console': 'warn',
'no-console': 'off',
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Reconsider disabling console warnings in production code.

Setting no-console to 'off' removes feedback for console statements in production code paths, which can:

  1. Leak sensitive data in production builds
  2. Create performance overhead
  3. Clutter device logs

The existing overrides already permit console usage in tests (line 214) and scripts (line 225) where it's appropriate.

Consider reverting to 'warn':

-    'no-console': 'off',
+    'no-console': 'warn',

This provides feedback during development while allowing exceptions where needed via the existing overrides.

📝 Committable suggestion

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

Suggested change
'no-console': 'off',
'no-console': 'warn',
🤖 Prompt for AI Agents
In app/.eslintrc.cjs around line 159, the rule 'no-console' is currently set to
'off'; change it to 'warn' so console usage surfaces as warnings in development
while relying on the existing overrides (tests at ~line 214 and scripts at ~line
225) to permit console where appropriate; ensure no other rule conflicts with
this change and run ESLint to confirm only intended files receive console
warnings.

cmake {
cppFlags += "-fexceptions -frtti -std=c++11"
arguments += "-DANDROID_STL=c++_shared"
arguments += "-Wl,-z,max-page-size=16384"
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Verify the 16KB page size linker flag is necessary for your AGP version.

The linker flag -Wl,-z,max-page-size=16384 ensures compatibility with Android devices using 16KB page sizes (required for Android 15+). However, Android Gradle Plugin 8.5+ handles this automatically.

Verify your AGP version to confirm whether this manual flag is still required, as it may be redundant or conflict with automatic handling.


🏁 Script executed:

#!/bin/bash
# Description: Check Android Gradle Plugin version to verify if manual 16KB flag is needed

echo "=== Checking AGP version in project build.gradle ==="
rg -n "com.android.tools.build:gradle" app/android/build.gradle

echo -e "\n=== Checking AGP version in buildscript dependencies ==="
rg -n -A5 "buildscript" app/android/build.gradle | rg "com.android.tools.build:gradle"

Length of output: 172


Remove redundant 16KB page size linker flag
The project is using Android Gradle Plugin 8.11.2, which auto-applies the 16KB page size setting (AGP 8.5+). Remove the line

arguments += "-Wl,-z,max-page-size=16384"

in app/android/app/build.gradle (line 139).

🤖 Prompt for AI Agents
In app/android/app/build.gradle around line 139, remove the redundant linker
flag arguments += "-Wl,-z,max-page-size=16384" because AGP 8.5+ (we use 8.11.2)
auto-applies the 16KB page size; simply delete that line so the project no
longer sets the duplicate -z,max-page-size value.

| Requirement | Version | Installation Guide |
| ----------- | -------- | ------------------------------------------------------------------------ |
| nodejs | > v18 | [Install nodejs](https://nodejs.org/) |
| nodejs | >= 22 | [Install nodejs](https://nodejs.org/) |
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Verify Node.js 22 compatibility across all dependencies.

The Node.js requirement has been updated from >v18 to >=22, which is a major version jump. Ensure that all project dependencies, especially native modules and build tools, are compatible with Node.js 22.


🏁 Script executed:

#!/bin/bash
# Check if package.json specifies engine requirements
echo "=== Checking package.json for Node.js engine constraints ==="
fd -t f '^package\.json$' -x sh -c 'echo "--- $1 ---"; jq -r ".engines.node // \"not specified\"" "$1"' sh {}

echo ""
echo "=== Checking for known Node.js version-specific issues in native modules ==="
# Check for native module dependencies that might have version constraints
fd -t f '^package\.json$' -x sh -c 'jq -r "select(.dependencies != null) | .dependencies | keys[]" "$1" 2>/dev/null' sh {} | sort -u | grep -E "(react-native|@react-native|node-gyp|native)" | head -20

Length of output: 717


Enforce Node.js engine requirement across all packages

  • Add "engines": { "node": ">=22 <23" } to package.json in:
    • packages/mobile-sdk-demo
    • packages/mobile-sdk-alpha
    • scripts/tests
    • app/android/react-native-passport-reader
  • Automated scan found no native-module dependencies, but manually verify any platform-specific build tools or native modules for Node.js 22 compatibility.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
.github/workflows/mobile-deploy.yml (2)

796-840: LGTM on retry logic with exponential backoff.

The retry mechanism with exponential backoff (2^attempt seconds) is a solid approach for handling transient sdkmanager failures. Both NDK and CMake installations are properly protected.

Consider making the CMake version (currently hardcoded to 3.22.1) configurable via an environment variable at the top of the workflow, similar to ANDROID_NDK_VERSION. This would make future CMake updates easier to manage.

 env:
   # Build environment versions
   RUBY_VERSION: 3.2
   JAVA_VERSION: 17
   ANDROID_API_LEVEL: 35
   ANDROID_NDK_VERSION: 27.0.12077973
+  CMAKE_VERSION: 3.22.1
   XCODE_VERSION: 16.4

Then reference it in line 826:

-            if sdkmanager "cmake;3.22.1"; then
+            if sdkmanager "cmake;${{ env.CMAKE_VERSION }}"; then

223-241: Remove unreachable pull_request logic
This workflow only triggers on workflow_dispatch, so the if: github.event_name == 'pull_request' branches will never execute—remove or update them to match the intended triggers.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 675c00e and a09ff23.

📒 Files selected for processing (5)
  • .github/workflows/mobile-deploy-auto.yml (3 hunks)
  • .github/workflows/mobile-deploy.yml (23 hunks)
  • .github/workflows/mobile-e2e.yml (10 hunks)
  • .github/workflows/mobile-sdk-demo-ci.yml (1 hunks)
  • README.md (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/mobile-sdk-demo-ci.yml
🧰 Additional context used
📓 Path-based instructions (1)
.github/workflows/**/*.{yml,yaml}

📄 CodeRabbit inference engine (AGENTS.md)

.github/workflows/**/*.{yml,yaml}: In GitHub Actions workflows, use shared composite caching actions from .github/actions (cache-yarn, cache-bundler, cache-gradle, cache-pods)
Do not call actions/cache directly; rely on the shared composite caching actions
When using cache actions, optionally pass cache-version (often with GH_CACHE_VERSION and tool version) for stable keys

Files:

  • .github/workflows/mobile-deploy-auto.yml
  • .github/workflows/mobile-e2e.yml
  • .github/workflows/mobile-deploy.yml
🧠 Learnings (3)
📚 Learning: 2025-08-29T15:29:47.727Z
Learnt from: CR
PR: selfxyz/self#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:29:47.727Z
Learning: Use nvm and Corepack to set up the Yarn v4 monorepo before any other commands (nvm use; corepack enable; corepack prepare yarnstable --activate; yarn install)

Applied to files:

  • .github/workflows/mobile-e2e.yml
📚 Learning: 2025-08-29T15:29:47.727Z
Learnt from: CR
PR: selfxyz/self#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:29:47.727Z
Learning: Applies to .github/workflows/**/*.{yml,yaml} : In GitHub Actions workflows, use shared composite caching actions from .github/actions (cache-yarn, cache-bundler, cache-gradle, cache-pods)

Applied to files:

  • .github/workflows/mobile-e2e.yml
  • .github/workflows/mobile-deploy.yml
📚 Learning: 2025-09-22T11:10:22.019Z
Learnt from: CR
PR: selfxyz/self#0
File: .cursorrules:0-0
Timestamp: 2025-09-22T11:10:22.019Z
Learning: Test, build, and deploy scripts (`yarn test`, `yarn ios`, `yarn test:e2e:ios`, Fastlane, etc.) must be used for automation.

Applied to files:

  • .github/workflows/mobile-e2e.yml
🪛 markdownlint-cli2 (0.18.1)
README.md

23-23: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4

(MD001, heading-increment)

⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-ios
🔇 Additional comments (37)
.github/workflows/mobile-deploy-auto.yml (4)

6-6: Branch trigger updated to staging aligns with deployment strategy.

The shift from main/dev to staging as the PR trigger branch is consistent with the broader PR objective to establish staging as a core deployment base.


11-11: Including mobile-sdk-alpha in path filters is appropriate.

Triggering deployments when the mobile SDK changes ensures consistency between SDK updates and app deployments.


13-15: Verify the concurrency strategy for deployment safety.

With cancel-in-progress: false, if multiple PRs are merged to staging in quick succession, deployments will queue rather than cancel. This could result in deploying an older version after a newer one has already been deployed, potentially causing rollbacks or inconsistent state.

Consider whether cancel-in-progress: true would be safer, or if queueing is intentional to ensure every merged PR gets deployed in order.


49-51: Deployment track mapping updated correctly.

The change from dev to staging for the internal deployment track is consistent with the workflow's new branch trigger and maintains the correct mapping of branches to deployment tracks.

.github/workflows/mobile-e2e.yml (22)

7-7: LGTM: NDK version updated.

The NDK version bump appears to be a routine update.


13-13: LGTM: Gradle options streamlined.

Removing deprecated and redundant flags is appropriate.


21-27: LGTM: Trigger configuration expanded appropriately.

Adding staging branch and mobile-sdk-alpha path coverage aligns with the PR objectives.


60-66: LGTM: Proper use of shared caching action.

The implementation correctly uses the shared composite cache-yarn action with comprehensive cache paths and versioned keys.

As per coding guidelines


67-77: Verify hardened mode handling aligns with security policy.

Disabling Yarn hardened mode for non-fork PRs (YARN_ENABLE_HARDENED_MODE=0) reduces package integrity checks. Ensure this trade-off is intentional and documented, especially if non-fork PRs can modify dependency declarations.

The dual installation path (with/without PAT) correctly handles fork scenarios.


79-81: LGTM: Maestro validation appropriately skipped for build-only mode.

The conditional skip aligns with the build-focused nature of the current workflow.


108-112: LGTM: Dependency build command with proper error handling.

The workspace command and error handling are appropriate.


119-123: LGTM: Android build configuration appropriate for E2E.

The Debug build variant and Gradle flags are suitable for testing workflows.


124-148: LGTM: Comprehensive build verification with fork-aware checks.

The verification logic properly handles both internal and fork scenarios. However, this depends on fixing the clone step to be conditional (see previous comment).


150-171: LGTM: Emulator step appropriately disabled for build-only workflow.

The conditional skip is consistent with the workflow's current build-focused scope.


181-182: LGTM: Resource allocation improvements for iOS job.

The timeout increase and large runner selection will improve reliability.


213-219: LGTM: Consistent use of shared caching action.

iOS job correctly mirrors the Android caching implementation.

As per coding guidelines


220-230: LGTM: iOS dependency handling mirrors Android approach.

The implementation is consistent with the Android job. The same hardened mode security consideration applies here.


232-233: LGTM: iOS test file validation enabled for full E2E.

Unlike Android, iOS runs complete E2E testing, so validation is appropriate.


268-273: Verify bundler caching approach against guidelines.

The coding guidelines state: "use shared composite caching actions from .github/actions (cache-yarn, cache-bundler, cache-gradle, cache-pods)". However, this implementation uses bundler-cache: true on the ruby/setup-ruby action instead of calling ./.github/actions/cache-bundler.

Confirm whether the built-in bundler-cache is acceptable or if the shared composite action should be used for consistency.

As per coding guidelines


281-288: LGTM: DerivedData caching well-configured.

The cache path and key strategy are appropriate for iOS builds.


294-298: LGTM: iOS dependency build consistent with Android.


299-306: Verify pod install handles forked PRs without PAT.

The pod install step passes SELFXYZ_INTERNAL_REPO_PAT but doesn't conditionally skip for forks. If private pods are required, this will fail for forked PRs.

Ensure the pod-install-with-cache-fix.sh script gracefully handles missing PAT, or add conditional logic similar to the Android clone step.


377-389: LGTM: Dynamic workspace resolution handles project migration.

The logic elegantly handles the transition between OpenPassport and Self workspace names.


390-427: LGTM: iOS build configuration optimized for CI.

The defensive checks and build flags are well-configured for reliable CI execution.


431-431: LGTM: App path correctly updated for Debug configuration.


113-117: Clone step will fail for forked PRs without PAT.

The clone action requires SELFXYZ_INTERNAL_REPO_PAT which won't be available for forked PRs, causing workflow failure before reaching the verification step that handles missing secrets.

Guard the clone step with a conditional:

       - name: Clone android-passport-nfc-reader
+        if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false }}
         uses: ./.github/actions/clone-android-passport-nfc-reader
         with:
           working_directory: app
           selfxyz_internal_pat: ${{ secrets.SELFXYZ_INTERNAL_REPO_PAT }}
.github/workflows/mobile-deploy.yml (6)

93-95: LGTM on concurrency configuration.

The concurrency group correctly prevents parallel deployments to the same track while allowing different tracks to run simultaneously. Setting cancel-in-progress: false is appropriate for deployment workflows to avoid interrupting in-progress releases.


620-681: LGTM on Workload Identity Federation and secrets verification.

The early secrets verification with comprehensive keytool checks is excellent for fail-fast behavior. The WIF setup correctly authenticates via Google's workload identity provider, eliminating the need for long-lived service account keys. Detecting and exporting the keystore type is a nice touch for downstream steps.


966-973: LGTM on job dependencies and conditions.

The dependency chain (build jobs → update-version → create-release-tags) is well-structured. The always() combined with explicit result checks ensures proper execution flow: update-version runs when at least one build succeeds (unless test_mode), and release tags are only created for production deployments after successful version updates.

Also applies to: 1042-1048


175-181: Cache-bundler action has invalid inputs.

The key and restore-keys inputs are not valid for the cache-bundler composite action. Use cache-version and lock-file instead, as specified in the coding guidelines.

Apply the fix from the previous review:

       - name: Cache Ruby gems
         id: gems-cache
         uses: ./.github/actions/cache-bundler
         with:
           path: ${{ env.APP_PATH }}/ios/vendor/bundle
-          key: ${{ runner.os }}-ruby${{ env.RUBY_VERSION }}-gems-${{ env.GH_CACHE_VERSION }}-${{ env.GH_GEMS_CACHE_VERSION }}-${{ hashFiles('app/Gemfile.lock') }}
-          restore-keys: |
-            ${{ runner.os }}-ruby${{ env.RUBY_VERSION }}-gems-${{ env.GH_CACHE_VERSION }}-${{ env.GH_GEMS_CACHE_VERSION }}-${{ hashFiles('app/Gemfile.lock') }}-
-            ${{ runner.os }}-ruby${{ env.RUBY_VERSION }}-gems-${{ env.GH_CACHE_VERSION }}-${{ env.GH_GEMS_CACHE_VERSION }}-
-            ${{ runner.os }}-ruby${{ env.RUBY_VERSION }}-gems-${{ env.GH_CACHE_VERSION }}-
+          lock-file: app/Gemfile.lock
+          cache-version: ${{ env.GH_CACHE_VERSION }}-${{ env.GH_GEMS_CACHE_VERSION }}-ruby${{ env.RUBY_VERSION }}

Based on coding guidelines


724-730: Cache-bundler action has invalid inputs (Android job).

Same issue as the iOS job: using key and restore-keys instead of cache-version and lock-file.

Apply the same fix:

       - name: Cache Ruby gems
         id: gems-cache
         uses: ./.github/actions/cache-bundler
         with:
           path: ${{ env.APP_PATH }}/ios/vendor/bundle
-          key: ${{ runner.os }}-ruby${{ env.RUBY_VERSION }}-gems-${{ env.GH_CACHE_VERSION }}-${{ env.GH_GEMS_CACHE_VERSION }}-${{ hashFiles('app/Gemfile.lock') }}
-          restore-keys: |
-            ${{ runner.os }}-ruby${{ env.RUBY_VERSION }}-gems-${{ env.GH_CACHE_VERSION }}-${{ env.GH_GEMS_CACHE_VERSION }}-${{ hashFiles('app/Gemfile.lock') }}-
-            ${{ runner.os }}-ruby${{ env.RUBY_VERSION }}-gems-${{ env.GH_CACHE_VERSION }}-${{ env.GH_GEMS_CACHE_VERSION }}-
-            ${{ runner.os }}-ruby${{ env.RUBY_VERSION }}-gems-${{ env.GH_CACHE_VERSION }}-
+          lock-file: app/Gemfile.lock
+          cache-version: ${{ env.GH_CACHE_VERSION }}-${{ env.GH_GEMS_CACHE_VERSION }}-ruby${{ env.RUBY_VERSION }}

Based on coding guidelines


568-578: Prevent merge conflicts by consolidating or sequencing PRs that modify app/version.json. The iOS bump, Android bump, and post-deploy version update jobs each open separate PRs targeting the same file, risking merge collisions. Consider combining bump changes into one PR when both builds pass, or having the update-version job handle all version bumps sequentially.

README.md (5)

17-17: LGTM!

Clear distinction between ICAO-compliant documents and Aadhaar cards. The phrasing accurately reflects the different standards.


23-29: Well-structured FAQ expansion.

The broadened question title and organized breakdown by document type improves clarity. The coverage map reference is helpful for users to verify support.


60-60: LGTM!

Removing Aadhaar from "Project Ideas" is consistent with promoting it to currently-supported documents in lines 5 and 17.


89-89: Good catch on the typo!


5-7: README: keep the NFC wording; remove or qualify the new “Aadhaar” claim.

  • Repo still contains full NFC support (native readers + screens + deps) — the intro line about “scanning the NFC chip” is accurate for passports / ID cards with NFC. Key locations: packages/mobile-sdk-alpha/android/src/main/java/.../RNSelfPassportReaderModule.kt, app/src/screens/document/DocumentNFCScanScreen.tsx, app/src/utils/nfcScanner.ts, app/ios/Podfile, app/package.json (react-native-nfc-manager).
  • “Aadhaar” appears only in README; I found no Aadhaar-specific NFC reader/implementation. Official Aadhaar cards are not chip-based (validation is typically via e‑Aadhaar / QR / mAadhaar app), and mAadhaar supports app-to-app sharing (QR/NFC) — do not imply physical-Aadhaar NFC scanning. (en.wikipedia.org)

Action: either remove/qualify “Aadhaar” from the intro (e.g., “passports and NFC‑equipped ID cards; Aadhaar via e‑Aadhaar/QR or mAadhaar”), or add/point to an Aadhaar-specific implementation and tests before claiming NFC support.

Likely an incorrect or invalid review comment.

Comment on lines 91 to 92
> **Important:** Please open your pull request from the `staging` branch. Pull requests from other branches will be automatically closed.
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Clear workflow guidance for contributors.

The staging branch requirement is well-communicated. Consider verifying that the automation mentioned ("will be automatically closed") is actually configured in your CI/CD.


🏁 Script executed:

#!/bin/bash
# Description: Check if there's automation to enforce staging branch requirement

# Search for GitHub Actions or CI configs that validate source branch
fd -e yml -e yaml . .github/workflows --exec rg -l 'head.*staging|source.*staging|base.*branch'

# Search for PR template or automation config
rg -n 'staging.*branch|pull.*request.*from' .github/

Length of output: 298


Ensure automated enforcement matches the README.
The README states non-staging PRs “will be automatically closed,” but there’s no workflow to do so. Add a GitHub Action (or other CI hook) to close or block PRs from non-staging branches, or update the documentation to reflect the actual process.

🤖 Prompt for AI Agents
In README.md around lines 91-92, the doc claims non-staging PRs “will be
automatically closed” but there’s no automation enforcing this; either implement
a GitHub Action that runs on pull_request, checks if
github.event.pull_request.head.ref !== 'staging' and then closes the PR (or adds
a blocking label/comment/draft state) and ensure the workflow file is placed
under .github/workflows with clear name and permissions, or update the README to
accurately describe the current behavior (remove the automatic-closing claim and
state the actual policy).

@transphorm transphorm changed the title Update main Update main: v2.6.8 Sep 30, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
.github/workflows/mobile-deploy.yml (1)

200-201: Document and constrain Yarn hardened mode disabling

Add inline comments above each “Disable Yarn hardened mode” step explaining the specific compatibility issue (e.g. integrity‐check failures with current Yarn/deps), extract the env toggle into a shared reusable workflow or limit it to only the jobs that actually fail without it, and plan to re-enable hardened mode once those compatibility issues are resolved.

app/fastlane/Fastfile (1)

258-258: Optional: Remove trailing commas per RuboCop style.

RuboCop flags trailing commas after the last parameter. While purely stylistic, removing them aligns with Ruby community conventions.

Apply this diff:

       # setting to false for now because of NFCPassportReader locally we use ssh to install but the
       # workflow uses https so the Podfile.lock is different
-      deployment: false,
+      deployment: false
       validate_play_store_json_key(
-        json_key: ENV["ANDROID_PLAY_STORE_JSON_KEY_PATH"],
+        json_key: ENV["ANDROID_PLAY_STORE_JSON_KEY_PATH"]
       )
           "MYAPP_UPLOAD_STORE_PASSWORD" => ENV["ANDROID_KEYSTORE_PASSWORD"],
           "MYAPP_UPLOAD_KEY_ALIAS" => ENV["ANDROID_KEY_ALIAS"],
-          "MYAPP_UPLOAD_KEY_PASSWORD" => ENV["ANDROID_KEY_PASSWORD"] == "EMPTY" ? "" : ENV["ANDROID_KEY_PASSWORD"],
+          "MYAPP_UPLOAD_KEY_PASSWORD" => ENV["ANDROID_KEY_PASSWORD"] == "EMPTY" ? "" : ENV["ANDROID_KEY_PASSWORD"]
         },

Also applies to: 401-401, 414-414

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a09ff23 and 9870b7b.

⛔ Files ignored due to path filters (1)
  • app/Gemfile.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • .github/workflows/mobile-deploy-auto.yml (5 hunks)
  • .github/workflows/mobile-deploy.yml (24 hunks)
  • app/fastlane/Fastfile (6 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
.github/workflows/**/*.{yml,yaml}

📄 CodeRabbit inference engine (AGENTS.md)

.github/workflows/**/*.{yml,yaml}: In GitHub Actions workflows, use shared composite caching actions from .github/actions (cache-yarn, cache-bundler, cache-gradle, cache-pods)
Do not call actions/cache directly; rely on the shared composite caching actions
When using cache actions, optionally pass cache-version (often with GH_CACHE_VERSION and tool version) for stable keys

Files:

  • .github/workflows/mobile-deploy.yml
  • .github/workflows/mobile-deploy-auto.yml
🧠 Learnings (1)
📚 Learning: 2025-08-29T15:29:47.727Z
Learnt from: CR
PR: selfxyz/self#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:29:47.727Z
Learning: Applies to .github/workflows/**/*.{yml,yaml} : In GitHub Actions workflows, use shared composite caching actions from .github/actions (cache-yarn, cache-bundler, cache-gradle, cache-pods)

Applied to files:

  • .github/workflows/mobile-deploy.yml
🪛 RuboCop (1.80.2)
app/fastlane/Fastfile

[convention] 258-258: Avoid comma after the last parameter of a method call.

(Style/TrailingCommaInArguments)


[convention] 401-401: Avoid comma after the last parameter of a method call.

(Style/TrailingCommaInArguments)


[convention] 414-414: Avoid comma after the last parameter of a method call.

(Style/TrailingCommaInArguments)


[convention] 444-457: Avoid more than 3 levels of block nesting.

(Metrics/BlockNesting)

🔇 Additional comments (27)
.github/workflows/mobile-deploy-auto.yml (4)

6-6: LGTM! Staging-focused trigger and safe concurrency.

The workflow now targets staging exclusively and includes the mobile-sdk-alpha package path. The concurrency group with cancel-in-progress: false ensures deployments complete without interruption, which is appropriate for production-like deployment workflows.

Also applies to: 11-11, 13-15


20-20: LGTM! Required for Workload Identity Federation.

The id-token: write permission enables OIDC-based authentication with Google Cloud, which is used in the deployment workflow for secure, keyless authentication.


50-52: LGTM! Deployment track mapping updated for staging.

The mapping now correctly associates the staging branch with the internal deployment track, aligning with the updated branching strategy.


94-94: Confirm test_mode: true for staging auto-deploy
Both iOS and Android steps in .github/workflows/mobile-deploy-auto.yml (L94 & L106) pass test_mode: true, which skips all App Store and Play Store uploads in the reusable workflow (mobile-deploy.yml gates uploads on inputs.test_mode != true). If this is only for testing, document its temporary nature and expose test_mode as a workflow input (defaulting to false for real deploys). Otherwise, verify this behavior matches your intended staging strategy.

.github/workflows/mobile-deploy.yml (16)

8-8: LGTM! Environment and concurrency configuration.

The NDK version update, id-token permission, and concurrency block are all appropriate. The concurrency grouping by deployment track or ref name prevents conflicts while allowing parallel deployments to different tracks.

Also applies to: 33-33, 93-95


99-99: LGTM! iOS setup and branch verification.

The switch to macos-latest-large, deep checkout, and staging ref are appropriate. The branch verification step provides useful diagnostics without blocking the build, which is a good balance for deployment workflows.

Also applies to: 110-112, 127-143


165-173: LGTM! Cache configurations follow guidelines.

The caching steps correctly use the shared composite actions (cache-yarn, cache-bundler, cache-pods) as specified in the coding guidelines. The cache keys properly incorporate version variables and lock file hashes.

As per coding guidelines.

Also applies to: 183-191


223-241: LGTM! Secure dependency installation for forked PRs.

The split installation approach correctly prevents secret exposure to forked PRs while maintaining full functionality for main repo workflows. This is a security best practice for public repositories.


243-275: LGTM! Comprehensive iOS secret verification.

The early validation of iOS secrets with format checks is an excellent fail-fast approach that will prevent cryptic build failures. The UUID and key ID format validations are particularly valuable.


449-456: LGTM! iOS dependency build step.

The explicit SDK dependency build step with proper error handling ensures dependencies are prepared before the main build. The silent flag helps keep logs focused on important information.


477-477: LGTM! Internal repo PAT for iOS build.

Adding the internal repository PAT to the build environment enables access to private dependencies during the iOS build process.


567-578: LGTM! PR-based version bump approach.

Switching to PR-based version updates instead of direct commits is a safer approach that:

  • Allows review of automated changes
  • Prevents race conditions when both platforms deploy
  • Maintains a clear audit trail

614-623: LGTM! Workload Identity Federation for secure GCP authentication.

The WIF setup replaces traditional service account keys with OIDC-based authentication, which is a security best practice. The configuration correctly specifies project ID, workload identity pool, and service account.


625-680: LGTM! Comprehensive Android keystore verification.

The extensive keystore validation using keytool is excellent:

  • Verifies password correctness
  • Validates alias existence
  • Confirms PrivateKeyEntry (required for signing)
  • Detects keystore type dynamically

This fail-fast approach will catch configuration issues early and provide clear error messages.


695-711: LGTM! Android branch verification.

Consistent with the iOS approach, providing useful diagnostics without blocking builds. This helps catch potential issues where the workflow might not be building from the expected commit.


795-839: LGTM! Robust NDK/CMake installation with retry.

The retry logic with exponential backoff (2^attempt seconds, max 5 attempts) handles transient network failures gracefully. Installing CMake explicitly ensures native module builds have all required tools.


846-850: LGTM! Android build and WIF-based upload.

The Python dependencies for Google API client, explicit dependency build step, and WIF-based Play Store upload are all well-structured. The Python upload script using Application Default Credentials (ADC) from WIF is a security best practice that eliminates service account key management.

Also applies to: 859-865, 867-912


922-932: LGTM! Version update coordination.

The separate update-version job that runs after both platform builds is an excellent solution to race condition issues. Creating a PR with all version files (version.json, package.json, yarn.lock) ensures consistency and allows review of automated version changes.

Also applies to: 965-1038


1040-1136: LGTM! Release tagging and GitHub release creation.

The create-release-tags job properly coordinates with the version update job and only runs for production deployments. The idempotent tag creation and automated GitHub release with changelog are valuable additions to the deployment pipeline.


852-857: android-passport-nfc-reader is still required – it’s referenced in app/package.json and in Android Gradle settings (settings.gradle, build.gradle), so retain the clone step; the summary claiming its removal is inaccurate.

app/fastlane/Fastfile (7)

122-125: LGTM! Version synchronization is correct.

Calling sync_version after semantic version bumps ensures that the iOS project's MARKETING_VERSION stays in sync with package.json. This is the right approach to maintain version consistency.


306-316: LGTM! Build-only lane is well-structured.

The new build_only lane effectively reuses the existing upload_android_build infrastructure by passing skip_upload: true. This is a clean implementation that avoids code duplication.


359-359: LGTM! Conditional credential requirements are appropriate.

Making ANDROID_PLAY_STORE_JSON_KEY_PATH required only for local development is correct since CI uses Workload Identity Federation (ADC). This reduces the attack surface by not requiring JSON keys in CI environments.

Also applies to: 378-379


398-403: LGTM! Validation logic aligns with credential strategy.

Validating the JSON key only in local development is consistent with the ADC-based CI approach. This is the correct implementation.


418-426: LGTM! Clear messaging for different skip scenarios.

The distinct messages for skip_upload vs test_mode provide good user feedback about why the upload was skipped. This improves the developer experience.


256-258: Fastfile comment regarding NFCPassportReader remains valid. The NFCPassportReader pod is still present in Podfile.lock and related source files; no change needed.


410-413: Release signing config correctly references MYAPP_UPLOAD_ variables
Verified in app/android/app/build.gradle (lines 158–162) that the storeFile, storePassword, keyAlias, and keyPassword fields use the new MYAPP_UPLOAD_* properties; the legacy debug keystore entries remain only in the debug configuration.

Comment on lines 429 to 432
upload_options = {
track: options[:track],
json_key: ENV["ANDROID_PLAY_STORE_JSON_KEY_PATH"],
package_name: ENV["ANDROID_PACKAGE_NAME"],
skip_upload_changelogs: true,
skip_upload_images: true,
skip_upload_screenshots: true,
track_promote_release_status: "completed",
aab: android_aab_path,
)
}
# In local development, use the JSON key file; in CI rely on ADC
if local_development
upload_options[:json_key] = ENV["ANDROID_PLAY_STORE_JSON_KEY_PATH"]
else
# In CI, try to use ADC credentials file directly
adc_creds_path = ENV["GOOGLE_APPLICATION_CREDENTIALS"]
if adc_creds_path && File.exist?(adc_creds_path)
UI.message("🔑 Using ADC credentials file: #{adc_creds_path}")
begin
# Try passing the credentials file content as json_key_data
creds_content = File.read(adc_creds_path)
upload_options[:json_key_data] = creds_content
rescue => e
UI.error("Failed to read ADC credentials: #{e.message}")
# Fallback: let supply try to use ADC automatically
UI.message("🔄 Falling back to automatic ADC detection")
end
else
UI.error("❌ ADC credentials not found at: #{adc_creds_path}")
end
end

upload_to_play_store(upload_options)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Improve error handling for missing ADC credentials in CI.

The current implementation attempts to upload to Play Store even when ADC credentials are missing or unreadable in CI. This will cause authentication failures with potentially unclear error messages.

Consider the following improvements:

  1. Fail fast when ADC is unavailable in CI: If GOOGLE_APPLICATION_CREDENTIALS is not set or the file doesn't exist in CI, raise an error immediately rather than attempting the upload.

  2. Clarify the fallback message: The message "Falling back to automatic ADC detection" is misleading—the supply plugin won't automatically detect ADC in a way that resolves this failure.

Apply this diff to fail fast when ADC credentials are unavailable in CI:

           else
             # In CI, try to use ADC credentials file directly
             adc_creds_path = ENV["GOOGLE_APPLICATION_CREDENTIALS"]
-            if adc_creds_path && File.exist?(adc_creds_path)
+            if !adc_creds_path || !File.exist?(adc_creds_path)
+              UI.user_error!("❌ ADC credentials not found. Set GOOGLE_APPLICATION_CREDENTIALS to a valid credentials file path.")
+            end
+            
+            if adc_creds_path && File.exist?(adc_creds_path)
               UI.message("🔑 Using ADC credentials file: #{adc_creds_path}")
               begin
                 # Try passing the credentials file content as json_key_data
                 creds_content = File.read(adc_creds_path)
                 upload_options[:json_key_data] = creds_content
               rescue => e
-                UI.error("Failed to read ADC credentials: #{e.message}")
-                # Fallback: let supply try to use ADC automatically
-                UI.message("🔄 Falling back to automatic ADC detection")
+                UI.user_error!("❌ Failed to read ADC credentials: #{e.message}")
               end
-            else
-              UI.error("❌ ADC credentials not found at: #{adc_creds_path}")
             end
           end
📝 Committable suggestion

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

Suggested change
upload_options = {
track: options[:track],
json_key: ENV["ANDROID_PLAY_STORE_JSON_KEY_PATH"],
package_name: ENV["ANDROID_PACKAGE_NAME"],
skip_upload_changelogs: true,
skip_upload_images: true,
skip_upload_screenshots: true,
track_promote_release_status: "completed",
aab: android_aab_path,
)
}
# In local development, use the JSON key file; in CI rely on ADC
if local_development
upload_options[:json_key] = ENV["ANDROID_PLAY_STORE_JSON_KEY_PATH"]
else
# In CI, try to use ADC credentials file directly
adc_creds_path = ENV["GOOGLE_APPLICATION_CREDENTIALS"]
if adc_creds_path && File.exist?(adc_creds_path)
UI.message("🔑 Using ADC credentials file: #{adc_creds_path}")
begin
# Try passing the credentials file content as json_key_data
creds_content = File.read(adc_creds_path)
upload_options[:json_key_data] = creds_content
rescue => e
UI.error("Failed to read ADC credentials: #{e.message}")
# Fallback: let supply try to use ADC automatically
UI.message("🔄 Falling back to automatic ADC detection")
end
else
UI.error("❌ ADC credentials not found at: #{adc_creds_path}")
end
end
upload_to_play_store(upload_options)
upload_options = {
track: options[:track],
package_name: ENV["ANDROID_PACKAGE_NAME"],
skip_upload_changelogs: true,
skip_upload_images: true,
skip_upload_screenshots: true,
track_promote_release_status: "completed",
aab: android_aab_path,
}
# In local development, use the JSON key file; in CI rely on ADC
if local_development
upload_options[:json_key] = ENV["ANDROID_PLAY_STORE_JSON_KEY_PATH"]
else
# In CI, try to use ADC credentials file directly
adc_creds_path = ENV["GOOGLE_APPLICATION_CREDENTIALS"]
if !adc_creds_path || !File.exist?(adc_creds_path)
UI.user_error!("❌ ADC credentials not found. Set GOOGLE_APPLICATION_CREDENTIALS to a valid credentials file path.")
end
if adc_creds_path && File.exist?(adc_creds_path)
UI.message("🔑 Using ADC credentials file: #{adc_creds_path}")
begin
# Try passing the credentials file content as json_key_data
creds_content = File.read(adc_creds_path)
upload_options[:json_key_data] = creds_content
rescue => e
UI.user_error!("❌ Failed to read ADC credentials: #{e.message}")
end
end
end
upload_to_play_store(upload_options)
🧰 Tools
🪛 RuboCop (1.80.2)

[convention] 444-457: Avoid more than 3 levels of block nesting.

(Metrics/BlockNesting)

🤖 Prompt for AI Agents
In app/fastlane/Fastfile around lines 429 to 460, the CI path continues to call
upload_to_play_store even when GOOGLE_APPLICATION_CREDENTIALS is unset or the
credentials file is unreadable; change the logic to fail fast in CI by aborting
with a clear error instead of proceeding. Specifically, when local_development
is false: if ENV["GOOGLE_APPLICATION_CREDENTIALS"] is nil or the file does not
exist, call UI.user_error or raise to stop the lane with a descriptive message;
if File.read raises, also call UI.user_error/raise with the read error (do not
log a misleading "falling back" message), and only populate
upload_options[:json_key_data] when the read succeeds so upload_to_play_store is
only invoked with valid credentials.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (2)
.github/workflows/mobile-deploy-auto.yml (1)

41-47: Avoid interpolating untrusted PR fields directly in bash scripts

${{ github.event.pull_request.title }} / body are untrusted and are inlined into the shell here, enabling injection. Pass them via env and reference safely inside the script.

Apply this diff:

       - name: Check deployment conditions
         id: check
-        run: |
+        env:
+          PR_TITLE: ${{ github.event.pull_request.title }}
+          PR_BODY: ${{ github.event.pull_request.body }}
+        run: |
+          set -euo pipefail
           echo "🔍 Checking deployment conditions..."

           # Skip if PR has skip-deploy in title or body
-          if [[ "${{ github.event.pull_request.title }}" =~ \[skip-deploy\] ]] ||
-             [[ "${{ github.event.pull_request.body }}" =~ \[skip-deploy\] ]]; then
+          if printf '%s\n%s' "$PR_TITLE" "$PR_BODY" | grep -q '\[skip-deploy\]'; then
             echo "should_deploy=false" >> $GITHUB_OUTPUT
             echo "⏭️ Skipping deployment due to [skip-deploy] flag"
             exit 0
           fi
.github/workflows/mobile-deploy.yml (1)

760-766: Replace direct actions/cache usage with a repo composite cache action

Guidelines prohibit calling actions/cache directly in workflows; use a shared composite action instead (e.g., add ./.github/actions/cache-ndk). This keeps cache keys/versioning consistent across CI. As per coding guidelines.

Apply this diff (after adding the composite action):

-      - name: Cache Android NDK
-        id: ndk-cache
-        uses: actions/cache@v4
-        with:
-          path: ${{ env.ANDROID_SDK_ROOT }}/ndk/${{ env.ANDROID_NDK_VERSION }}
-          key: ${{ runner.os }}-ndk-${{ env.ANDROID_NDK_VERSION }}
+      - name: Cache Android NDK
+        id: ndk-cache
+        uses: ./.github/actions/cache-ndk
+        with:
+          path: ${{ env.ANDROID_SDK_ROOT }}/ndk/${{ env.ANDROID_NDK_VERSION }}
+          cache-version: ${{ env.GH_CACHE_VERSION }}-ndk-${{ env.ANDROID_NDK_VERSION }}
♻️ Duplicate comments (1)
app/fastlane/Fastfile (1)

410-431: Fail fast in CI when ADC credentials are missing/unreadable

Proceeding without valid ADC leads to confusing Play upload failures. Abort early with a clear error and use the ADC file content explicitly.

Apply this diff:

-          # In CI, try to use ADC credentials file directly
-          adc_creds_path = ENV["GOOGLE_APPLICATION_CREDENTIALS"]
-          if adc_creds_path && File.exist?(adc_creds_path)
-            UI.message("🔑 Using ADC credentials file: #{adc_creds_path}")
-            begin
-              # Try passing the credentials file content as json_key_data
-              creds_content = File.read(adc_creds_path)
-              upload_options[:json_key_data] = creds_content
-            rescue => e
-              UI.error("Failed to read ADC credentials: #{e.message}")
-              # Fallback: let supply try to use ADC automatically
-              UI.message("🔄 Falling back to automatic ADC detection")
-            end
-          else
-            UI.error("❌ ADC credentials not found at: #{adc_creds_path}")
-          end
+          # In CI, require ADC and pass its contents explicitly
+          adc_creds_path = ENV["GOOGLE_APPLICATION_CREDENTIALS"] || ENV["GOOGLE_GHA_CREDS_PATH"]
+          if !adc_creds_path || !File.exist?(adc_creds_path)
+            UI.user_error!("❌ ADC credentials not found. Set GOOGLE_APPLICATION_CREDENTIALS (or GOOGLE_GHA_CREDS_PATH) to a valid file.")
+          end
+          begin
+            UI.message("🔑 Using ADC credentials file: #{adc_creds_path}")
+            creds_content = File.read(adc_creds_path)
+            upload_options[:json_key_data] = creds_content
+          rescue => e
+            UI.user_error!("❌ Failed to read ADC credentials: #{e.message}")
+          end
🧹 Nitpick comments (1)
.github/workflows/mobile-deploy.yml (1)

872-874: Pin Python deps (or use a constraints/requirements file) for reproducibility

Unpinned pip install can break the deploy unexpectedly. Pin versions or install from a checked‑in requirements-ci.txt.

Apply this diff:

-          python -m pip install --upgrade pip
-          pip install google-auth google-auth-oauthlib google-auth-httplib2 google-api-python-client
+          python -m pip install --upgrade pip
+          pip install -r app/scripts/requirements-ci.txt
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9870b7b and 4f80aa5.

📒 Files selected for processing (4)
  • .github/workflows/mobile-deploy-auto.yml (5 hunks)
  • .github/workflows/mobile-deploy.yml (22 hunks)
  • app/fastlane/Fastfile (6 hunks)
  • app/fastlane/helpers.rb (0 hunks)
💤 Files with no reviewable changes (1)
  • app/fastlane/helpers.rb
🧰 Additional context used
📓 Path-based instructions (1)
.github/workflows/**/*.{yml,yaml}

📄 CodeRabbit inference engine (AGENTS.md)

.github/workflows/**/*.{yml,yaml}: In GitHub Actions workflows, use shared composite caching actions from .github/actions (cache-yarn, cache-bundler, cache-gradle, cache-pods)
Do not call actions/cache directly; rely on the shared composite caching actions
When using cache actions, optionally pass cache-version (often with GH_CACHE_VERSION and tool version) for stable keys

Files:

  • .github/workflows/mobile-deploy-auto.yml
  • .github/workflows/mobile-deploy.yml
🧠 Learnings (1)
📚 Learning: 2025-08-29T15:29:47.727Z
Learnt from: CR
PR: selfxyz/self#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:29:47.727Z
Learning: Applies to .github/workflows/**/*.{yml,yaml} : In GitHub Actions workflows, use shared composite caching actions from .github/actions (cache-yarn, cache-bundler, cache-gradle, cache-pods)

Applied to files:

  • .github/workflows/mobile-deploy.yml
🪛 actionlint (1.7.7)
.github/workflows/mobile-deploy.yml

122-122: "github.event.pull_request.title" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions for more details

(expression)


627-627: "github.event.pull_request.title" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions for more details

(expression)

🪛 RuboCop (1.80.2)
app/fastlane/Fastfile

[convention] 230-230: Avoid comma after the last parameter of a method call.

(Style/TrailingCommaInArguments)


[convention] 373-373: Avoid comma after the last parameter of a method call.

(Style/TrailingCommaInArguments)


[convention] 386-386: Avoid comma after the last parameter of a method call.

(Style/TrailingCommaInArguments)


[convention] 416-429: Avoid more than 3 levels of block nesting.

(Metrics/BlockNesting)

🔇 Additional comments (1)
.github/workflows/mobile-deploy.yml (1)

1039-1053: Confirm base branch for the auto “update-version” PR

This opens a PR against dev after checking out staging. If intentional, all good; otherwise switch base to match your release flow to avoid cross‑branch drift.

Would you like a follow‑up patch to parameterize the base branch per track (e.g., internal→staging, production→main)?

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (4)
.github/workflows/mobile-ci.yml (1)

159-180: Drop the redundant “Force Build Dependencies” fallback.

This block still duplicates the cache‑miss build path and hides real cache issues. Kill it or merge the guard into the existing build step instead.

.github/workflows/mobile-deploy.yml (3)

133-136: Stop pinning checkout to staging.

These jobs must build/tag the commit that triggered the workflow. Forcing ref: staging breaks that guarantee and risks releasing the wrong code. Use the triggering SHA instead (or omit ref) so every run operates on the correct source.

-        with:
-          fetch-depth: 0
-          ref: staging
+        with:
+          fetch-depth: 0
+          ref: ${{ github.event.pull_request.merge_commit_sha || github.sha }}
-        with:
-          fetch-depth: 0
-          ref: staging
+        with:
+          fetch-depth: 0
+          ref: ${{ github.event.pull_request.merge_commit_sha || github.sha }}
-        with:
-          fetch-depth: 0
-          ref: staging
+        with:
+          fetch-depth: 0
+          ref: ${{ github.sha }}

Also applies to: 652-654, 1123-1126


641-647: Sanitize PR metadata in Android status step too.

Same shell-injection risk here—route the PR fields through env vars and print the shell variables instead of interpolating expressions directly.

       run: |
-          echo "🚀 Mobile deployment is enabled - proceeding with Android build"
-          echo "📱 Platform: ${{ inputs.platform || 'both' }}"
-          echo "🎯 Track: ${{ inputs.deployment_track || 'internal' }}"
-          echo "📦 Version bump: ${{ inputs.version_bump || 'build' }}"
-          if [ "${{ github.event_name }}" = "pull_request" ]; then
-            echo "🔀 Triggered by PR merge: #${{ github.event.pull_request.number }} - ${{ github.event.pull_request.title }}"
-            echo "👤 Merged by: ${{ github.event.pull_request.merged_by.login }}"
-          fi
+          set -euo pipefail
+          echo "🚀 Mobile deployment is enabled - proceeding with Android build"
+          echo "📱 Platform: ${PLATFORM}"
+          echo "🎯 Track: ${TRACK}"
+          echo "📦 Version bump: ${VERSION_BUMP}"
+          if [ "${GITHUB_EVENT_NAME}" = "pull_request" ]; then
+            printf '🔀 Triggered by PR merge: #%s - %s\n' "${PR_NUMBER}" "${PR_TITLE}"
+            printf '👤 Merged by: %s\n' "${PR_MERGED_BY}"
+          fi
       env:
+          PLATFORM: ${{ inputs.platform || 'both' }}
+          TRACK: ${{ inputs.deployment_track || 'internal' }}
+          VERSION_BUMP: ${{ inputs.version_bump || 'build' }}
+          GITHUB_EVENT_NAME: ${{ github.event_name }}
+          PR_NUMBER: ${{ github.event.pull_request.number }}
+          PR_TITLE: ${{ github.event.pull_request.title }}
+          PR_MERGED_BY: ${{ github.event.pull_request.merged_by.login }}

124-130: Sanitize PR metadata before logging.

Stop interpolating ${{ github.event.pull_request.* }} straight into the shell; it’s untrusted input. Pass them via env: and print the variables instead.

       run: |
-          echo "🚀 Mobile deployment is enabled - proceeding with iOS build"
-          echo "📱 Platform: ${{ inputs.platform || 'both' }}"
-          echo "🎯 Track: ${{ inputs.deployment_track || 'internal' }}"
-          echo "📦 Version bump: ${{ inputs.version_bump || 'build' }}"
-          if [ "${{ github.event_name }}" = "pull_request" ]; then
-            echo "🔀 Triggered by PR merge: #${{ github.event.pull_request.number }} - ${{ github.event.pull_request.title }}"
-            echo "👤 Merged by: ${{ github.event.pull_request.merged_by.login }}"
-          fi
+          set -euo pipefail
+          echo "🚀 Mobile deployment is enabled - proceeding with iOS build"
+          echo "📱 Platform: ${PLATFORM}"
+          echo "🎯 Track: ${TRACK}"
+          echo "📦 Version bump: ${VERSION_BUMP}"
+          if [ "${GITHUB_EVENT_NAME}" = "pull_request" ]; then
+            printf '🔀 Triggered by PR merge: #%s - %s\n' "${PR_NUMBER}" "${PR_TITLE}"
+            printf '👤 Merged by: %s\n' "${PR_MERGED_BY}"
+          fi
       env:
+          PLATFORM: ${{ inputs.platform || 'both' }}
+          TRACK: ${{ inputs.deployment_track || 'internal' }}
+          VERSION_BUMP: ${{ inputs.version_bump || 'build' }}
+          GITHUB_EVENT_NAME: ${{ github.event_name }}
+          PR_NUMBER: ${{ github.event.pull_request.number }}
+          PR_TITLE: ${{ github.event.pull_request.title }}
+          PR_MERGED_BY: ${{ github.event.pull_request.merged_by.login }}
🧹 Nitpick comments (1)
app/jest.config.cjs (1)

28-35: Consider more robust module resolution for monorepo dependencies.

Mapping to node_modules in sibling directories (../circuits/node_modules, ../common/node_modules) is fragile and creates hidden dependencies on the install/build state of those packages. If those directories aren't properly installed or if the monorepo structure changes, tests will break with cryptic errors.

These "fix" mappings suggest underlying resolution issues. Consider:

  • Using workspace dependencies properly via package.json workspace protocol
  • Hoisting dependencies to root node_modules
  • Investigating why Jest's default resolution isn't working for these packages

Run this script to verify the mapped paths exist:

#!/bin/bash
# Check if the hard-coded paths to sibling node_modules exist
echo "Checking snarkjs path:"
ls -la circuits/node_modules/snarkjs/build/main.cjs 2>&1

echo -e "\nChecking ffjavascript path:"
ls -la circuits/node_modules/ffjavascript/build/main.cjs 2>&1

echo -e "\nChecking @anon-aadhaar/core path:"
ls -la common/node_modules/@anon-aadhaar/core/dist/index.js 2>&1
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e8b311 and 48f8d79.

⛔ Files ignored due to path filters (2)
  • app/ios/Podfile.lock is excluded by !**/*.lock
  • app/src/images/icons/plus_slate600.svg is excluded by !**/*.svg
📒 Files selected for processing (3)
  • .github/workflows/mobile-ci.yml (9 hunks)
  • .github/workflows/mobile-deploy.yml (23 hunks)
  • app/jest.config.cjs (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
app/jest.config.cjs

📄 CodeRabbit inference engine (.cursor/rules/mobile-sdk-migration.mdc)

app/jest.config.cjs: Use Jest in the app with a React Native preset configured in app/jest.config.cjs
Configure moduleNameMapper in app/jest.config.cjs to map '@/'' to 'src/' and '@tests/' to 'tests/src/'

Files:

  • app/jest.config.cjs
.github/workflows/**/*.{yml,yaml}

📄 CodeRabbit inference engine (AGENTS.md)

.github/workflows/**/*.{yml,yaml}: In GitHub Actions workflows, use shared composite caching actions from .github/actions (cache-yarn, cache-bundler, cache-gradle, cache-pods)
Do not call actions/cache directly; rely on the shared composite caching actions
When using cache actions, optionally pass cache-version (often with GH_CACHE_VERSION and tool version) for stable keys

Files:

  • .github/workflows/mobile-deploy.yml
  • .github/workflows/mobile-ci.yml
🧠 Learnings (8)
📚 Learning: 2025-08-24T18:54:04.809Z
Learnt from: CR
PR: selfxyz/self#0
File: .cursor/rules/mobile-sdk-migration.mdc:0-0
Timestamp: 2025-08-24T18:54:04.809Z
Learning: Applies to app/jest.config.cjs : Configure moduleNameMapper in app/jest.config.cjs to map '@/'' to 'src/' and 'tests/' to 'tests/src/'

Applied to files:

  • app/jest.config.cjs
📚 Learning: 2025-08-29T15:31:15.924Z
Learnt from: CR
PR: selfxyz/self#0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-08-29T15:31:15.924Z
Learning: Applies to packages/mobile-sdk-alpha/{**/*.test.{ts,tsx},**/__tests__/**/*.{ts,tsx}} : Do NOT mock selfxyz/mobile-sdk-alpha in tests (avoid jest.mock('selfxyz/mobile-sdk-alpha') and replacing real functions with mocks)

Applied to files:

  • app/jest.config.cjs
📚 Learning: 2025-08-24T18:54:04.809Z
Learnt from: CR
PR: selfxyz/self#0
File: .cursor/rules/mobile-sdk-migration.mdc:0-0
Timestamp: 2025-08-24T18:54:04.809Z
Learning: Applies to app/jest.config.cjs : Use Jest in the app with a React Native preset configured in app/jest.config.cjs

Applied to files:

  • app/jest.config.cjs
📚 Learning: 2025-08-29T15:31:15.924Z
Learnt from: CR
PR: selfxyz/self#0
File: packages/mobile-sdk-alpha/AGENTS.md:0-0
Timestamp: 2025-08-29T15:31:15.924Z
Learning: Applies to packages/mobile-sdk-alpha/{**/*.test.{ts,tsx},**/__tests__/**/*.{ts,tsx}} : Use actual imports from selfxyz/mobile-sdk-alpha in tests

Applied to files:

  • app/jest.config.cjs
📚 Learning: 2025-09-22T11:10:22.019Z
Learnt from: CR
PR: selfxyz/self#0
File: .cursorrules:0-0
Timestamp: 2025-09-22T11:10:22.019Z
Learning: Module mapping `@/` → `src/`, `tests/` → `tests/src/` must be maintained across the project.

Applied to files:

  • app/jest.config.cjs
📚 Learning: 2025-08-29T15:29:47.727Z
Learnt from: CR
PR: selfxyz/self#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:29:47.727Z
Learning: Applies to .github/workflows/**/*.{yml,yaml} : In GitHub Actions workflows, use shared composite caching actions from .github/actions (cache-yarn, cache-bundler, cache-gradle, cache-pods)

Applied to files:

  • .github/workflows/mobile-deploy.yml
  • .github/workflows/mobile-ci.yml
📚 Learning: 2025-09-22T11:10:22.019Z
Learnt from: CR
PR: selfxyz/self#0
File: .cursorrules:0-0
Timestamp: 2025-09-22T11:10:22.019Z
Learning: Test, build, and deploy scripts (`yarn test`, `yarn ios`, `yarn test:e2e:ios`, Fastlane, etc.) must be used for automation.

Applied to files:

  • .github/workflows/mobile-ci.yml
📚 Learning: 2025-08-29T15:29:47.727Z
Learnt from: CR
PR: selfxyz/self#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:29:47.727Z
Learning: Use nvm and Corepack to set up the Yarn v4 monorepo before any other commands (nvm use; corepack enable; corepack prepare yarnstable --activate; yarn install)

Applied to files:

  • .github/workflows/mobile-ci.yml
🪛 actionlint (1.7.7)
.github/workflows/mobile-deploy.yml

122-122: "github.event.pull_request.title" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions for more details

(expression)


639-639: "github.event.pull_request.title" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions for more details

(expression)

⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: GitGuardian Security Checks
🔇 Additional comments (2)
app/jest.config.cjs (2)

1-3: LGTM!

License headers are properly formatted and follow SPDX standards.


9-9: LGTM!

The additions to transformIgnorePatterns for @selfxyz, @sentry, and @anon-aadhaar align with the new module mappings below and are necessary to prevent Jest from transforming these ESM/CJS packages.

Comment on lines 20 to 27
'^@selfxyz/mobile-sdk-alpha$':
'<rootDir>/../packages/mobile-sdk-alpha/dist/cjs/index.cjs',
'^@selfxyz/mobile-sdk-alpha/onboarding/(.*)$':
'<rootDir>/../packages/mobile-sdk-alpha/dist/cjs/flows/onboarding/$1.cjs',
'^@selfxyz/mobile-sdk-alpha/disclosing/(.*)$':
'<rootDir>/../packages/mobile-sdk-alpha/dist/cjs/flows/disclosing/$1.cjs',
'^@selfxyz/mobile-sdk-alpha/(.*)$':
'<rootDir>/../packages/mobile-sdk-alpha/dist/cjs/$1.cjs',
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify that pre-built artifacts are always available before tests run.

These mappings point to compiled CJS artifacts in dist/cjs/ rather than source TypeScript files. If the mobile-sdk-alpha package hasn't been built or if the build is stale, tests will fail or run against outdated code.

Based on learnings, tests should use actual imports from the package. Ensure your CI pipeline builds @selfxyz/mobile-sdk-alpha before running these tests, or consider mapping to source files instead of built artifacts.

Run this script to check if the dist artifacts exist and if there's a build step in CI:


🏁 Script executed:

#!/bin/bash
# Check if the mapped CJS files exist
fd --type f '\.cjs$' packages/mobile-sdk-alpha/dist/cjs/ | head -20

# Check if CI builds mobile-sdk-alpha before app tests
rg -n "mobile-sdk-alpha.*build" .github/workflows/

Length of output: 885


Fix moduleNameMapper paths or include a pretest SDK build
Entries 20–27 point at packages/mobile-sdk-alpha/dist/cjs/, which doesn’t exist until you run yarn workspace @selfxyz/mobile-sdk-alpha build. Either map to source files (src/…) for local tests or add a pretest build step so dist/cjs/ is present.

🤖 Prompt for AI Agents
In app/jest.config.cjs around lines 20 to 27 the moduleNameMapper targets
packages/mobile-sdk-alpha/dist/cjs/* which doesn't exist until the package is
built; update the mappings to point at the package source (src/...) paths so
tests run against local source, or add a pretest step in package.json (or
workspace root) that runs yarn workspace @selfxyz/mobile-sdk-alpha build before
tests to ensure dist/cjs/ is present; pick one approach and update
jest.config.cjs or the test script accordingly so mapped paths resolve during
test runs.

@transphorm transphorm merged commit 48f8d79 into main Oct 4, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants