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
1113on :
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
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)"
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
4451 default : true
4552
4653concurrency :
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
5360
5461jobs :
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"
0 commit comments