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: 5 additions & 0 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v5

- name: Setup Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: 16.4

- name: Create working directory
run: mkdir -p ${{ env.WORKING_DIR }}

Expand Down
59 changes: 33 additions & 26 deletions .github/workflows/test-nitro-cli.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
name: Test Nitro CLI - Generate & Build

# Minimal permissions for downloading artifacts from other runs
permissions:
contents: write
contents: read
actions: read

on:
Expand All @@ -18,15 +19,18 @@ concurrency:
jobs:
test-ios-build:
name: Test iOS Build - ${{ matrix.pm }} - ${{ matrix.package-type }} (${{ matrix.mode }})
if: github.event.workflow_run.conclusion == 'success'
runs-on: macOS-15
# Run on successful upstream, or when manually dispatched
if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success'
runs-on: macOS-latest
strategy:
Comment on lines +23 to 25
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Bug: manual dispatch path lacks a run-id for artifact download.

When workflow_dispatch triggers this workflow, ${{ github.event.workflow_run.id }} is undefined and the download step will fail.

Add an optional input and use it when manually dispatched:

 on:
   workflow_run:
     workflows: ['Generate Packages']
     types:
       - completed
-  workflow_dispatch:
+  workflow_dispatch:
+    inputs:
+      upstream_run_id:
+        description: 'Run ID of the upstream "Generate Packages" workflow'
+        required: false
+        type: string

Then select the run-id:

-  run-id: ${{ github.event.workflow_run.id }}
+  run-id: ${{ github.event.workflow_run.id || inputs.upstream_run_id }}

And guard the step when neither is present:

-  - name: Download generated package
+  - name: Download generated package
+    if: github.event_name == 'workflow_dispatch' && inputs.upstream_run_id || github.event_name == 'workflow_run'

Also applies to: 38-46

fail-fast: false
matrix:
pm: ['bun', 'yarn']
package-type: ['module', 'view']
mode: ['Debug', 'Release']
env:
WORKING_DIR: ${{ github.workspace }}/react-native-test-${{ matrix.package-type }}
SCHEME: ${{ matrix.package-type == 'module' && 'TestModuleExample' || 'TestViewExample' }}
steps:
- name: Create working directory
run: mkdir -p ${{ env.WORKING_DIR }}
Expand Down Expand Up @@ -57,14 +61,8 @@ jobs:
ruby-version: '3.2'
bundler-cache: true

- name: Setup pnpm
if: matrix.pm == 'pnpm'
uses: pnpm/action-setup@v4
with:
version: 10

- name: Setup Node.js
if: matrix.pm == 'yarn' || matrix.pm == 'pnpm'
if: matrix.pm == 'yarn'
uses: actions/setup-node@v4
with:
node-version: 22.x
Expand Down Expand Up @@ -95,6 +93,16 @@ jobs:
${{ matrix.pm }} run build
node post-script.js

- name: Cache CocoaPods
uses: actions/cache@v4
with:
path: |
~/.cocoapods/repos
${{ env.WORKING_DIR }}/example/ios/Pods
key: ${{ runner.os }}-pods-${{ hashFiles(format('{0}/example/ios/Podfile.lock', env.WORKING_DIR)) }}
restore-keys: |
${{ runner.os }}-pods-

- name: Install CocoaPods dependencies
working-directory: ${{ env.WORKING_DIR }}/example
run: ${{ matrix.pm }} pod
Expand All @@ -106,18 +114,11 @@ jobs:
- name: Build iOS project
working-directory: ${{ env.WORKING_DIR }}/example/ios
run: |
# Get the correct scheme name based on package type
if [ "${{ matrix.package-type }}" == "module" ]; then
SCHEME="TestModuleExample"
else
SCHEME="TestViewExample"
fi

set -o pipefail && xcodebuild \
CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ \
-derivedDataPath build -UseModernBuildSystem=YES \
-workspace "${SCHEME}.xcworkspace" \
-scheme "$SCHEME" \
-scheme "${SCHEME}" \
-sdk iphonesimulator \
-configuration ${{ matrix.mode }} \
-destination 'platform=iOS Simulator,name=iPhone 16' \
Expand All @@ -126,9 +127,11 @@ jobs:

test-android-build:
name: Test Android Build - ${{ matrix.pm }} - ${{ matrix.package-type }} (${{ matrix.mode }})
if: github.event.workflow_run.conclusion == 'success'
# Run on successful upstream, or when manually dispatched
if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
pm: ['bun', 'yarn']
package-type: ['module', 'view']
Expand All @@ -154,14 +157,8 @@ jobs:
echo "Package structure:"
find . -type f -name "*.json" -o -name "*.js" -o -name "*.ts" | head -20

- name: Setup pnpm
if: matrix.pm == 'pnpm'
uses: pnpm/action-setup@v4
with:
version: 10

- name: Setup Node.js
if: matrix.pm == 'yarn' || matrix.pm == 'pnpm'
if: matrix.pm == 'yarn'
uses: actions/setup-node@v4
with:
node-version: 22.x
Expand Down Expand Up @@ -203,6 +200,16 @@ jobs:
working-directory: ${{ env.WORKING_DIR }}/example/android
run: chmod +x ./gradlew

- name: Cache Gradle
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles(format('{0}/example/android/**/*.gradle*', env.WORKING_DIR)) }}
restore-keys: |
${{ runner.os }}-gradle-

- name: Clean and generate codegen artifacts
working-directory: ${{ env.WORKING_DIR }}/example/android
run: |
Expand Down
62 changes: 27 additions & 35 deletions assets/template/.github/workflows/android-build.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
name: Build Android

permissions:
contents: read

on:
push:
branches:
Expand All @@ -25,63 +28,52 @@ on:
- '**/bun.lock'
- '**/react-native.config.js'
- '**/nitro.json'
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build_new:
name: Build Android Example App (new architecture)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2

- name: Install npm dependencies (bun)
run: bun install

- name: Setup JDK 17
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: 17
java-package: jdk
cache: gradle

- name: Run Gradle Build for example/android/
working-directory: example/android
run: ./gradlew assembleDebug --no-daemon --build-cache

- name: Stop Gradle Daemon
working-directory: example/android
run: ./gradlew --stop

build_old:
name: Build Android Example App (old architecture)
build:
name: Build Android Example App (${{ matrix.arch }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
arch: [new, old]
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2

- name: Install npm dependencies (bun)
- name: Install dependencies (bun)
run: bun install

- name: Disable new architecture in gradle.properties
if: matrix.arch == 'old'
run: sed -i "s/newArchEnabled=true/newArchEnabled=false/g" example/android/gradle.properties

- name: Setup JDK 17
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: 'zulu'
java-version: 17
java-package: jdk
cache: gradle
java-version: '17'
cache: 'gradle'

Comment on lines 56 to +62
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid double Gradle caching.

You’re using both setup-java’s cache: gradle and an explicit Gradle cache step. Keep one to prevent redundant restores/saves.

Option A (keep setup-java cache, remove explicit cache):

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

Option B (remove cache: gradle and keep explicit cache with broader key):

-      with:
-        distribution: 'zulu'
-        java-version: '17'
-        cache: 'gradle'
+      with:
+        distribution: 'zulu'
+        java-version: '17'

And widen cache key:

-  key: ${{ runner.os }}-gradle-${{ hashFiles('example/android/**/*.gradle*') }}
+  key: ${{ runner.os }}-gradle-${{ hashFiles('example/android/**/*.gradle*', 'example/android/**/gradle.properties') }}

Also applies to: 63-72

🤖 Prompt for AI Agents
In assets/template/.github/workflows/android-build.yml around lines 56-62 (and
similarly lines 63-72), the workflow currently enables Gradle caching twice by
setting actions/setup-java@v5 with cache: 'gradle' and also using an explicit
Gradle cache step; remove the redundancy by choosing one approach: either remove
the explicit Gradle cache step and rely on setup-java's cache: 'gradle', or
remove cache: 'gradle' from setup-java and keep the explicit cache step, then
widen the explicit cache key to include OS, Gradle wrapper version, and
gradle.properties/hash of build.gradle files to make it more robust; update only
the workflow caching sections accordingly to avoid duplicate restores/saves.

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

- name: Run Gradle Build for example/android/
- name: Run Gradle build
working-directory: example/android
run: ./gradlew assembleDebug --no-daemon --build-cache

- name: Stop Gradle Daemon
- name: Stop Gradle daemon
working-directory: example/android
run: ./gradlew --stop
100 changes: 31 additions & 69 deletions assets/template/.github/workflows/ios-build.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
name: Build iOS

permissions:
contents: read

on:
push:
branches:
Expand Down Expand Up @@ -33,6 +36,7 @@ on:
- '**/*.podspec'
- '**/react-native.config.js'
- '**/nitro.json'
workflow_dispatch:

env:
USE_CCACHE: 1
Expand All @@ -42,9 +46,13 @@ concurrency:
cancel-in-progress: true

jobs:
build_new:
name: Build iOS Example App (new architecture)
build:
name: Build iOS Example App (${{ matrix.arch }})
runs-on: macOS-15
strategy:
fail-fast: false
matrix:
arch: [new, old]
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
Expand All @@ -53,93 +61,47 @@ jobs:
with:
xcode-version: 16.4

- name: Install npm dependencies (bun)
run: bun install

- name: Setup Ruby (bundle)
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.7.2
bundler-cache: true
working-directory: example/ios

- name: Install xcpretty
run: gem install xcpretty

- name: Restore Pods cache
uses: actions/cache@v4
with:
path: example/ios/Pods
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock', '**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
- name: Install Pods
working-directory: example/ios
run: pod install
- name: Build App
working-directory: example/ios
run: "set -o pipefail && xcodebuild \
CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ \
-derivedDataPath build -UseModernBuildSystem=YES \
-workspace $$exampleApp$$.xcworkspace \
-scheme $$exampleApp$$ \
-sdk iphonesimulator \
-configuration Debug \
-destination 'platform=iOS Simulator,name=iPhone 16' \
build \
CODE_SIGNING_ALLOWED=NO | xcpretty"

build_old:
name: Build iOS Example App (old architecture)
runs-on: macOS-15
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2

- name: Setup Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: 16.4

- name: Install npm dependencies (bun)
- name: Install dependencies (bun)
run: bun install

- name: Disable new architecture in Podfile
if: matrix.arch == 'old'
run: sed -i "" "s/ENV\['RCT_NEW_ARCH_ENABLED'\] = '1'/ENV['RCT_NEW_ARCH_ENABLED'] = '0'/g" example/ios/Podfile

- name: Restore buildcache
uses: mikehardy/buildcache-action@v2
continue-on-error: true

- name: Setup Ruby (bundle)
uses: ruby/setup-ruby@v1
with:
ruby-version: 2.7.2
ruby-version: '3.2'
bundler-cache: true
working-directory: example/ios

Comment on lines 71 to 77
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix: ruby/setup-ruby working-directory is misplaced.

ruby/setup-ruby@v1 doesn’t accept working-directory under with. Put it at the step level so Bundler caches against example/ios/Gemfile.

-      - name: Setup Ruby (bundle)
-        uses: ruby/setup-ruby@v1
-        with:
-          ruby-version: '3.2'
-          bundler-cache: true
-          working-directory: example/ios
+      - name: Setup Ruby (bundle)
+        uses: ruby/setup-ruby@v1
+        with:
+          ruby-version: '3.2'
+          bundler-cache: true
+        working-directory: example/ios

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
assets/template/.github/workflows/ios-build.yml around lines 71 to 77: the step
config places working-directory under the `with:` block for ruby/setup-ruby, but
that action expects working-directory at the step level; move
`working-directory: example/ios` out of the `with:` map to be a sibling of
`uses:` and `with:` so the action executes in example/ios and the bundler-cache
targets example/ios/Gemfile.

- name: Install xcpretty
run: gem install xcpretty

- name: Restore Pods cache
- name: Cache CocoaPods
uses: actions/cache@v4
with:
path: example/ios/Pods
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock', '**/Gemfile.lock') }}
path: |
~/.cocoapods/repos
example/ios/Pods
key: ${{ runner.os }}-pods-${{ hashFiles('example/ios/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-

- name: Install Pods
working-directory: example/ios
run: pod install

- name: Build App
working-directory: example/ios
run: "set -o pipefail && xcodebuild \
CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ \
-derivedDataPath build -UseModernBuildSystem=YES \
-workspace $$exampleApp$$.xcworkspace \
-scheme $$exampleApp$$ \
-sdk iphonesimulator \
-configuration Debug \
-destination 'platform=iOS Simulator,name=iPhone 16' \
build \
CODE_SIGNING_ALLOWED=NO | xcpretty"
run: |
set -o pipefail && xcodebuild \
CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ \
-derivedDataPath build -UseModernBuildSystem=YES \
-workspace $$exampleApp$$.xcworkspace \
-scheme $$exampleApp$$ \
-sdk iphonesimulator \
-configuration Debug \
-destination 'platform=iOS Simulator,name=iPhone 16' \
build \
CODE_SIGNING_ALLOWED=NO | xcpretty
Loading
Loading