Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
533e79a
feat(types): add v6 cross-platform façade (Presentation builder, outc…
kherembourg May 28, 2026
772cc99
feat(android): wire React Native bridge to v6 SDK (builder, outcome, …
kherembourg May 28, 2026
8d0d823
chore(ios): scaffold v6 bridge category header + ignore caches
kherembourg May 28, 2026
8e2c918
feat(ios): implement v6 bridge category on PurchaselyRN
kherembourg May 28, 2026
4f48b1f
feat(ios): register v6 events on PurchaselyRN
kherembourg May 28, 2026
bddd097
chore(example): demonstrate v6 contract in example app
kherembourg May 28, 2026
ffd25e5
docs: add v6 migration guide, changelog and bump to 6.0.0-beta.0
kherembourg May 28, 2026
318bf18
test(v6): add integration tests for façade ↔ native bridge contract
kherembourg May 28, 2026
2767d92
fix(v6): address Greptile review findings
claude May 28, 2026
81f15ac
fix(v6): bound Android interceptor wait; document default() resolution
kherembourg May 29, 2026
8349e1a
feat(v6)!: remove the v5 paywall API — v6 is the only paywall surface
kherembourg May 29, 2026
06cc3a4
refactor(android): merge PurchaselyV6Bridge into PurchaselyModule — s…
kherembourg Jun 1, 2026
6188557
refactor: single iOS bridge + drop the "v6" naming everywhere
kherembourg Jun 1, 2026
8d2092e
fix(v6): align native bridge migration
kherembourg Jun 1, 2026
36a1b12
fix(v6): wire synchronize callback, pin natives to 6.0.0-rc.1, bump v…
kherembourg Jun 16, 2026
0f6daa1
chore(deps): migrate React Native to 0.86.0 (#253)
kherembourg Jun 16, 2026
252f4b0
fix(v6): complete iOS native bridge migration to rc.1; drop presentSu…
kherembourg Jun 16, 2026
d26a2c9
docs(v6): record iOS bridge completion and presentSubscriptions removal
kherembourg Jun 16, 2026
af900f4
fix(v6): default unknown runningMode to observer, not full
kherembourg Jun 16, 2026
242a0f9
fix(example): drop the removed presentSubscriptions button
kherembourg Jun 16, 2026
89422af
chore(deps): pin Android native SDK to 6.0.0-beta.12
kherembourg Jun 23, 2026
39941c4
feat(v6)!: add setDefaultPresentationDismissHandler global handler
kherembourg Jun 23, 2026
6627c6a
test(v6): cover the default dismiss handler
kherembourg Jun 23, 2026
105ad2d
docs(v6): document setDefaultPresentationDismissHandler
kherembourg Jun 23, 2026
cc80941
feat(v6)!: align RN public API with native v6 (outcome/deeplink/close…
kherembourg Jun 24, 2026
b9e74af
test(e2e): add Android E2E functional suite T1–T10
kherembourg Jun 24, 2026
c7402e2
ci(e2e): add Android E2E nightly workflow with manual trigger
kherembourg Jun 24, 2026
ce03f52
test(ci): temporary push trigger to validate E2E workflow on feature …
kherembourg Jun 24, 2026
9f33e05
chore(android): bump all Purchasely native deps to 6.0.0-rc.2
kherembourg Jun 24, 2026
263bde7
fix(ci): switch E2E emulator to ubuntu-latest + KVM + x86_64
kherembourg Jun 24, 2026
12e16c9
test(e2e): drop T6, simplify T9 purchase interceptor
kherembourg Jun 25, 2026
e7aa983
test(e2e): renumber T7-T10 → T6-T9, add E2E_TEST_INDEX.md
kherembourg Jun 25, 2026
2ca7287
test(e2e): expand suite T1-T13 with property assertions + iOS skeleton
kherembourg Jun 25, 2026
58e8189
ci(e2e): switch to Mac mini self-hosted runner + fix JS bundle + fix …
kherembourg Jun 25, 2026
11bc1b0
ci(e2e): use macos-14 runner (Apple Silicon, ARM64, no KVM)
kherembourg Jun 25, 2026
48c3d88
ci(e2e): add android-actions/setup-android to fix sdkmanager PATH on …
kherembourg Jun 26, 2026
9550cbb
ci(e2e): switch back to ubuntu-latest + KVM + x86_64 for Android E2E
kherembourg Jun 26, 2026
a8acdc9
ci(e2e): add android-actions/setup-android on ubuntu (sdkmanager not …
kherembourg Jun 26, 2026
19cceb7
ci(e2e): use reactivecircuit/android-emulator-runner to fix AVD setup
kherembourg Jun 26, 2026
bbad10e
ci(e2e): fix action name ReactiveCircus/android-emulator-runner (typo)
kherembourg Jun 26, 2026
8026275
ci(e2e): switch to release APK + verify bundle + better logcat dump
kherembourg Jun 26, 2026
6c48cd0
chore(ios): bump native iOS SDK dependency to 6.0.0-rc.2
kherembourg Jun 26, 2026
476dde3
test(e2e): add iOS E2E suite (T1-T13) + CI workflow
kherembourg Jun 26, 2026
80cbde9
ci(e2e-ios): use macos-15 + select Xcode 16 (RN 0.79 needs >=16.1)
kherembourg Jun 26, 2026
51122a7
chore: reconcile yarn.lock after rebase onto main
kherembourg Jun 26, 2026
9a23d07
test(e2e): pin exact closeReason + assert purchaseResult in T7/T9
kherembourg Jun 26, 2026
559be55
fix(ios): add 30s interceptor timeout fallback to notHandled
El-Fitz Jun 30, 2026
cc67694
chore: remove leftover turbo config from sub-packages
kherembourg Jun 30, 2026
1c17865
refactor(v6): align public API with Flutter (PLY prefix) + parity fixes
kherembourg Jun 30, 2026
ce16fa9
feat(v6): full Flutter-v6 parity (E2E T14-T20, CI, native normalization)
kherembourg Jun 30, 2026
81e75fd
fix(android): type array setters explicitly so suspend bridge picks c…
kherembourg Jun 30, 2026
d30ea91
fix(android): force float overload in setUserAttributeWithNumber
kherembourg Jun 30, 2026
c27a4da
test(js): remove dead v5 native mocks, add removeDefaultPresentationD…
kherembourg Jul 1, 2026
989c167
fix(android): convert array user attributes to WritableArray on read
kherembourg Jul 1, 2026
aa5b112
docs(android): correct setUserAttributeWithNumber comment
kherembourg Jul 1, 2026
218d63a
fix(android): raise minSdk to 23 to match the native SDK requirement
kherembourg Jul 2, 2026
d5adf68
docs: align CLAUDE.md/VERSIONS.md/MIGRATION-v6.md with the real v6 rc…
kherembourg Jul 2, 2026
03a77f0
fix(ios): forward displayCloseButton/displayBackButton to the native …
kherembourg Jul 2, 2026
1a5a554
feat(js)!: align the presentation API with the Flutter v6 surface
kherembourg Jul 2, 2026
0176ec8
feat(view): embed a preloaded request via <PLYPresentationView reques…
kherembourg Jul 2, 2026
5b66ec9
fix(js): route unhandled display() dismissals to the default dismiss …
kherembourg Jul 3, 2026
8322a43
test(e2e): port Flutter parity scenarios as T21-T27
kherembourg Jul 3, 2026
4f37916
ci(e2e): run E2E when the SDK bridge source changes
kherembourg Jul 3, 2026
52bb232
fix(ios): unfreeze embedded view mount and emit PRESENTATION_VIEWED
kherembourg Jul 3, 2026
7bbe528
chore(example): sync iOS project with pod install (rc.2 lockfile)
kherembourg Jul 3, 2026
d30fa90
fix(release): build publishable workspaces once
kherembourg Jul 3, 2026
535ff58
chore(release): prepare 6.0.0-rc.2
kherembourg Jul 3, 2026
c4ce868
fix(release): tag prerelease publishes as latest
kherembourg Jul 3, 2026
6d8b202
fix(bridge): keep clientPresentationDisplayed/Closed — native v6 rena…
kherembourg Jul 7, 2026
b641a6c
chore(native): bump native SDKs to 6.0.0-rc.3 and drop rc.2 runtime f…
kherembourg Jul 7, 2026
32274c7
fix(release): complete 6.0.0-rc.3 alignment
kherembourg Jul 10, 2026
1c936ba
docs(plans): add Custom Screens (BYOS) implementation plan
chouaibMo Jul 17, 2026
7b2d504
feat: add custom screens BYOS support
chouaibMo Jul 20, 2026
f35a422
fix: unblock BYOS custom screen flows
chouaibMo Jul 21, 2026
018c5ca
fix(review): drop dead requestId branch in normalizePresentation
chouaibMo Jul 23, 2026
ff4b972
test(review): cover custom-screen key resolution; dedupe navigation g…
chouaibMo Jul 23, 2026
abfcacb
fix(review): harden native custom-screen bridge (not yet built/tested)
chouaibMo Jul 23, 2026
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
7 changes: 7 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ jobs:
cd example/android
./gradlew :app:assembleDebug $GRADLE_FLAGS

- name: Run Purchasely Android native unit tests
env:
JAVA_OPTS: "-XX:MaxHeapSize=4g"
run: |
cd example/android
./gradlew :react-native-purchasely:testDebugUnitTest

build-ios:
runs-on: macos-latest
steps:
Expand Down
118 changes: 118 additions & 0 deletions .github/workflows/e2e-android.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
name: E2E Android

on:
workflow_dispatch:
schedule:
# 2h00 UTC chaque nuit
- cron: '0 2 * * *'
push:
branches:
- feat/sdk-v6-migration
paths:
# SDK source (shared JS bridge + native): changing the bridge must run E2E.
- 'packages/purchasely/src/**'
- 'packages/purchasely/ios/**'
- 'packages/purchasely/android/src/**'
- 'packages/purchasely/android/build.gradle'
- 'packages/*/android/build.gradle'
- '.github/workflows/e2e-android.yml'
- 'integration_test/**'
- 'example/src/E2ETestRunner.tsx'
- 'example/android/app/build.gradle'
pull_request:
paths:
# SDK source (shared JS bridge + native): changing the bridge must run E2E.
- 'packages/purchasely/src/**'
- 'packages/purchasely/ios/**'
- 'packages/purchasely/android/src/**'
- 'packages/purchasely/android/build.gradle'
- 'packages/*/android/build.gradle'
- '.github/workflows/e2e-android.yml'
- 'integration_test/**'
- 'example/src/E2ETestRunner.tsx'
- 'example/android/app/build.gradle'

concurrency:
group: e2e-android
cancel-in-progress: true

jobs:
e2e-android:
name: E2E Tests (Android T1-T20)
# ubuntu-latest: KVM disponible pour x86_64, requis par reactivecircuit/android-emulator-runner.
# macOS sera utilisé dans e2e-ios.yml (simulateur iOS).
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Enable KVM
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm

- name: Setup Node.js 20
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'yarn'

- name: Setup Java 17
uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: '17'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5
with:
gradle-version: wrapper
cache-read-only: false

- name: Install JS dependencies
run: yarn install --immutable

- name: Build JS SDK
run: yarn purchasely:prepare

- name: Build release APK (JS always bundled in release)
# Release builds always embed the JS bundle — no Metro bundler needed in CI.
# ProGuard is disabled in build.gradle (enableProguardInReleaseBuilds = false).
# -x lintVitalRelease skips lint step that false-positives on ReactActivity.
env:
JAVA_OPTS: "-XX:MaxHeapSize=4g"
run: |
cd example/android
./gradlew :app:assembleRelease -x lintVitalRelease
# Verify the JS bundle is embedded
APK="app/build/outputs/apk/release/app-release.apk"
if unzip -l "$APK" | grep -q "index.android.bundle"; then
echo "✅ JS bundle confirmed in APK"
else
echo "❌ JS bundle NOT found in APK"
exit 1
fi

- name: Run E2E suite on emulator (T1-T20)
# ReactiveCircus/android-emulator-runner handles: system-image install,
# AVD creation, emulator start with KVM, boot wait, animations disable.
uses: ReactiveCircus/android-emulator-runner@v2
with:
api-level: 34
arch: x86_64
target: google_apis
avd-name: rn_e2e_api34
disable-animations: true
emulator-options: -no-window -no-audio -no-boot-anim -gpu swiftshader_indirect -no-snapshot
script: bash integration_test/run_e2e.sh emulator-5554 --skip-build

- name: Upload logcat on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: logcat-${{ github.run_id }}
path: /tmp/e2e_rn_logcat_*.log
retention-days: 7
121 changes: 121 additions & 0 deletions .github/workflows/e2e-ios.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
name: E2E iOS

on:
workflow_dispatch:
schedule:
# 2h30 UTC chaque nuit (décalé de l'E2E Android à 2h00)
- cron: '30 2 * * *'
push:
branches:
- feat/sdk-v6-migration
paths:
# SDK source (shared JS bridge + native): changing the bridge must run E2E.
- 'packages/purchasely/src/**'
- 'packages/purchasely/ios/**'
- 'packages/purchasely/android/src/**'
- 'packages/purchasely/react-native-purchasely.podspec'
- '.github/workflows/e2e-ios.yml'
- 'integration_test/**'
- 'example/src/E2ETestRunner.tsx'
- 'example/ios/**'
pull_request:
paths:
# SDK source (shared JS bridge + native): changing the bridge must run E2E.
- 'packages/purchasely/src/**'
- 'packages/purchasely/ios/**'
- 'packages/purchasely/android/src/**'
- 'packages/purchasely/react-native-purchasely.podspec'
- '.github/workflows/e2e-ios.yml'
- 'integration_test/**'
- 'example/src/E2ETestRunner.tsx'
- 'example/ios/**'

concurrency:
group: e2e-ios
cancel-in-progress: true

jobs:
e2e-ios:
name: E2E Tests (iOS T1-T20)
# macOS requis : simulateur iOS + xcodebuild. Pas de HVF nécessaire (le
# simulateur iOS ne virtualise pas un OS invité, contrairement à l'émulateur
# Android ARM — c'est pourquoi Android tourne sur ubuntu + KVM).
# macos-15 : Xcode 16.x par défaut (RN 0.79 exige Xcode >= 16.1).
runs-on: macos-15
timeout-minutes: 60

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Select latest Xcode 16 (RN 0.79 requires >= 16.1)
run: |
LATEST=$(ls -d /Applications/Xcode_16*.app 2>/dev/null | sort -V | tail -1)
if [ -n "$LATEST" ]; then sudo xcode-select -s "$LATEST/Contents/Developer"; fi
xcodebuild -version

- name: Setup (Node + Yarn)
uses: ./.github/actions/setup

- name: Build JS SDK
run: yarn prepare

- name: Cache CocoaPods
uses: actions/cache@v4
with:
path: |
example/ios/Pods
~/.cocoapods
~/Library/Caches/CocoaPods
key: ${{ runner.os }}-cocoapods-${{ hashFiles('example/ios/Podfile.lock', 'packages/purchasely/react-native-purchasely.podspec') }}
restore-keys: |
${{ runner.os }}-cocoapods-

- name: Install CocoaPods
run: |
cd example/ios
pod install --repo-update
env:
NO_FLIPPER: 1

- name: Install idb (companion + client)
run: |
# idb_companion : tap Facebook (nécessite brew trust sur les brew récents).
brew tap facebook/fb
brew trust facebook/fb || true
brew install idb-companion
# fb-idb (client Python) ne supporte pas Python 3.14 (asyncio.get_event_loop
# y lève) — on l'isole dans un venv 3.11/3.12/3.13 déterministe et on
# exporte le binaire via $IDB (lu par les drivers tap/swipe).
PY=$(command -v python3.12 || command -v python3.11 || command -v python3.13 || command -v python3)
"$PY" -m venv "$RUNNER_TEMP/idbvenv"
"$RUNNER_TEMP/idbvenv/bin/pip" install -q --upgrade pip fb-idb
echo "IDB=$RUNNER_TEMP/idbvenv/bin/idb" >> "$GITHUB_ENV"
"$RUNNER_TEMP/idbvenv/bin/idb" --help >/dev/null && echo "✅ idb client OK"

- name: Boot iOS simulator
run: |
UDID=$(xcrun simctl list devices available -j | python3 -c "
import sys, json
d = json.load(sys.stdin)['devices']
cands = [v for k, vs in d.items() if 'iOS' in k for v in vs if 'iPhone' in v['name']]
# iPhone 15/16 de préférence, sinon le dernier iPhone disponible
pref = [c for c in cands if any(n in c['name'] for n in ('iPhone 16', 'iPhone 15'))]
chosen = (pref or cands)[-1]
print(chosen['udid'])
")
echo "Booting simulator $UDID"
xcrun simctl boot "$UDID"
xcrun simctl bootstatus "$UDID" -b
echo "IOS_SIMULATOR_UDID=$UDID" >> "$GITHUB_ENV"

- name: Run E2E suite on simulator (build Release + T1-T20)
run: bash integration_test/run_e2e_ios.sh "$IOS_SIMULATOR_UDID"

- name: Upload logs on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: ios-e2e-logs-${{ github.run_id }}
path: /tmp/e2e_rn_ios_*.log
retention-days: 7
10 changes: 5 additions & 5 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,20 @@ jobs:

- name: Publish react-native-purchasely
working-directory: packages/purchasely
run: npm publish --access public --provenance
run: npm publish --access public --provenance --tag latest

- name: Publish @purchasely/react-native-purchasely-google
working-directory: packages/google
run: npm publish --access public --provenance
run: npm publish --access public --provenance --tag latest

- name: Publish @purchasely/react-native-purchasely-amazon
working-directory: packages/amazon
run: npm publish --access public --provenance
run: npm publish --access public --provenance --tag latest

- name: Publish @purchasely/react-native-purchasely-huawei
working-directory: packages/huawei
run: npm publish --access public --provenance
run: npm publish --access public --provenance --tag latest

- name: Publish @purchasely/react-native-purchasely-android-player
working-directory: packages/android-player
run: npm publish --access public --provenance
run: npm publish --access public --provenance --tag latest
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,7 @@ nitrogen/


.nx/cache
.nx/workspace-data
.nx/workspace-data
jest_dx/
node-compile-cache/
**/coverage/
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v20
v22
Loading
Loading