Skip to content

Commit f9b0365

Browse files
authored
refactor(ffi): split direct engine backends
Generated by Codex. Squashes PR #33 after CI passed.
1 parent 4ac13af commit f9b0365

168 files changed

Lines changed: 25682 additions & 1325 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ jobs:
2020
- name: Install Dependencies
2121
run: npm install
2222

23+
- name: Check FFI backend boundaries
24+
run: npm run check:ffi-boundaries
25+
2326
- name: Download V8
2427
run: ./scripts/download_v8.sh
2528

@@ -49,4 +52,6 @@ jobs:
4952
IOS_BUILD_TIMEOUT_MS: "600000"
5053
IOS_TEST_TIMEOUT_MS: "600000"
5154
IOS_TEST_INACTIVITY_TIMEOUT_MS: "180000"
55+
IOS_TEST_VERBOSE_SPECS: "1"
56+
IOS_SIMCTL_QUERY_TIMEOUT_MS: "10000"
5257
run: npm run test:ios

.github/workflows/npm_trusted_release.yml

Lines changed: 137 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1-
name: NPM Trusted Release (iOS engines)
1+
name: NPM Trusted Release
22

3-
# Publishes one or more engine-specific NativeScript iOS runtime packages
3+
# Publishes one or more NativeScript iOS npm packages
44
# (@nativescript/ios-v8, @nativescript/ios-hermes, @nativescript/ios-jsc,
5-
# @nativescript/ios-quickjs) via npm trusted publishing (OIDC).
5+
# @nativescript/ios-quickjs, @nativescript/react-native) via npm trusted
6+
# publishing (OIDC).
67
#
78
# Each package must be configured on npmjs.com with a trusted publisher that
89
# points at this repository + workflow + environment. With `engine: all`, the
9-
# workflow fans out across all four engines via a matrix.
10+
# workflow fans out across the four iOS engine packages via a matrix; use
11+
# `engine: react-native` to publish @nativescript/react-native.
1012

1113
on:
1214
workflow_dispatch:
1315
inputs:
1416
engine:
15-
description: "Engine to release (or 'all' to publish every engine)"
17+
description: "Package to release (engine package, react-native, or 'all' for every iOS engine)"
1618
required: true
1719
type: choice
1820
default: v8
@@ -21,6 +23,7 @@ on:
2123
- hermes
2224
- jsc
2325
- quickjs
26+
- react-native
2427
- all
2528
release-type:
2629
description: "Version bump (patch/minor/major publish to 'latest'; prerelease uses 'preid' as the dist-tag)"
@@ -32,6 +35,10 @@ on:
3235
- patch
3336
- minor
3437
- major
38+
version:
39+
description: "Exact npm version to publish; overrides release-type/preid. Use a prerelease version for preview publishes, e.g. 9.0.0-preview.0"
40+
required: false
41+
type: string
3542
preid:
3643
description: "Prerelease identifier (used only when release-type=prerelease; also becomes the npm dist-tag, e.g. next | canary)"
3744
required: false
@@ -44,7 +51,7 @@ on:
4451
default: true
4552

4653
concurrency:
47-
# Avoid overlapping publishes on the same ref/engine selection.
54+
# Avoid overlapping publishes on the same ref/package selection.
4855
group: npm-trusted-release-${{ github.ref }}-${{ inputs.engine }}
4956
cancel-in-progress: false
5057

@@ -53,34 +60,45 @@ env:
5360

5461
jobs:
5562
matrix:
56-
name: Resolve engine matrix
63+
name: Resolve package matrix
5764
runs-on: ubuntu-latest
65+
permissions: {}
5866
outputs:
59-
engines: ${{ steps.compute.outputs.engines }}
67+
targets: ${{ steps.compute.outputs.targets }}
6068
steps:
6169
- name: Compute matrix
6270
id: compute
71+
env:
72+
ENGINE: ${{ inputs.engine }}
6373
run: |
64-
if [ "${{ inputs.engine }}" = "all" ]; then
65-
echo 'engines=["v8","hermes","jsc","quickjs"]' >> "$GITHUB_OUTPUT"
66-
else
67-
echo "engines=[\"${{ inputs.engine }}\"]" >> "$GITHUB_OUTPUT"
68-
fi
74+
set -euo pipefail
75+
case "$ENGINE" in
76+
all)
77+
echo 'targets=["v8","hermes","jsc","quickjs"]' >> "$GITHUB_OUTPUT"
78+
;;
79+
v8|hermes|jsc|quickjs|react-native)
80+
printf 'targets=["%s"]\n' "$ENGINE" >> "$GITHUB_OUTPUT"
81+
;;
82+
*)
83+
echo "Unsupported engine: $ENGINE" >&2
84+
exit 1
85+
;;
86+
esac
6987
7088
build:
71-
name: Build ${{ matrix.engine }}
89+
name: Build ${{ matrix.target }}
7290
needs: matrix
7391
runs-on: macos-26
92+
permissions:
93+
contents: read
7494
strategy:
7595
fail-fast: false
7696
matrix:
77-
engine: ${{ fromJson(needs.matrix.outputs.engines) }}
97+
target: ${{ fromJson(needs.matrix.outputs.targets) }}
7898
outputs:
79-
# Per-engine outputs aren't natively supported with matrices, so each job
99+
# Per-target outputs aren't natively supported with matrices, so each job
80100
# uploads its computed metadata alongside the tarball artifact.
81101
placeholder: noop
82-
env:
83-
IOS_VARIANT: ios-${{ matrix.engine }}
84102
steps:
85103
- name: Harden the runner (Audit all outbound calls)
86104
uses: step-security/harden-runner@95d9a5deda9de15063e7595e9719c11c38c90ae2 # v2.13.2
@@ -118,55 +136,102 @@ jobs:
118136
- name: Bump version
119137
id: bump
120138
shell: bash
139+
env:
140+
RELEASE_TYPE: ${{ inputs.release-type }}
141+
PACKAGE_VERSION: ${{ inputs.version }}
142+
PREID: ${{ inputs.preid }}
143+
TARGET: ${{ matrix.target }}
121144
run: |
122145
set -euo pipefail
123-
release_type='${{ inputs.release-type }}'
124-
preid='${{ inputs.preid }}'
125-
pkg_dir="packages/${IOS_VARIANT}"
146+
release_type="$RELEASE_TYPE"
147+
package_version="$PACKAGE_VERSION"
148+
preid="$PREID"
149+
target="$TARGET"
150+
if [ "$target" = "react-native" ]; then
151+
pkg_dir="packages/react-native"
152+
package_name="@nativescript/react-native"
153+
tarball_basename="nativescript-react-native"
154+
npm_tag_target="react-native"
155+
else
156+
pkg_dir="packages/ios-${target}"
157+
package_name="@nativescript/ios-${target}"
158+
tarball_basename="nativescript-ios-${target}"
159+
npm_tag_target="ios-${target}"
160+
echo "IOS_VARIANT=ios-${target}" >> "$GITHUB_ENV"
161+
fi
126162
127163
pushd "$pkg_dir" >/dev/null
128-
if [ "$release_type" = "prerelease" ]; then
164+
if [ -n "$package_version" ]; then
165+
npm version "$package_version" --no-git-tag-version >/dev/null
166+
elif [ "$release_type" = "prerelease" ]; then
129167
npm version prerelease --preid "$preid" --no-git-tag-version >/dev/null
130168
else
131169
npm version "$release_type" --no-git-tag-version >/dev/null
132170
fi
133171
NPM_VERSION=$(node -e "console.log(require('./package.json').version)")
134172
popd >/dev/null
135173
136-
NPM_TAG=$(NPM_VERSION="$NPM_VERSION" node ./scripts/get-npm-tag.js "$IOS_VARIANT")
174+
NPM_TAG=$(NPM_VERSION="$NPM_VERSION" node ./scripts/get-npm-tag.js "$npm_tag_target")
175+
if [ -n "$package_version" ] && [ "$release_type" = "prerelease" ] && [ "$NPM_TAG" = "latest" ]; then
176+
echo "Exact prerelease publishes must include a prerelease identifier (for example 9.0.0-preview.0)." >&2
177+
exit 1
178+
fi
137179
echo "NPM_VERSION=$NPM_VERSION" >> "$GITHUB_OUTPUT"
138180
echo "NPM_TAG=$NPM_TAG" >> "$GITHUB_OUTPUT"
139-
echo "Resolved $IOS_VARIANT@$NPM_VERSION (tag: $NPM_TAG)"
140-
- name: Build (--${{ matrix.engine }})
141-
run: ./scripts/build_all_ios.sh --${{ matrix.engine }}
181+
echo "PACKAGE_DIR=$pkg_dir" >> "$GITHUB_OUTPUT"
182+
echo "PACKAGE_NAME=$package_name" >> "$GITHUB_OUTPUT"
183+
echo "TARBALL_BASENAME=$tarball_basename" >> "$GITHUB_OUTPUT"
184+
echo "Resolved $package_name@$NPM_VERSION (tag: $NPM_TAG)"
185+
- name: Build iOS engine (--${{ matrix.target }})
186+
if: ${{ matrix.target != 'react-native' }}
187+
env:
188+
TARGET: ${{ matrix.target }}
189+
run: ./scripts/build_all_ios.sh "--${TARGET}"
190+
- name: Build @nativescript/react-native
191+
if: ${{ matrix.target == 'react-native' }}
192+
run: |
193+
./scripts/build_all_react_native.sh
194+
./scripts/build_react_native_turbomodule.sh
142195
- name: Record metadata
143196
shell: bash
197+
env:
198+
TARGET: ${{ matrix.target }}
199+
PACKAGE_DIR: ${{ steps.bump.outputs.PACKAGE_DIR }}
200+
PACKAGE_NAME: ${{ steps.bump.outputs.PACKAGE_NAME }}
201+
NPM_VERSION: ${{ steps.bump.outputs.NPM_VERSION }}
202+
NPM_TAG: ${{ steps.bump.outputs.NPM_TAG }}
203+
TARBALL_BASENAME: ${{ steps.bump.outputs.TARBALL_BASENAME }}
144204
run: |
145-
mkdir -p packages/${IOS_VARIANT}/dist
146-
cat > packages/${IOS_VARIANT}/dist/release-meta.json <<EOF
205+
set -euo pipefail
206+
package_dir="$PACKAGE_DIR"
207+
tarball_file="${TARBALL_BASENAME}-${NPM_VERSION}.tgz"
208+
mkdir -p "$package_dir/dist"
209+
cat > "$package_dir/dist/release-meta.json" <<EOF
147210
{
148-
"engine": "${{ matrix.engine }}",
149-
"variant": "${IOS_VARIANT}",
150-
"package_name": "@nativescript/ios-${{ matrix.engine }}",
151-
"version": "${{ steps.bump.outputs.NPM_VERSION }}",
152-
"tag": "${{ steps.bump.outputs.NPM_TAG }}"
211+
"target": "$TARGET",
212+
"package_dir": "$package_dir",
213+
"package_name": "$PACKAGE_NAME",
214+
"version": "$NPM_VERSION",
215+
"tag": "$NPM_TAG",
216+
"tarball": "$tarball_file"
153217
}
154218
EOF
155219
- name: Upload npm package artifact
156220
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
157221
with:
158-
name: npm-package-${{ matrix.engine }}
222+
name: npm-package-${{ matrix.target }}
159223
path: |
160-
packages/ios-${{ matrix.engine }}/dist/nativescript-ios-${{ matrix.engine }}-${{ steps.bump.outputs.NPM_VERSION }}.tgz
161-
packages/ios-${{ matrix.engine }}/dist/release-meta.json
224+
${{ steps.bump.outputs.PACKAGE_DIR }}/dist/${{ steps.bump.outputs.TARBALL_BASENAME }}-${{ steps.bump.outputs.NPM_VERSION }}.tgz
225+
${{ steps.bump.outputs.PACKAGE_DIR }}/dist/release-meta.json
162226
- name: Upload dSYMs artifact
227+
if: ${{ matrix.target != 'react-native' }}
163228
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
164229
with:
165-
name: NativeScript-dSYMs-${{ matrix.engine }}
230+
name: NativeScript-dSYMs-${{ matrix.target }}
166231
path: dist/dSYMs
167232

168233
publish:
169-
name: Publish ${{ matrix.engine }}
234+
name: Publish ${{ matrix.target }}
170235
needs:
171236
- matrix
172237
- build
@@ -176,7 +241,7 @@ jobs:
176241
strategy:
177242
fail-fast: false
178243
matrix:
179-
engine: ${{ fromJson(needs.matrix.outputs.engines) }}
244+
target: ${{ fromJson(needs.matrix.outputs.targets) }}
180245
permissions:
181246
contents: read
182247
id-token: write
@@ -191,8 +256,8 @@ jobs:
191256
registry-url: "https://registry.npmjs.org"
192257
- uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
193258
with:
194-
name: npm-package-${{ matrix.engine }}
195-
path: packages/ios-${{ matrix.engine }}/dist
259+
name: npm-package-${{ matrix.target }}
260+
path: npm-package/${{ matrix.target }}
196261
- name: Update npm (required for OIDC trusted publishing)
197262
run: |
198263
corepack enable npm
@@ -202,32 +267,38 @@ jobs:
202267
- name: Read release metadata
203268
id: meta
204269
shell: bash
270+
env:
271+
TARGET: ${{ matrix.target }}
205272
run: |
206273
set -euo pipefail
207-
meta="packages/ios-${{ matrix.engine }}/dist/release-meta.json"
274+
meta="npm-package/${TARGET}/release-meta.json"
208275
if [ ! -f "$meta" ]; then
209276
echo "Missing release metadata at $meta" >&2
210277
exit 1
211278
fi
212279
NPM_VERSION=$(node -e "console.log(require('./$meta').version)")
213280
NPM_TAG=$(node -e "console.log(require('./$meta').tag)")
214281
PACKAGE_NAME=$(node -e "console.log(require('./$meta').package_name)")
282+
TARBALL=$(node -e "console.log(require('./$meta').tarball)")
215283
echo "NPM_VERSION=$NPM_VERSION" >> "$GITHUB_OUTPUT"
216284
echo "NPM_TAG=$NPM_TAG" >> "$GITHUB_OUTPUT"
217285
echo "PACKAGE_NAME=$PACKAGE_NAME" >> "$GITHUB_OUTPUT"
286+
echo "TARBALL=$TARBALL" >> "$GITHUB_OUTPUT"
218287
- name: Publish package (OIDC trusted publishing)
219288
if: ${{ vars.USE_NPM_TOKEN != 'true' }}
220289
shell: bash
221290
env:
222291
NPM_VERSION: ${{ steps.meta.outputs.NPM_VERSION }}
223292
NPM_TAG: ${{ steps.meta.outputs.NPM_TAG }}
224293
PACKAGE_NAME: ${{ steps.meta.outputs.PACKAGE_NAME }}
294+
TARBALL: ${{ steps.meta.outputs.TARBALL }}
295+
TARGET: ${{ matrix.target }}
225296
DRY_RUN: ${{ inputs.dry-run }}
226297
NODE_AUTH_TOKEN: ""
227298
run: |
228299
set -euo pipefail
229-
TARBALL="packages/ios-${{ matrix.engine }}/dist/nativescript-ios-${{ matrix.engine }}-${NPM_VERSION}.tgz"
230-
PUBLISH_ARGS=("$TARBALL" --tag "$NPM_TAG" --access public --provenance)
300+
TARBALL_PATH="npm-package/${TARGET}/${TARBALL}"
301+
PUBLISH_ARGS=("$TARBALL_PATH" --tag "$NPM_TAG" --access public --provenance)
231302
if [ "$DRY_RUN" = "true" ]; then
232303
PUBLISH_ARGS+=(--dry-run)
233304
fi
@@ -245,12 +316,14 @@ jobs:
245316
NPM_VERSION: ${{ steps.meta.outputs.NPM_VERSION }}
246317
NPM_TAG: ${{ steps.meta.outputs.NPM_TAG }}
247318
PACKAGE_NAME: ${{ steps.meta.outputs.PACKAGE_NAME }}
319+
TARBALL: ${{ steps.meta.outputs.TARBALL }}
320+
TARGET: ${{ matrix.target }}
248321
DRY_RUN: ${{ inputs.dry-run }}
249322
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
250323
run: |
251324
set -euo pipefail
252-
TARBALL="packages/ios-${{ matrix.engine }}/dist/nativescript-ios-${{ matrix.engine }}-${NPM_VERSION}.tgz"
253-
PUBLISH_ARGS=("$TARBALL" --tag "$NPM_TAG" --access public --provenance)
325+
TARBALL_PATH="npm-package/${TARGET}/${TARBALL}"
326+
PUBLISH_ARGS=("$TARBALL_PATH" --tag "$NPM_TAG" --access public --provenance)
254327
if [ "$DRY_RUN" = "true" ]; then
255328
PUBLISH_ARGS+=(--dry-run)
256329
fi
@@ -265,13 +338,24 @@ jobs:
265338
- build
266339
- publish
267340
runs-on: ubuntu-latest
341+
permissions: {}
268342
steps:
269343
- name: Print summary
344+
env:
345+
PACKAGE_SELECTION: ${{ inputs.engine }}
346+
RELEASE_TYPE: ${{ inputs.release-type }}
347+
PACKAGE_VERSION: ${{ inputs.version }}
348+
PREID: ${{ inputs.preid }}
349+
DRY_RUN: ${{ inputs.dry-run }}
350+
TARGETS: ${{ needs.matrix.outputs.targets }}
351+
BUILD_RESULT: ${{ needs.build.result }}
352+
PUBLISH_RESULT: ${{ needs.publish.result }}
270353
run: |
271-
echo "Engine selection: ${{ inputs.engine }}"
272-
echo "Release type: ${{ inputs.release-type }}"
273-
echo "Preid: ${{ inputs.preid }}"
274-
echo "Dry run: ${{ inputs.dry-run }}"
275-
echo "Engines: ${{ needs.matrix.outputs.engines }}"
276-
echo "Build result: ${{ needs.build.result }}"
277-
echo "Publish result: ${{ needs.publish.result }}"
354+
echo "Package selection: $PACKAGE_SELECTION"
355+
echo "Release type: $RELEASE_TYPE"
356+
echo "Exact version: $PACKAGE_VERSION"
357+
echo "Preid: $PREID"
358+
echo "Dry run: $DRY_RUN"
359+
echo "Targets: $TARGETS"
360+
echo "Build result: $BUILD_RESULT"
361+
echo "Publish result: $PUBLISH_RESULT"

.gitignore

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,11 @@ packages/*/types
6565
SwiftBindgen
6666

6767
# Generated Objective-C/C dispatch wrappers
68-
NativeScript/ffi/GeneratedSignatureDispatch.inc
68+
NativeScript/ffi/napi/GeneratedSignatureDispatch.inc
69+
NativeScript/ffi/napi/GeneratedSignatureDispatch.inc.stamp
70+
71+
# React Native TurboModule package staging
72+
packages/react-native/dist/
73+
packages/react-native/ios/vendor/
74+
packages/react-native/metadata/
75+
packages/react-native/native-api-jsi/

0 commit comments

Comments
 (0)