Skip to content

Commit e8e1778

Browse files
committed
Merge remote-tracking branch 'origin/main' into feat/vite-improvements
2 parents 9df273f + fefa1d5 commit e8e1778

File tree

15 files changed

+623
-95
lines changed

15 files changed

+623
-95
lines changed
Lines changed: 232 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
name: Release Workflow
22

33
on:
4+
push:
5+
branches:
6+
- main
7+
tags:
8+
# Matches the Nx releaseTag pattern in nx.json: "{version}-{projectName}"
9+
- '*-*'
410
workflow_dispatch:
511
inputs:
612
dist-tag:
@@ -14,7 +20,7 @@ on:
1420
type: boolean
1521
default: false
1622
release-group:
17-
description: "Optional Nx release group or project to scope the release (empty = default behavior)"
23+
description: "Optional Nx project pattern to scope the release (empty = default behavior)"
1824
required: false
1925
type: string
2026
default: ""
@@ -26,19 +32,17 @@ concurrency:
2632

2733
permissions:
2834
contents: write # needed to push version commits and tags
29-
pull-requests: write # for changelog PRs/comments if Nx uses them
30-
id-token: write # required for npm provenance (OIDC)
35+
id-token: write # required for npm provenance / trusted publishing (OIDC)
3136

3237
jobs:
3338
release:
3439
name: Version and Publish (gated by environment)
40+
if: ${{ github.actor != 'github-actions[bot]' }}
3541
runs-on: ubuntu-latest
3642
environment:
37-
name: ${{ inputs.dry-run && 'npm-publish-dry-run' || 'npm-publish' }}
43+
name: ${{ (github.event_name == 'workflow_dispatch' && inputs.dry-run) && 'npm-publish-dry-run' || 'npm-publish' }}
3844

3945
env:
40-
# Default dist-tag if not provided via workflow_dispatch input
41-
NPM_DIST_TAG: ${{ inputs['dist-tag'] || 'next' }}
4246
# Optional: provide Nx Cloud token if used in this repo
4347
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
4448

@@ -60,83 +64,258 @@ jobs:
6064
registry-url: 'https://registry.npmjs.org'
6165
cache: 'npm'
6266

67+
- name: Update npm (required for OIDC trusted publishing)
68+
run: |
69+
npm install -g npm@^11.5.1
70+
npm --version
71+
6372
- name: Install dependencies
6473
run: npm ci
6574

6675
- name: Repo setup
6776
run: npm run setup
6877

69-
# Collect a one-time password (OTP) from a reviewer via the environment approval gate.
70-
- id: wait_for_otp
71-
name: Wait for npm OTP (2FA)
72-
if: ${{ !inputs.dry-run }}
73-
uses: step-security/wait-for-secrets@v1
74-
with:
75-
secrets: |
76-
NPM_OTP
77-
timeout-minutes: 30
78+
- name: Resolve release context
79+
id: ctx
80+
shell: bash
81+
run: |
82+
set -euo pipefail
7883
79-
- name: Configure npm auth
80-
if: ${{ !inputs.dry-run }}
81-
env:
82-
NPM_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
84+
if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
85+
dist_tag="${{ inputs['dist-tag'] }}"
86+
scope="${{ inputs['release-group'] }}"
87+
dry_run="${{ inputs['dry-run'] }}"
88+
mode="dispatch"
89+
elif [[ "${GITHUB_REF}" == refs/tags/* ]]; then
90+
dist_tag=""
91+
scope=""
92+
dry_run="false"
93+
mode="tag"
94+
else
95+
dist_tag="next"
96+
scope=""
97+
dry_run="false"
98+
mode="main"
99+
fi
100+
101+
echo "mode=${mode}" >> "$GITHUB_OUTPUT"
102+
echo "dist_tag=${dist_tag}" >> "$GITHUB_OUTPUT"
103+
echo "scope=${scope}" >> "$GITHUB_OUTPUT"
104+
echo "dry_run=${dry_run}" >> "$GITHUB_OUTPUT"
105+
106+
- name: Determine affected release projects (main)
107+
id: affected
108+
if: ${{ steps.ctx.outputs.mode == 'main' }}
109+
shell: bash
83110
run: |
84-
test -n "$NPM_TOKEN" || { echo "NPM_PUBLISH_TOKEN secret is required"; exit 1; }
85-
echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc
111+
set -euo pipefail
112+
113+
base='${{ github.event.before }}'
114+
head='${{ github.sha }}'
115+
116+
# Only consider libs under packages/* and exclude items configured as non-releaseable.
117+
affected_json=$(npx nx show projects --affected --base "$base" --head "$head" --type lib --projects "packages/*" --exclude "ui-mobile-base,types-minimal,winter-tc,types,types-ios,types-android" --json)
118+
affected_list=$(printf '%s' "$affected_json" | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{const a=JSON.parse(s||"[]");process.stdout.write(a.join(" "));});')
119+
affected_count=$(printf '%s' "$affected_json" | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{const a=JSON.parse(s||"[]");process.stdout.write(String(a.length));});')
120+
121+
echo "projects=${affected_list}" >> "$GITHUB_OUTPUT"
122+
echo "count=${affected_count}" >> "$GITHUB_OUTPUT"
123+
124+
- name: Determine tag release project and dist-tag (tags)
125+
id: taginfo
126+
if: ${{ steps.ctx.outputs.mode == 'tag' }}
127+
shell: bash
128+
run: |
129+
set -euo pipefail
130+
131+
tag_name="${GITHUB_REF_NAME}"
132+
133+
# Find the project by matching the tag suffix against known releaseable packages.
134+
projects=$(npx nx show projects --projects "packages/*" --type lib --exclude "ui-mobile-base,types-minimal,winter-tc,types,types-ios,types-android" --sep ' ')
135+
136+
best_match=""
137+
best_len=0
138+
for p in $projects; do
139+
suffix="-${p}"
140+
if [[ "$tag_name" == *"$suffix" ]]; then
141+
if (( ${#p} > best_len )); then
142+
best_match="$p"
143+
best_len=${#p}
144+
fi
145+
fi
146+
done
147+
148+
if [[ -z "$best_match" ]]; then
149+
echo "Could not determine project from tag '$tag_name'. Expected '{version}-{projectName}'." >&2
150+
exit 1
151+
fi
152+
153+
version_part="${tag_name%-$best_match}"
154+
if [[ "$version_part" == *-* ]]; then
155+
dist_tag="next"
156+
else
157+
dist_tag="latest"
158+
fi
159+
160+
echo "project=${best_match}" >> "$GITHUB_OUTPUT"
161+
echo "version=${version_part}" >> "$GITHUB_OUTPUT"
162+
echo "dist_tag=${dist_tag}" >> "$GITHUB_OUTPUT"
86163
87164
- name: Configure git user for automated commits
88165
run: |
89166
git config user.name "github-actions[bot]"
90167
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
91168
92-
# VERSION: updates versions, changelogs, creates git tags following nx.json releaseTag pattern.
93-
- name: nx release version
94-
if: ${{ !inputs.dry-run }}
169+
# VERSION: updates versions and creates git tags following nx.json releaseTag.pattern.
170+
- name: nx release version (main)
171+
if: ${{ steps.ctx.outputs.mode == 'main' && steps.affected.outputs.count != '0' }}
172+
shell: bash
173+
run: |
174+
set -euo pipefail
175+
npx nx release version prerelease \
176+
--preid next \
177+
--projects "${{ steps.affected.outputs.projects }}" \
178+
--git-commit \
179+
--git-tag \
180+
--git-push \
181+
--verbose
182+
183+
- name: nx release version (main, no-op)
184+
if: ${{ steps.ctx.outputs.mode == 'main' && steps.affected.outputs.count == '0' }}
185+
run: echo "No affected release projects on main; skipping version + publish."
186+
187+
- name: nx release version (dispatch)
188+
if: ${{ steps.ctx.outputs.mode == 'dispatch' && !inputs.dry-run }}
189+
shell: bash
190+
run: |
191+
set -euo pipefail
192+
193+
scope="${{ steps.ctx.outputs.scope }}"
194+
if [[ -n "$scope" ]]; then
195+
projects_arg=(--projects "$scope")
196+
else
197+
projects_arg=()
198+
fi
199+
200+
npx nx release version prerelease \
201+
--preid "${{ steps.ctx.outputs.dist_tag }}" \
202+
"${projects_arg[@]}" \
203+
--git-commit \
204+
--git-tag \
205+
--git-push \
206+
--verbose
207+
208+
- name: nx release version (dispatch, dry-run)
209+
if: ${{ steps.ctx.outputs.mode == 'dispatch' && inputs.dry-run }}
210+
shell: bash
211+
run: |
212+
set -euo pipefail
213+
214+
scope="${{ steps.ctx.outputs.scope }}"
215+
if [[ -n "$scope" ]]; then
216+
projects_arg=(--projects "$scope")
217+
else
218+
projects_arg=()
219+
fi
220+
221+
npx nx release version prerelease \
222+
--preid "${{ steps.ctx.outputs.dist_tag }}" \
223+
"${projects_arg[@]}" \
224+
--verbose \
225+
--dry-run
226+
227+
# PUBLISH: OIDC trusted publishing (default). Avoid any lingering token auth.
228+
- name: nx release publish (OIDC)
229+
if: ${{ steps.ctx.outputs.mode != 'tag' && steps.ctx.outputs.dry_run != 'true' && vars.USE_NPM_TOKEN != 'true' && (steps.ctx.outputs.mode != 'main' || steps.affected.outputs.count != '0') }}
230+
shell: bash
95231
env:
96-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
97-
NX_GROUP_ARG: ${{ inputs['release-group'] != '' && format('--group {0}', inputs['release-group']) || '' }}
232+
NPM_CONFIG_PROVENANCE: true
233+
NODE_AUTH_TOKEN: ""
98234
run: |
99-
npx nx release version ${NX_GROUP_ARG} --yes --verbose
235+
set -euo pipefail
236+
unset NODE_AUTH_TOKEN
237+
rm -f ~/.npmrc || true
238+
if [[ -n "${NPM_CONFIG_USERCONFIG:-}" ]]; then
239+
rm -f "$NPM_CONFIG_USERCONFIG" || true
240+
fi
100241
101-
- name: nx release version (dry-run)
102-
if: ${{ inputs.dry-run }}
242+
npx nx release publish \
243+
--tag "${{ steps.ctx.outputs.dist_tag }}" \
244+
--access public \
245+
--verbose
246+
247+
- name: nx release publish (OIDC, dry-run)
248+
if: ${{ steps.ctx.outputs.mode == 'dispatch' && inputs.dry-run && vars.USE_NPM_TOKEN != 'true' }}
249+
shell: bash
103250
env:
104-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
105-
NX_GROUP_ARG: ${{ inputs['release-group'] != '' && format('--group {0}', inputs['release-group']) || '' }}
251+
NPM_CONFIG_PROVENANCE: true
252+
NODE_AUTH_TOKEN: ""
106253
run: |
107-
npx nx release version ${NX_GROUP_ARG} --yes --verbose --dry-run
254+
set -euo pipefail
255+
unset NODE_AUTH_TOKEN
256+
rm -f ~/.npmrc || true
257+
if [[ -n "${NPM_CONFIG_USERCONFIG:-}" ]]; then
258+
rm -f "$NPM_CONFIG_USERCONFIG" || true
259+
fi
260+
261+
npx nx release publish \
262+
--tag "${{ steps.ctx.outputs.dist_tag }}" \
263+
--access public \
264+
--verbose \
265+
--dry-run
108266
109-
# Ensure version commits and tags are pushed if version step created them.
110-
- name: Push version commits and tags
111-
if: ${{ !inputs.dry-run }}
267+
# PUBLISH: token fallback (only when explicitly enabled via repo/environment variable USE_NPM_TOKEN=true).
268+
- name: nx release publish (token)
269+
if: ${{ steps.ctx.outputs.mode != 'tag' && steps.ctx.outputs.dry_run != 'true' && vars.USE_NPM_TOKEN == 'true' && (steps.ctx.outputs.mode != 'main' || steps.affected.outputs.count != '0') }}
270+
env:
271+
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
272+
NPM_CONFIG_PROVENANCE: true
112273
run: |
113-
# Push commits (if any) and tags created by Nx Release
114-
git push --follow-tags || true
274+
npx nx release publish --tag "${{ steps.ctx.outputs.dist_tag }}" --access public --verbose
115275
116-
# PUBLISH: perform npm publish using Nx Release, with 2FA OTP and provenance.
117-
- name: nx release publish
118-
if: ${{ !inputs.dry-run }}
276+
- name: nx release publish (token, dry-run)
277+
if: ${{ steps.ctx.outputs.mode == 'dispatch' && inputs.dry-run && vars.USE_NPM_TOKEN == 'true' }}
119278
env:
120-
NPM_CONFIG_OTP: ${{ steps.wait_for_otp.outputs.NPM_OTP }}
121-
# For npm provenance via OIDC
122279
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
123-
NX_GROUP_ARG: ${{ inputs['release-group'] != '' && format('--group {0}', inputs['release-group']) || '' }}
280+
NPM_CONFIG_PROVENANCE: true
124281
run: |
125-
test -n "$NPM_CONFIG_OTP" || { echo "Missing NPM OTP from environment approval"; exit 1; }
126-
# Use Nx Release to publish all changed packages; tag controls npm dist-tag; provenance enables supply chain attestations
127-
npx nx release publish ${NX_GROUP_ARG} --tag "$NPM_DIST_TAG" --provenance --yes --verbose
282+
npx nx release publish --tag "${{ steps.ctx.outputs.dist_tag }}" --access public --verbose --dry-run
128283
129-
- name: nx release publish (dry-run)
130-
if: ${{ inputs.dry-run }}
284+
# Tag-triggered publishing: publish the single package referenced by the tag.
285+
- name: nx release publish (tag)
286+
if: ${{ steps.ctx.outputs.mode == 'tag' && vars.USE_NPM_TOKEN != 'true' }}
287+
shell: bash
131288
env:
132-
NX_GROUP_ARG: ${{ inputs['release-group'] != '' && format('--group {0}', inputs['release-group']) || '' }}
289+
NPM_CONFIG_PROVENANCE: true
290+
NODE_AUTH_TOKEN: ""
291+
run: |
292+
set -euo pipefail
293+
unset NODE_AUTH_TOKEN
294+
rm -f ~/.npmrc || true
295+
if [[ -n "${NPM_CONFIG_USERCONFIG:-}" ]]; then
296+
rm -f "$NPM_CONFIG_USERCONFIG" || true
297+
fi
298+
299+
npx nx release publish \
300+
--projects "${{ steps.taginfo.outputs.project }}" \
301+
--tag "${{ steps.taginfo.outputs.dist_tag }}" \
302+
--access public \
303+
--verbose
304+
305+
- name: nx release publish (tag, token)
306+
if: ${{ steps.ctx.outputs.mode == 'tag' && vars.USE_NPM_TOKEN == 'true' }}
307+
env:
308+
NODE_AUTH_TOKEN: ${{ secrets.NPM_PUBLISH_TOKEN }}
309+
NPM_CONFIG_PROVENANCE: true
133310
run: |
134-
npx nx release publish ${NX_GROUP_ARG} --tag "$NPM_DIST_TAG" --provenance --yes --verbose --dry-run
311+
npx nx release publish --projects "${{ steps.taginfo.outputs.project }}" --tag "${{ steps.taginfo.outputs.dist_tag }}" --access public --verbose
135312
136313
- name: Summary
137314
if: always()
138315
run: |
139316
echo "Nx Release completed."
140-
echo "- dist-tag: $NPM_DIST_TAG"
141-
echo "- release-group: '${{ inputs['release-group'] }}'"
142-
echo "- dry-run: ${{ inputs['dry-run'] }}"
317+
echo "- mode: ${{ steps.ctx.outputs.mode }}"
318+
echo "- dist-tag: ${{ steps.ctx.outputs.mode == 'tag' && steps.taginfo.outputs.dist_tag || steps.ctx.outputs.dist_tag }}"
319+
echo "- scope: '${{ steps.ctx.outputs.scope }}'"
320+
echo "- dry-run: ${{ steps.ctx.outputs.dry_run }}"
321+
echo "- use-token: ${{ vars.USE_NPM_TOKEN == 'true' }}"

apps/toolbox/src/split-view/split-view-secondary.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page">
2-
<ActionBar title="Secondary View" class="action-bar">
3-
</ActionBar>
42
<!-- Secondary column (detail) -->
53
<StackLayout class="p-16">
64
<Label text="Secondary" marginBottom="12" fontSize="22" fontWeight="bold" />

apps/toolbox/src/split-view/split-view-supplement.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page">
2-
<ActionBar title="Supplementary View" class="action-bar">
3-
</ActionBar>
42
<!-- Supplementary column (detail) -->
53
<StackLayout class="p-16">
64
<Label text="Supplementary" marginBottom="12" fontSize="22" fontWeight="bold" />

packages/core/CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
## 9.0.9 (2025-12-21)
2+
3+
### 🚀 Features
4+
5+
- **ios:** statusBarStyle improvements for other edge cases ([15ae1514c](https://github.com/NativeScript/NativeScript/commit/15ae1514c))
6+
- **ios:** SplitView layout improvements ([edfa9b07c](https://github.com/NativeScript/NativeScript/commit/edfa9b07c))
7+
- **ios:** SplitView lifecycle improvements ([#11011](https://github.com/NativeScript/NativeScript/pull/11011))
8+
9+
### ❤️ Thank You
10+
11+
- Nathan Walker
12+
113
## 9.0.8 (2025-12-12)
214

315
### 🚀 Features

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nativescript/core",
3-
"version": "9.0.8",
3+
"version": "9.0.9",
44
"description": "A JavaScript library providing an easy to use api for interacting with iOS and Android platform APIs.",
55
"type": "module",
66
"main": "index",

0 commit comments

Comments
 (0)