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
5 changes: 3 additions & 2 deletions .github/actions/setup-maestro/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ runs:
steps:
- run: |
echo "Installing Maestro CLI..."
curl -Ls "https://get.maestro.mobile.dev" | bash
export MAESTRO_VERSION=1.40.0; curl -Ls "https://get.maestro.mobile.dev" | bash

# Add Maestro to PATH for subsequent steps
echo "${HOME}/.maestro/bin" >> $GITHUB_PATH
export PATH="$PATH":"$HOME/.maestro/bin"
echo "$HOME/.maestro/bin" >> $GITHUB_PATH

# Verify installation
maestro --version || echo "Maestro installation verification failed"
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/ci-packages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
- 'src/**'
- '.github/workflows/**'
- '.github/actions/**'
- 'scripts/**'
- 'package.json'
- 'bun.lock'
- 'assets/template/**'
Expand All @@ -16,6 +17,7 @@ on:
- 'src/**'
- '.github/workflows/**'
- '.github/actions/**'
- 'scripts/**'
- 'package.json'
- 'bun.lock'
- 'assets/template/**'
Expand Down Expand Up @@ -515,12 +517,40 @@ jobs:
working-directory: ${{ env.WORKING_DIR }}/example/ios
run: pod install

- name: Setup ccache
run: |
brew install ccache
ccache --version
ccache --zero-stats

- name: Cache ccache
uses: actions/cache@v4
with:
path: ~/Library/Caches/ccache
key: ${{ runner.os }}-ccache-${{ matrix.package-type }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-ccache-${{ matrix.package-type }}-
${{ runner.os }}-ccache-

- name: Configure ccache
run: |
ccache --set-config=max_size=2G
ccache --set-config=compression=true
ccache --set-config=compression_level=6

- name: Install Maestro CLI
uses: ./.github/actions/setup-maestro

- name: Run tests
env:
USE_CCACHE: 1
CCACHE_DIR: ~/Library/Caches/ccache
run: ${{ matrix.pm }} ios:e2e ${{ env.WORKING_DIR }}/example ${{ matrix.package-type }}

- name: Print ccache statistics
if: always()
run: ccache --show-stats

- name: Upload test artifacts
if: always()
uses: actions/upload-artifact@v4
Expand Down
2 changes: 2 additions & 0 deletions assets/template/bunfig.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[install]
linker = "hoisted"
10 changes: 5 additions & 5 deletions assets/template/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/git": "^10.0.1",
"@types/jest": "^29.5.12",
"@types/react": "19.1.0",
"nitrogen": "^0.29.4",
"react": "19.1.0",
"react-native": "0.81.1",
"@types/react": "19.1.1",
"nitrogen": "^0.29.8",
"react": "19.1.1",
"react-native": "0.82",
"react-native-builder-bob": "^0.37.0",
"react-native-nitro-modules": "^0.2942",
"react-native-nitro-modules": "^0.29.8",
"conventional-changelog-conventionalcommits": "^9.1.0",
"semantic-release": "^24.2.9",
"typescript": "^5.8.3"
Expand Down
2 changes: 2 additions & 0 deletions bunfig.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[install]
linker = "hoisted"
1 change: 1 addition & 0 deletions commitlint.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'footer-max-line-length': [0, 'always'],
'body-max-line-length': [0, 'always'],
},
}
58 changes: 40 additions & 18 deletions scripts/e2e-maestro.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@

trap 'exit' INT

# Save the script directory (project root)
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )"

PLATFORM=${1:-}
EXAMPLE_DIR=${2:-}
PACKAGE_TYPE=${3:-}

echo "🚀 Running e2e tests for $PLATFORM"
echo "🚀 Running e2e video recording for $PLATFORM"
echo "📂 Project root: $SCRIPT_DIR"

# Validate passed platform
case $PLATFORM in
Expand Down Expand Up @@ -46,17 +50,29 @@ if [ "$PLATFORM" == "ios" ]; then

# Build the app with optimizations and pretty output
export USE_CCACHE=1
# Configure ccache if available (optional optimization)
if command -v ccache >/dev/null 2>&1; then
export CCACHE_DIR="${CCACHE_DIR:-$HOME/Library/Caches/ccache}"
mkdir -p "$CCACHE_DIR"
export PATH="/opt/homebrew/bin:$PATH"
echo "✅ ccache is available"
echo "📦 ccache directory: $CCACHE_DIR"
ccache --max-size=2G 2>/dev/null || true
else
echo "⚠️ ccache not found (optional). Install with: brew install ccache"
fi

buildCmd="xcodebuild \
CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ \
-derivedDataPath build \
-UseModernBuildSystem=YES \
-workspace $SCHEME.xcworkspace \
-configuration Release \
-scheme $SCHEME \
-configuration Release \
-destination id=$iphone16Id \
-parallelizeTargets \
-derivedDataPath build \
-jobs $(sysctl -n hw.ncpu) \
ONLY_ACTIVE_ARCH=YES \
ARCHS=arm64 \
VALID_ARCHS=arm64 \
EXCLUDED_ARCHS=x86_64 \
CODE_SIGNING_ALLOWED=NO"
Comment on lines +68 to 76
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

iOS build arch overrides are non‑portable; VALID_ARCHS is deprecated.

Hard‑forcing ARCHS=arm64 and EXCLUDED_ARCHS=x86_64 breaks Intel runners; VALID_ARCHS no longer respected in modern Xcode. Prefer letting the simulator SDK resolve archs or gate by host CPU.

-    -configuration Release \
+    -configuration Release -sdk iphonesimulator \
     -destination id=$iphone16Id \
     -derivedDataPath build \
     -jobs $(sysctl -n hw.ncpu) \
-    ONLY_ACTIVE_ARCH=YES \
-    ARCHS=arm64 \
-    VALID_ARCHS=arm64 \
-    EXCLUDED_ARCHS=x86_64 \
     CODE_SIGNING_ALLOWED=NO"

Optionally gate EXCLUDED_ARCHS by host:

if [[ "$(uname -m)" == "x86_64" ]]; then EXCLUDED=""; else EXCLUDED="EXCLUDED_ARCHS=x86_64"; fi


echo "🔨 Building iOS app..."
Expand Down Expand Up @@ -92,7 +108,8 @@ if [ "$PLATFORM" == "ios" ]; then
echo "📲 Installing app from: $APP_PATH"
xcrun simctl install $iphone16Id "$APP_PATH"

cd ../../..
# Return to project root
cd "$SCRIPT_DIR"
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Fail fast if returning to the project root fails.

Both cd "$SCRIPT_DIR" calls should guard against failure; otherwise the script keeps running from the wrong directory and the rest of the flow breaks. Add || exit 1.

-  cd "$SCRIPT_DIR"
+  cd "$SCRIPT_DIR" || exit 1
-  cd "$SCRIPT_DIR"
+  cd "$SCRIPT_DIR" || exit 1

Also applies to: 135-135

🧰 Tools
🪛 Shellcheck (0.11.0)

[warning] 112-112: Use 'cd ... || exit' or 'cd ... || return' in case cd fails.

(SC2164)

🤖 Prompt for AI Agents
In scripts/e2e-maestro.sh around lines 112 and 135, the two cd "$SCRIPT_DIR"
invocations do not check for failure; if changing directories fails the script
will continue running from the wrong location. Update both cd commands to guard
against errors by exiting on failure (i.e., append a conditional exit such as ||
exit 1) so the script fails fast if returning to the project root fails.

else
cd $EXAMPLE_DIR/android
chmod +x ./gradlew
Expand All @@ -113,35 +130,40 @@ else
# Stop Gradle daemon to free up memory
echo "🧹 Stopping Gradle daemon..."
./gradlew --stop
cd ../../..

# Return to project root
cd "$SCRIPT_DIR"
fi

echo "📂 Script directory: $(pwd)"
echo ""

test_file="e2e-tests/$PACKAGE_TYPE.e2e.yaml"

echo "🧪 Using test file: $test_file"
echo "🎬 Using flow file for recording: $test_file"

if [ ! -f "$test_file" ]; then
echo "❌ Error! Test file not found: $test_file"
echo "❌ Error! Flow file not found: $test_file"
echo ""
exit 1
fi

testCmd="maestro test \"$test_file\" -e APP_ID=$APP_ID --flatten-debug-output"
echo "🎯 Running test: $testCmd"
# Create output directory for videos
mkdir -p e2e-artifacts

recordCmd="maestro record \"$test_file\" -e APP_ID=$APP_ID --local"
echo "🎯 Recording test video: $recordCmd"
echo "📱 APP_ID: $APP_ID"


if ! eval "$testCmd --debug-output e2e-artifacts/$PACKAGE_TYPE"; then
echo "Test ${test_file} failed. Retrying in 30 seconds..."
if ! eval "$recordCmd --debug-output e2e-artifacts/$PACKAGE_TYPE"; then
echo "Recording ${test_file} failed. Retrying in 30 seconds..."
sleep 30
if ! eval "$testCmd --debug-output e2e-artifacts/$PACKAGE_TYPE-retry-1"; then
echo "Test ${test_file} failed again. Retrying for the last time in 120 seconds..."
if ! eval "$recordCmd --debug-output e2e-artifacts/$PACKAGE_TYPE-retry-1"; then
echo "Recording ${test_file} failed again. Retrying for the last time in 120 seconds..."
sleep 120
if ! eval "$testCmd --debug-output e2e-artifacts/$PACKAGE_TYPE-retry-2"; then
echo "Test ${test_file} failed again. Exiting..."
if ! eval "$recordCmd --debug-output e2e-artifacts/$PACKAGE_TYPE-retry-2"; then
echo "Recording ${test_file} failed again. Exiting..."
exit 1
fi
fi
Expand Down
4 changes: 4 additions & 0 deletions src/generate-nitro-package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,10 @@ export class NitroModuleFactory {
'LICENSE',
]

if (this.config.pm === 'bun') {
filesToCopy.push('bunfig.toml')
}

await copyTemplateFiles(
this.config,
[__dirname, '..', 'assets', 'template'],
Expand Down