chore: Release 5.4.4#1945
Conversation
There was a problem hiding this comment.
LGTM, straightforward version bump for release 5.4.4.
Extended reasoning...
Overview
This PR is a single-line version bump in package.json from 5.4.3 to 5.4.4, accompanying the release of v5.4.4. The release bundles previously-merged PRs (#1942 E2E test workflow, #1944 react-native peer dep bump).
Security risks
None. This is purely a metadata version field change with no executable code, dependencies, or configuration semantics affected.
Level of scrutiny
Minimal scrutiny is appropriate. This is a mechanical release-management change that follows the established pattern used for prior releases. The diff is exactly one line.
Other factors
No bugs were flagged by the bug hunting system. The actual feature/fix changes were already reviewed and merged in their respective PRs (#1942, #1944). No outstanding reviewer comments to address.
There was a problem hiding this comment.
Additional findings (outside current diff — PR may have been updated during review):
-
🟡
examples/setup.sh:38-51— examples/setup.sh was migrated from bun→vp commands at lines 41/48/66/67, but the surrounding comments at lines 43, 53, 60 and the user-visible echo at line 65 still name 'bun' as the active tool. The echo prints 'Registering tarball with bun (refreshes bun.lock integrity hash)...' on every setup run — actively misleading anyone debugging a CI log who greps for 'bun' expecting to find a bun cache to inspect. Nit, doc-only — vp wraps bun under the hood (packageManager: bun@1.3.13) so functional behavior is unchanged, but the literal command names cited in the comments (bun pm pack,bun add,bun remove) no longer exist as call sites in the file.Extended reasoning...
What is stale
Verified directly from the diff and the current file. The PR converts four commands from bun to vp:
- Line 41:
vp run build(wasbun run build) - Line 48:
vp pm pack(wasbun pm pack) - Line 66:
vp remove react-native-onesignal(wasbun remove ...) - Line 67:
vp add file:../../react-native-onesignal.tgz(wasbun add ...)
…but the surrounding documentation block still names bun by its CLI:
- Line 43:
#bun pm packhonors package.json's "files" field …— describes the command on line 48, which is nowvp pm pack. - Line 53:
# Always go through bun add so bun.lock's integrity hash …— describes line 67, which is nowvp add. - Line 57:
# subsequentbun installthat re-resolved this entry … - Line 60:
#bun removefirst because bun verifies the existing integrity hash— describes line 66, which is nowvp remove. - Line 65:
echo "Registering tarball with bun (refreshes bun.lock integrity hash)..."— printed to stdout on every run.
The refutation is partially right
A verifier correctly noted that vp wraps the underlying package manager (per AGENTS.md), and
examples/demo/package.jsondeclarespackageManager: bun@1.3.13. So the integrity-hash mechanics andbun.lockfilename references in the comments remain technically accurate — bun is still the package manager doing the work, just behind the vp wrapper. That's why this is a nit, not a real bug.Why it's still worth flagging
-
The echo is genuinely misleading in a CI context. A future operator reading
Registering tarball with bun (refreshes bun.lock integrity hash)…in a workflow log will grep the script forbunto debug a stale-tarball or cache issue, and find only this echo — no actualbuninvocation. The command they need to inspect isvp, notbun. -
The literal command names cited in the comments don't appear at the call site. A reader applying the rule 'comments should match the code they document' would update line 43 to mention
vp pm pack(or both names), line 53 to mentionvp add, and line 60 to mentionvp remove. -
Header comment at line 3 (
Invoked from a demo dir … viabun run setup``) is not stale —examples/demo/package.jsonlines 7-8 still use `bun run setup` for `preandroid`/`preios`, so that reference is correct.
Step-by-step proof
- Open
examples/setup.shat this PR's HEAD. - Read line 65:
echo "Registering tarball with bun (refreshes bun.lock integrity hash)...". This string is unconditionally written to stdout when setup runs. - Read lines 66-67:
vp remove react-native-onesignal/vp add file:../../react-native-onesignal.tgz. The actual commands invoked arevp, notbun. - Run
grep -n bun examples/setup.shmentally: matches at lines 3, 43, 53, 56, 57, 60, 62, 65 — all comments or the echo, no realbuninvocations remain in the script body.
Suggested fix
Either (a) rephrase to name the wrapper and the underlying tool together, e.g.
echo "Registering tarball with vp (which delegates to bun and refreshes bun.lock's integrity hash)...", or (b) just s/bun/vp/g in the comments and echo, since vp is now the only literal command in the file. Option (a) preserves the explanatory value of mentioning bun.lock; option (b) is the smaller diff.Severity
nit — functional behavior is unchanged, the bun.lock filename references remain accurate, and the fix is purely cosmetic. Flagging because the misleading echo will appear in every CI log going forward and the comments were touched-by-proximity in this exact diff hunk.
- Line 41:
| ( | ||
| cd examples/demo | ||
| vp run setup | ||
| cd ios | ||
| pod install | ||
| ) | ||
| echo "✓ Refreshed examples/demo/ios/Podfile.lock" | ||
|
|
||
| # Only commit if there are changes | ||
| git add -A |
There was a problem hiding this comment.
🟡 Forward-looking nit: the new "Refresh demo Podfile.lock" step at create-release-pr.yml:189-207 runs pod install (no --repo-update, no preceding wait gate) seconds after the prior "Update iOS SDK version" step bumped the OneSignalXCFramework pin via sed. If a future iOS SDK release is pod trunk push-ed minutes before this workflow runs and the CocoaPods CDN has not yet indexed it, pod install fails with "Unable to find a specification for OneSignalXCFramework (= X.Y.Z)" — but only after the prior Update Android SDK version / Update iOS SDK version / Update sdk version steps have already committed and pushed package.json + podspec + wrapper-version literals to rel/X.Y.Z, leaving the release branch in a half-finished state requiring manual recovery. No immediate impact for 5.4.4 (5.5.1 has long since propagated through trunk) — but the new step is the symmetric iOS counterpart of the wait-for-maven-artifact gate this PR added on the Android side, and it would benefit from a wait-for-pod-trunk step (or equivalent retry loop) for the same reason. Note --repo-update is largely a no-op for CDN-backed trunk on CocoaPods 1.7+, so a wait/retry is the cleaner fix.
Extended reasoning...
What is wrong
The new "Refresh demo Podfile.lock" step at .github/workflows/create-release-pr.yml:189-207 runs pod install immediately after the preceding "Update iOS SDK version" step (lines 130-156) sed-bumps the OneSignalXCFramework pin in react-native-onesignal.podspec. There is no --repo-update, no pod repo update, and no wait-for-pod-trunk gate between the bump and the install. The only validation upstream is the curl -sf GitHub-release-tag check at line 136 — but that endpoint has no opinion on whether the pod has propagated through the CocoaPods CDN.
This is the same class of race the verifier flagged for e2e.yml:60 (the asymmetric Android Maven Central wait vs. no iOS wait), but at a different file (this PR's newly introduced step) and a different (tighter) race window. The previous comment was scoped to e2e.yml; the fix for that file does not automatically cover this one.
Code path that triggers it
- Operator triggers
create-release-pr.ymlwithios_version: X.Y.Zshortly after the iOS SDK teampod trunk push-edOneSignalXCFramework X.Y.Z. - "Update Android SDK version" step (if applicable) commits and pushes the Android bump to
rel/X.Y.Z. - "Update iOS SDK version" step validates the GitHub release tag exists (succeeds — the tag was created at
pod trunk pushtime), seds the podspec tos.dependency 'OneSignalXCFramework', 'X.Y.Z', commits and pushes. - "Update sdk version" step bumps
package.json, the wrapper-version literals inRNOneSignal.javaandRCTOneSignal.mm, commits and pushes. - "Refresh demo Podfile.lock" step runs
vp run setupthenpod installagainst the freshly-sed-ed podspec. - CocoaPods asks the CDN for
OneSignalXCFramework/X.Y.Z.podspec.json. If CDN propagation has not completed (the spec was just registered with trunk), CocoaPods errors withUnable to find a specification for OneSignalXCFramework (= X.Y.Z)andpod installexits non-zero. Underset -ethe run-block aborts. git add -A; git diff --staged --quiet && exit 0; git commit ...never runs, so this step exits without committing the lock — but the prior three steps have already pushed package.json + podspec + wrapper-version commits torel/X.Y.Z. The release branch is now in a half-finished state.
Why nothing prevents it
- The GitHub-tag check at line 136 (
curl -sf .../releases/tags/${VERSION}) validates only that the GitHub release exists — orthogonal to CDN indexing. pod installwith no flags uses the CocoaPods 1.7+ CDN by default (seeexamples/demo/ios/Podfiledeclares no source).--repo-updateis largely a no-op for CDN-backed trunk because there is no local spec repo to refresh — this is why a retry/wait is the substantive fix.- The "Refresh demo Podfile.lock" step is new in this PR; no equivalent backstop existed before.
- The Android side already has a symmetric protection: this PR adds
wait-for-maven-artifactine2e.yml. The iOS side now has the same kind of race exposure increate-release-pr.ymlwith no analogous gate.
Why this is genuinely a nit (not a blocker) and not a duplicate
- Duplicate refutation: The synthesis agent has already considered the prior
e2e.yml:60comment — the substance there was about a different file (e2e.yml, onpush: rel/**) and a differentpod installcallsite (insidesetup-demo). This bug is about a new step increate-release-pr.ymlintroduced by this PR. The fix is localized to each callsite; addressing the e2e.yml comment does not automatically harden this step. - Proposed fix being partially wrong: The refutation rightly notes that
--repo-updateis mostly a no-op for CDN-backed trunk. That observation is correct and informs the recommended fix: await-for-pod-trunkstep (mirroring the newwait-for-maven-artifactstep) or apod search/retry loop is the substantive remedy, not--repo-updateper se. - Operationally narrow: CocoaPods CDN propagation is typically sub-minute, and OneSignal iOS SDK 5.5.1 has long since propagated, so this PR's 5.4.4 cut will not flake. The race exists for future iOS bumps where the wrapper PR is triggered close to the iOS SDK's
pod trunk push. - Recoverable: A failure halts before
create-prruns. The operator can re-run; a second attempt succeeds once CDN propagation completes. Not release-blocking — hence nit.
How to fix
Add a wait-for-pod-trunk step before pod install, mirroring the wait-for-maven-artifact step this PR added on the Android side, e.g.:
- name: Resolve OneSignal iOS SDK version
id: ios-sdk-version
run: |
VERSION=$(grep "OneSignalXCFramework" react-native-onesignal.podspec | sed -E "s/.*'([^']+)'.*/\1/")
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
- name: Wait for OneSignalXCFramework on CocoaPods trunk
uses: OneSignal/sdk-shared/.github/actions/wait-for-pod-trunk@main
with:
pod: OneSignalXCFramework
version: ${{ steps.ios-sdk-version.outputs.version }}If no wait-for-pod-trunk action exists in OneSignal/sdk-shared, an inline retry loop works equally well:
for i in 1 2 3 4 5; do
if pod install; then break; fi
echo "pod install failed (attempt $i); waiting 30s for CDN propagation"
sleep 30
doneStep-by-step proof
Suppose the iOS SDK team pod trunk push-es OneSignalXCFramework 5.6.0 at T+0. The wrapper releaser triggers create-release-pr.yml with ios_version: 5.6.0 at T+45s.
T+45s— "Update iOS SDK version" step runs.curl -sf .../releases/tags/5.6.0returns 200 (GitHub tag was created at trunk push time).sedrewrites the podspec to'5.6.0'.git commit -m "Update iOS SDK to 5.6.0" && git push—rel/X.Y.Znow has the podspec bump committed.T+50s— "Update sdk version" step bumpspackage.jsonto the new RN version, seds the wrapper-version literals inRNOneSignal.javaandRCTOneSignal.mm, commits and pushes.T+55s— "Refresh demo Podfile.lock" step runsvp run setup(re-packs the SDK tarball with the new wrapper version) thencd ios; pod install.- CocoaPods queries
https://cdn.cocoapods.org/all_pods_versions_*.txtandhttps://cdn.cocoapods.org/Specs/.../OneSignalXCFramework/5.6.0/OneSignalXCFramework.podspec.json. The version-shard file has not finished propagating. CocoaPods reportsUnable to find a specification forOneSignalXCFramework (= 5.6.0)``. Exit non-zero. - Under
set -e, the run-block aborts.git diff --staged --quiet && exit 0; git commit ... && git pushnever executes, so the Podfile.lock refresh is not committed. But the prior three steps have already pushed package.json + podspec + wrapper-version literal commits torel/X.Y.Z. - The release branch is now half-finished: podspec at 5.6.0, wrapper version bumped, but
examples/demo/ios/Podfile.lockstill pinned to the previous OneSignalXCFramework version.create-pr(the next job) does not run becauseupdate_versionfailed. Operator must either re-trigger the workflow (will succeed after CDN propagation completes) or manually push the missing lock commit.
Severity
nit — narrow, forward-looking race window. CocoaPods trunk indexing is typically fast and 5.5.1 has long since propagated, so no immediate impact for this PR. But the new step is the symmetric iOS counterpart of the wait-for-maven-artifact Android gate this PR introduces, and the same defensive treatment makes the asymmetry intentional rather than accidental.
🔬 also observed by previous_4
|
|
||
| # Update Android SDK version in build.gradle (handles both api '...' and api('...') syntax) | ||
| sed -i '' -E "s/(com\.onesignal:OneSignal:)[0-9.]+/\1$VERSION/" android/build.gradle | ||
| sed -i '' -E "s/(com\.onesignal:OneSignal:)[^\"']+/\1$VERSION/" android/build.gradle | ||
| echo "✓ Updated android/build.gradle with Android SDK ${VERSION}" | ||
|
|
||
| # Only commit if there are changes |
There was a problem hiding this comment.
🟡 Forward-looking nit: this PR added grep -q post-substitution verification to the wrapper-version sed in Update sdk version (lines 170-173, 178-181), but the parallel Update Android SDK version (line 121, which this PR just touched to broaden [0-9.]+ → [^"']+) and Update iOS SDK version (line 146) seds still rely on the unverified sed → echo "✓ Updated" → git diff --staged --quiet && exit 0 pattern. BSD sed -i exits 0 on zero matches, so a future reformat of android/build.gradle (e.g. catalog/multi-line) or the podspec (e.g. s.dependency('OneSignalXCFramework', "5.5.1")) would silently no-op while the log lies — and since neither step has a prior mutation, the staged diff guard fires exit 0 cleanly, leaving the release with a bumped package.json but a stale native pin. Current files match losslessly so no immediate impact; mirroring the existing wrapper-version grep -qF pattern to both earlier seds (two lines per step) closes the same class of bug symmetrically.
Extended reasoning...
What is asymmetric
This PR closed a silent-sed-miss gap in the wrapper-version block at .github/workflows/create-release-pr.yml:168-181 by adding post-substitution grep -q checks:
sed -i '' -E "s/(OneSignalWrapper\.setSdkVersion\(\")[0-9]+(\"\))/\1${PADDED_VERSION}\2/" "$ANDROID_FILE"
if ! grep -q "OneSignalWrapper.setSdkVersion(\"${PADDED_VERSION}\")" "$ANDROID_FILE"; then
echo "::error::Failed to update wrapper version in ${ANDROID_FILE} to ${PADDED_VERSION}"
exit 1
fiBut the structurally-identical seds in the two earlier steps in the same job — both of which this PR actively touched (broadened the regexes from [0-9.]+ to [^"']+ / [^']+) — got no analogous verification:
- Line 121 (
Update Android SDK version):sed -i '' -E "s/(com\.onesignal:OneSignal:)[^\"']+/\1$VERSION/" android/build.gradlefollowed only by an unconditionalecho "✓ Updated …"andgit add -A; git diff --staged --quiet && exit 0. - Line 146 (
Update iOS SDK version):sed -i '' "s/s\.dependency 'OneSignalXCFramework', '[^']*'/.../" react-native-onesignal.podspecwith the same unverified pattern.
Why the existing guard does not save these
BSD sed -i '' (job runs on macos-latest) exits 0 even when the pattern matches zero lines. The echo "✓ Updated …" is unconditional so the log lies. And critically, unlike the wrapper-version step, neither of these earlier steps has a prior mutation like npm pkg set version. So when the sed misses, the staged diff is genuinely empty and git diff --staged --quiet && exit 0 exits the step cleanly with success status — no commit, no error, no signal that anything went wrong.
Failure mode (Android — most exposed)
- Future contributor reformats
android/build.gradle— e.g. moves the dep into alibs.versions.tomlcatalog and references it asapi libs.onesignal, or splits the literal across multiple lines. - Operator triggers the workflow with
android_version: 5.9.0. The newcurl -sfvalidates that release exists. Good. sedruns against the reformattedbuild.gradle. Thecom.onesignal:OneSignal:[^"']+pattern matches zero lines. BSDsed -iexits 0.echo "✓ Updated android/build.gradle with Android SDK 5.9.0"— workflow log claims success.git add -A; git diff --staged --quiet && exit 0— staged diff empty, step exits 0.- Workflow proceeds.
Update sdk versionbumpspackage.json+ wrapper literal.Refresh demo Podfile.lockregenerates the lock against the still-stale gradle line. Final commits pushed. rel/5.9.0ships withpackage.jsonat 5.9.0 butandroid/build.gradlestill pinning the prior Android SDK — exactly the failure mode the wrapper-version verification was added to prevent.
The iOS branch is structurally more brittle: the regex requires exact s.dependency + space + single-quoted args + comma-space syntax. A future podspec refactor to parens (s.dependency('OneSignalXCFramework', '5.5.1')) or double-quoted version produces zero matches with the same silent-exit-0 outcome. The downstream Refresh demo Podfile.lock step does not catch it either — pod install resolves against the stale podspec and produces a self-consistent lock at the old version.
Why nothing else catches it
curl -sfvalidates the GitHub release tag exists; it has no opinion on whether sed matched.- The downstream
pod installresolves whatever the podspec says, so a missed iOS sed produces a self-consistent (but stale) lock. - e2e on
rel/**may pass if the previously-pinned native SDK is still live on Maven Central / CocoaPods trunk.
Step-by-step proof — Android branch
- Reformat the Android dep declaration (any of: catalog reference, multi-line interpolation, removed quotes around version) so the literal
com.onesignal:OneSignal:5.8.0no longer appears on a single line inandroid/build.gradle. - Workflow runs with
android_version: 5.9.0. sed -i '' -E "s/(com\.onesignal:OneSignal:)[^\"']+/\15.9.0/" android/build.gradle— pattern matches zero lines. BSD sed exits 0.echo "✓ Updated android/build.gradle with Android SDK 5.9.0"— log says success.git add -A— nothing new to stage.git diff --staged --quiet && exit 0— empty diff, exits 0.- Step status: success. No human-visible signal of the miss.
- Subsequent steps run normally and commit/push the bumped
package.jsonand wrapper literal.
How to fix
Mirror the wrapper-version pattern (~4 lines per step):
sed -i '' -E "s/(com\.onesignal:OneSignal:)[^\"']+/\1$VERSION/" android/build.gradle
if ! grep -qF "com.onesignal:OneSignal:${VERSION}" android/build.gradle; then
echo "::error::Failed to update android/build.gradle to OneSignal SDK ${VERSION}"
exit 1
fi
echo "✓ Updated android/build.gradle with Android SDK ${VERSION}"and analogously for the iOS podspec sed. grep -qF (fixed-string) is sufficient since we are matching the exact value just substituted in.
Severity
nit — current pins (Android 5.8.0, iOS 5.5.1) match the regexes losslessly so there is no immediate impact. Worth flagging because (a) this PR has been twice-revised to harden this very script (curl -sf, wrapper-version grep -q), and (b) the parallel gap in the two earlier seds leaves the same class of silent-drift bug open. Mirroring the new pattern symmetrically while it is fresh costs 4 lines per step.
|
|
||
| # Optional: Android Notification Channel ID for the WITH SOUND test notification. | ||
| # Create one in your OneSignal dashboard under Settings > Android Notification Categories. | ||
| ONESIGNAL_ANDROID_CHANNEL_ID= |
There was a problem hiding this comment.
🟣 Pre-existing nit (lines 1–2 aren't in the diff, but this PR adds an adjacent line that pairs cleanly with the correct pattern, so it's a natural fold-in). .env.example:1 documents "Default App ID (used if ONESIGNAL_APP_ID is empty): 77e32082-…" but .env.example:2 ships ONESIGNAL_APP_ID=your-onesignal-app-id (non-empty), and the fallback at useOneSignal.ts:32 is ONESIGNAL_APP_ID?.trim() || DEFAULT_APP_ID — only triggers on empty/whitespace, not on the literal placeholder. So a developer who runs cp .env.example .env verbatim ends up calling OneSignal.initialize("your-onesignal-app-id") (which OneSignal rejects) instead of getting the documented default. Fix: ship ONESIGNAL_APP_ID= (matching the new ONESIGNAL_ANDROID_CHANNEL_ID= on line 8) so the fallback actually kicks in, or drop the "used if empty" comment. CI is unaffected (setup-demo writes a real APP_ID); only local-dev onboarding bites.
Extended reasoning...
What is wrong
Three pieces of code disagree about whether ONESIGNAL_APP_ID is a "must-be-replaced placeholder" or a "may-be-empty fallback":
examples/demo/.env.example:1—# Default App ID (used if ONESIGNAL_APP_ID is empty): 77e32082-ea27-42e3-a898-c72e141824ef. Comment says the fallback kicks in when the value is empty.examples/demo/.env.example:2—ONESIGNAL_APP_ID=your-onesignal-app-id. Non-empty placeholder.examples/demo/src/hooks/useOneSignal.ts:32—return ONESIGNAL_APP_ID?.trim() || DEFAULT_APP_ID;. The||only short-circuits on empty/whitespace, not on the literal placeholder string.
The result: a developer who follows the documented onboarding flow (cp .env.example .env and run) does not get the default UUID — they get the literal string your-onesignal-app-id passed straight into OneSignal.initialize(), which the API rejects.
Addressing the refutation
The refuting verifier argues the file deliberately mixes two conventions: placeholder-must-replace for required values (ONESIGNAL_APP_ID, ONESIGNAL_API_KEY) and empty-with-default for optional values (ONESIGNAL_ANDROID_CHANNEL_ID). That framing is reasonable on its face, but it does not fit ONESIGNAL_APP_ID specifically, because line 1 of this very file explicitly documents that the value has an empty-triggered fallback (used if ONESIGNAL_APP_ID is empty: 77e32082-…). If ONESIGNAL_APP_ID were truly required, that comment would be wrong; if the comment is right, line 2 should be empty. They cannot both be correct, which is the contradiction.
Why this PR is the natural place to fix it
Lines 1–2 are pre-existing — not in the diff. But this PR adds ONESIGNAL_ANDROID_CHANNEL_ID= on line 8, which is the correct defined-but-empty pattern that pairs cleanly with ONESIGNAL_ANDROID_CHANNEL_ID?.trim() || ... at OneSignalApiService.ts:53 (also added by this PR). So the same pattern is now used both ways within the same 8-line file: line 8 does it right, line 2 does not. That makes the line 2 inconsistency more visible than it was before this PR, and a one-character fold-in (ONESIGNAL_APP_ID=) aligns the two.
Impact
- CI: unaffected.
.github/actions/setup-demo/action.ymlwrites a non-emptyONESIGNAL_APP_IDfrom a workflow secret, so e2e never reads.env.exampleverbatim. - End users: unaffected. They install via npm;
examples/demois internal. - Local-dev onboarding: the documented
cp .env.example .envflow does not produce the documented default. New contributors hitOneSignal.initializerejection and have to debug why "the default is supposed to kick in".
How to fix
Either:
-# Default App ID (used if ONESIGNAL_APP_ID is empty): 77e32082-ea27-42e3-a898-c72e141824ef
-ONESIGNAL_APP_ID=your-onesignal-app-id
+# Default App ID (used if ONESIGNAL_APP_ID is empty): 77e32082-ea27-42e3-a898-c72e141824ef
+ONESIGNAL_APP_ID=(matches line 8 ONESIGNAL_ANDROID_CHANNEL_ID= pattern), or drop the "used if empty" comment entirely and tell the developer to replace the placeholder.
Step-by-step proof
- Developer clones the repo and runs
cp examples/demo/.env.example examples/demo/.env(the documented onboarding step). .envnow containsONESIGNAL_APP_ID=your-onesignal-app-id.babel.config.js(react-native-dotenv) inlinesONESIGNAL_APP_IDas the literal string"your-onesignal-app-id"at every callsite.useOneSignal.ts:32evaluates"your-onesignal-app-id"?.trim() || DEFAULT_APP_ID..trim()returns"your-onesignal-app-id"(truthy), so||short-circuits andDEFAULT_APP_IDis not used.OneSignal.initialize("your-onesignal-app-id")runs. OneSignals API rejects the malformed (non-UUID) app ID.- Developer is confused because line 1 of
.env.exampletold them the documented default would be used "if ONESIGNAL_APP_ID is empty" — and from their point of view, they did not set it.
Severity
pre_existing — line 2 is unchanged by this PR, but the PR adds an adjacent line that uses the correct empty-fallback pattern, so this is the natural moment to align the older line. Trivial fix (one character) and only affects local-dev onboarding.
Channels: Current
🐛 Bug Fixes
🛠️ Native Dependency Updates