Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 82 additions & 68 deletions .github/workflows/mobile-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ env:
# Path configuration
WORKSPACE: ${{ github.workspace }}
APP_PATH: ${{ github.workspace }}/app
# Cache versions
GH_CACHE_VERSION: v1 # Global cache version
GH_GEMS_CACHE_VERSION: v1 # Ruby gems cache version
# Performance optimizations
GRADLE_OPTS: -Dorg.gradle.daemon=false -Dorg.gradle.workers.max=4 -Dorg.gradle.parallel=true -Dorg.gradle.configureondemand=true -Dorg.gradle.caching=true
CI: true
on:
push:
paths:
Expand All @@ -19,7 +25,7 @@ on:

jobs:
lint:
runs-on: macos-14
runs-on: macos-latest
Copy link
Member Author

Choose a reason for hiding this comment

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

this fixes the failing 16.4 error. missed it from earlier

steps:
- uses: actions/checkout@v4
- name: Read and sanitize Node.js version
Expand Down Expand Up @@ -62,7 +68,7 @@ jobs:
working-directory: ./app

test:
runs-on: macos-14
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Read and sanitize Node.js version
Expand Down Expand Up @@ -102,7 +108,11 @@ jobs:
run: yarn test
working-directory: ./app
build:
runs-on: macos-14
runs-on: macos-latest
env:
# iOS project configuration - hardcoded for CI stability
IOS_PROJECT_NAME: "Self"
IOS_PROJECT_SCHEME: "OpenPassport"
steps:
- uses: actions/checkout@v4
- name: Read and sanitize Node.js version
Expand Down Expand Up @@ -147,50 +157,44 @@ jobs:
bundler-cache: false
working-directory: ./app

- uses: actions/checkout@v4
- name: Cache 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') }}
path: app/node_modules
key: ${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-${{ hashFiles('app/yarn.lock') }}
restore-keys: |
${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-yarn-
- name: Cache Ruby Bundler
uses: actions/cache@v4
${{ runner.os }}-node-${{ env.NODE_VERSION_SANITIZED }}-
- name: Cache Ruby gems
uses: ./.github/actions/cache-bundler
with:
path: app/vendor/bundle
key: ${{ runner.os }}-ruby${{ env.RUBY_VERSION }}-gems-${{ hashFiles('app/Gemfile.lock') }}
lock-file: app/Gemfile.lock
cache-version: ${{ env.GH_CACHE_VERSION }}-${{ env.GH_GEMS_CACHE_VERSION }}-ruby${{ env.RUBY_VERSION }}
- name: Cache Pods
uses: ./.github/actions/cache-pods
with:
path: |
app/ios/Pods
~/Library/Caches/CocoaPods
lock-file: app/ios/Podfile.lock
- name: Cache Xcode build
uses: actions/cache@v4
with:
path: |
app/ios/build
~/Library/Developer/Xcode/DerivedData
~/Library/Caches/com.apple.dt.Xcode
key: ${{ runner.os }}-xcode-${{ hashFiles('app/ios/Podfile.lock') }}-${{ hashFiles('app/ios/${{ env.IOS_PROJECT_NAME }}.xcworkspace/contents.xcworkspacedata') }}
restore-keys: |
Comment on lines +181 to 188
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

Cache key won’t include workspace hash due to unevaluated expression inside hashFiles().

hashFiles() won’t expand ${{ env.IOS_PROJECT_NAME }} when it’s inside the quoted path literal. The call will likely return an empty hash, reducing cache uniqueness.

Use a glob that doesn’t require expression interpolation:

-          key: ${{ runner.os }}-xcode-${{ hashFiles('app/ios/Podfile.lock') }}-${{ hashFiles('app/ios/${{ env.IOS_PROJECT_NAME }}.xcworkspace/contents.xcworkspacedata') }}
+          key: ${{ runner.os }}-xcode-${{ hashFiles('app/ios/Podfile.lock') }}-${{ hashFiles('app/ios/*.xcworkspace/contents.xcworkspacedata') }}
📝 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
uses: actions/cache@v4
with:
path: |
app/ios/build
~/Library/Developer/Xcode/DerivedData
~/Library/Caches/com.apple.dt.Xcode
key: ${{ runner.os }}-xcode-${{ hashFiles('app/ios/Podfile.lock') }}-${{ hashFiles('app/ios/${{ env.IOS_PROJECT_NAME }}.xcworkspace/contents.xcworkspacedata') }}
restore-keys: |
uses: actions/cache@v4
with:
path: |
app/ios/build
~/Library/Developer/Xcode/DerivedData
~/Library/Caches/com.apple.dt.Xcode
key: ${{ runner.os }}-xcode-${{ hashFiles('app/ios/Podfile.lock') }}-${{ hashFiles('app/ios/*.xcworkspace/contents.xcworkspacedata') }}
restore-keys: |
🤖 Prompt for AI Agents
In .github/workflows/mobile-ci.yml around lines 181-188, the hashFiles() call
embeds the env expression inside a quoted path so ${{ env.IOS_PROJECT_NAME }}
won’t be expanded, making the workspace hash empty; fix by using a glob that
doesn’t require interpolation (e.g.
hashFiles('app/ios/**/contents.xcworkspacedata')) and include the
IOS_PROJECT_NAME separately in the cache key (e.g. ...-${{ env.IOS_PROJECT_NAME
}}), or alternatively compute the workspace path before using hashFiles so the
path string passed to hashFiles contains no unevaluated expressions.

${{ runner.os }}-ruby${{ env.RUBY_VERSION }}-gems-
- name: Cache CocoaPods
${{ runner.os }}-xcode-${{ hashFiles('app/ios/Podfile.lock') }}-
${{ runner.os }}-xcode-
- name: Cache Xcode Index
uses: actions/cache@v4
with:
path: app/ios/Pods
key: ${{ runner.os }}-pods-${{ hashFiles('app/ios/Podfile.lock') }}
path: app/ios/build/Index.noindex
key: ${{ runner.os }}-xcode-index-${{ hashFiles('app/ios/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
- name: Verify CocoaPods Cache
run: |
echo "Checking CocoaPods cache status..."
if [ -d "app/ios/Pods" ] && [ "$(ls -A app/ios/Pods)" ]; then
echo "✅ CocoaPods cache restored successfully"
ls -la app/ios/Pods/ | head -10

# Check if key files exist
if [ ! -f "app/ios/Podfile.lock" ]; then
echo "⚠️ Podfile.lock is missing - pods cache may be stale"
fi
# If Pods directory exists but is incomplete, clear only Pods; keep Podfile.lock
if [ ! -d "app/ios/Pods" ] || [ -z "$(ls -A app/ios/Pods 2>/dev/null)" ]; then
echo "⚠️ Pods directory incomplete - clearing Pods (preserving Podfile.lock)"
rm -rf app/ios/Pods
fi
else
echo "⚠️ CocoaPods cache is empty or missing - will install fresh"
fi
${{ runner.os }}-xcode-index-
- name: Cache Gradle
uses: actions/cache@v4
with:
Expand Down Expand Up @@ -219,7 +223,10 @@ jobs:
- name: Install Mobile Dependencies
uses: ./.github/actions/yarn-install
- name: Build Dependencies
run: yarn build:deps
run: |
echo "Building dependencies..."
yarn workspace @selfxyz/mobile-app run build:deps --silent || { echo "❌ Dependency build failed"; exit 1; }
echo "✅ Dependencies built successfully"
working-directory: ./app
- name: Install Ruby Dependencies
run: |
Expand All @@ -230,40 +237,18 @@ jobs:
- name: Install iOS Dependencies
run: |
echo "Installing iOS dependencies..."

# Clean Pods directory if it's corrupted or empty
if [ ! -d "Pods" ] || [ -z "$(ls -A Pods 2>/dev/null)" ]; then
echo "Cleaning empty/corrupted Pods directory..."
rm -rf Pods Podfile.lock
fi

# Install pods
bundle exec pod install --silent || { echo "❌ Pod install failed"; exit 1; }
(cd app/ios && pod install --silent) || { echo "❌ Pod install failed"; exit 1; }
echo "✅ Pods installed successfully"

# Verify installation
if [ ! -d "Pods" ] || [ -z "$(ls -A Pods 2>/dev/null)" ]; then
echo "❌ Pods directory is still empty after installation"
exit 1
fi

echo "Pods directory contents:"
ls -la Pods/ | head -10

# Verify key files exist
if [ ! -f "Pods/Target Support Files/Pods-Self/Pods-Self.debug.xcconfig" ]; then
echo "❌ Key CocoaPods configuration file missing"
exit 1
fi

echo "✅ iOS dependencies installed successfully"
working-directory: ./app/ios
- name: Verify iOS Workspace
Comment on lines 238 to 243
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

Fix double-directory traversal in Pods install (cd into app/ios twice).

The step’s working-directory is already ./app/ios. The subshell cd app/ios causes path resolution to ./app/ios/app/ios, breaking pod install.

Apply this diff:

-      - name: Install iOS Dependencies
+      - name: Install iOS Dependencies
         run: |
           echo "Installing iOS dependencies..."
-          (cd app/ios && pod install --silent) || { echo "❌ Pod install failed"; exit 1; }
+          pod install --silent || { echo "❌ Pod install failed"; exit 1; }
           echo "✅ Pods installed successfully"
         working-directory: ./app/ios
📝 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
run: |
echo "Installing iOS dependencies..."
# Clean Pods directory if it's corrupted or empty
if [ ! -d "Pods" ] || [ -z "$(ls -A Pods 2>/dev/null)" ]; then
echo "Cleaning empty/corrupted Pods directory..."
rm -rf Pods Podfile.lock
fi
# Install pods
bundle exec pod install --silent || { echo "❌ Pod install failed"; exit 1; }
(cd app/ios && pod install --silent) || { echo "❌ Pod install failed"; exit 1; }
echo "✅ Pods installed successfully"
# Verify installation
if [ ! -d "Pods" ] || [ -z "$(ls -A Pods 2>/dev/null)" ]; then
echo "❌ Pods directory is still empty after installation"
exit 1
fi
echo "Pods directory contents:"
ls -la Pods/ | head -10
# Verify key files exist
if [ ! -f "Pods/Target Support Files/Pods-Self/Pods-Self.debug.xcconfig" ]; then
echo "❌ Key CocoaPods configuration file missing"
exit 1
fi
echo "✅ iOS dependencies installed successfully"
working-directory: ./app/ios
- name: Verify iOS Workspace
- name: Install iOS Dependencies
run: |
echo "Installing iOS dependencies..."
pod install --silent || { echo "❌ Pod install failed"; exit 1; }
echo "✅ Pods installed successfully"
working-directory: ./app/ios
🤖 Prompt for AI Agents
.github/workflows/mobile-ci.yml around lines 238 to 243: the run step currently
cds into app/ios even though the job already sets working-directory: ./app/ios,
causing a double traversal to ./app/ios/app/ios and breaking pod install; remove
the subshell cd and run pod install --silent directly (e.g., run: echo
"Installing iOS dependencies..." ; pod install --silent || { echo "❌ Pod install
failed"; exit 1; } ; echo "✅ Pods installed successfully") so the command
executes in the declared working-directory.

run: |
echo "Verifying iOS workspace setup..."

if [ ! -f "OpenPassport.xcworkspace/contents.xcworkspacedata" ]; then
echo "❌ OpenPassport.xcworkspace is missing or corrupted"
WORKSPACE_PATH="app/ios/${{ env.IOS_PROJECT_NAME }}.xcworkspace"
if [ ! -d "$WORKSPACE_PATH" ]; then
echo "❌ Workspace not found at: $WORKSPACE_PATH"
echo "Available workspaces:"
find app/ios -name "*.xcworkspace" -type d
exit 1
fi

Expand All @@ -272,10 +257,39 @@ jobs:
exit 1
fi

# Verify scheme exists by listing available schemes
echo "Verifying scheme availability..."
AVAILABLE_SCHEMES=$(xcodebuild -list -workspace "$WORKSPACE_PATH" 2>/dev/null | grep -A 200 "Schemes:" | grep -v "Schemes:" | xargs)
echo "Available schemes (first 20): $(echo $AVAILABLE_SCHEMES | cut -d' ' -f1-20)..."

if [[ ! "$AVAILABLE_SCHEMES" =~ ${{ env.IOS_PROJECT_SCHEME }} ]]; then
echo "❌ Scheme '${{ env.IOS_PROJECT_SCHEME }}' not found"
echo "Full scheme list:"
xcodebuild -list -workspace "$WORKSPACE_PATH" 2>/dev/null | grep -A 200 "Schemes:" | grep -v "Schemes:" | head -50
exit 1
fi

echo "✅ iOS workspace is properly configured"
echo "✅ Using workspace: $WORKSPACE_PATH"
echo "✅ Using scheme: ${{ env.IOS_PROJECT_SCHEME }}"
working-directory: ./app/ios
- name: Build iOS
run: yarn ios
run: |
echo "Building iOS app..."
echo "Project: ${{ env.IOS_PROJECT_NAME }}, Scheme: ${{ env.IOS_PROJECT_SCHEME }}"

WORKSPACE_PATH="app/ios/${{ env.IOS_PROJECT_NAME }}.xcworkspace"

# Use cached derived data and enable parallel builds for faster compilation
xcodebuild -workspace "$WORKSPACE_PATH" \
-scheme ${{ env.IOS_PROJECT_SCHEME }} \
-configuration Release \
-destination "generic/platform=iOS" \
-derivedDataPath app/ios/build \
-jobs "$(sysctl -n hw.ncpu)" \
-parallelizeTargets \
-quiet || { echo "❌ iOS build failed"; exit 1; }
echo "✅ iOS build succeeded"
working-directory: ./app
- name: Build Android
run: yarn android
Expand Down
8 changes: 5 additions & 3 deletions app/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -93,24 +93,26 @@ module.exports = {
],

// Prevent empty lines at the beginning and end of files, and limit consecutive empty lines
// Exception: allow one empty line after license header at file start

'no-multiple-empty-lines': [
'error',
{
max: 1,
maxEOF: 0,
maxBOF: 0,
maxBOF: 1, // Allow one empty line at beginning (for license header)
},
],
// Enforce empty line after header comments (but not at file start)
// Keep lines-around-comment rule disabled for normal comments
// License header newlines will be enforced by the check-license-headers.mjs script

'lines-around-comment': [
'error',
{
beforeBlockComment: false,
afterBlockComment: false,
beforeLineComment: false,
afterLineComment: false,
afterLineComment: false, // Keep disabled - license script handles this
allowBlockStart: true,
allowBlockEnd: false,
allowObjectStart: false,
Expand Down
21 changes: 12 additions & 9 deletions app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { LoggerProvider } from './src/providers/loggerProvider';
import { NotificationTrackingProvider } from './src/providers/notificationTrackingProvider';
import { PassportProvider } from './src/providers/passportDataProvider';
import { RemoteConfigProvider } from './src/providers/remoteConfigProvider';
import { SelfClientProvider } from './src/providers/selfClientProvider';
import { initSentry, wrapWithSentry } from './src/Sentry';

initSentry();
Expand All @@ -25,15 +26,17 @@ function App(): React.JSX.Element {
<YStack flex={1} height="100%" width="100%">
<RemoteConfigProvider>
<LoggerProvider>
<AuthProvider>
<PassportProvider>
<DatabaseProvider>
<NotificationTrackingProvider>
<AppNavigation />
</NotificationTrackingProvider>
</DatabaseProvider>
</PassportProvider>
</AuthProvider>
<SelfClientProvider>
<AuthProvider>
<PassportProvider>
<DatabaseProvider>
<NotificationTrackingProvider>
<AppNavigation />
</NotificationTrackingProvider>
</DatabaseProvider>
</PassportProvider>
</AuthProvider>
</SelfClientProvider>
</LoggerProvider>
</RemoteConfigProvider>
</YStack>
Expand Down
4 changes: 2 additions & 2 deletions app/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ GEM
artifactory (3.0.17)
atomos (0.1.3)
aws-eventstream (1.4.0)
aws-partitions (1.1147.0)
aws-partitions (1.1148.0)
aws-sdk-core (3.229.0)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
Expand All @@ -37,7 +37,7 @@ GEM
aws-sdk-kms (1.110.0)
aws-sdk-core (~> 3, >= 3.228.0)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.196.1)
aws-sdk-s3 (1.197.0)
aws-sdk-core (~> 3, >= 3.228.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
Expand Down
5 changes: 3 additions & 2 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@
"ios": "yarn build:deps && react-native run-ios --scheme OpenPassport",
"ios:fastlane-debug": "yarn reinstall && bundle exec fastlane --verbose ios internal_test",
"lint": "yarn lint:headers && eslint .",
"lint:fix": "yarn lint:headers && eslint --fix .",
"lint:headers": "node scripts/check-duplicate-headers.cjs",
"lint:fix": "yarn lint:headers:fix && eslint --fix .",
"lint:headers": "node scripts/check-duplicate-headers.cjs && node scripts/check-license-headers.mjs --check",
"lint:headers:fix": "node scripts/check-duplicate-headers.cjs && node scripts/check-license-headers.mjs --fix",
"mobile-deploy": "node scripts/mobile-deploy-confirm.cjs both",
"mobile-deploy:android": "node scripts/mobile-deploy-confirm.cjs android",
"mobile-deploy:ios": "node scripts/mobile-deploy-confirm.cjs ios",
Expand Down
1 change: 1 addition & 0 deletions app/scripts/check-duplicate-headers.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ function main() {
// Get all relevant files
const patterns = EXTENSIONS.map(ext => path.join('src', ext));
patterns.push(...EXTENSIONS.map(ext => path.join('tests', ext)));
patterns.push(...EXTENSIONS.map(ext => path.join('scripts', ext)));
patterns.push('*.ts', '*.tsx', '*.js', '*.jsx');

for (const pattern of patterns) {
Expand Down
Loading
Loading