Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
29 changes: 17 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ on:
pull_request:
branches: [main, master]
workflow_call:
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
unit-tests:
Expand All @@ -12,12 +17,12 @@ jobs:

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

- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: "20"
node-version: "24"

- name: Install dependencies
working-directory: purchasely
Expand All @@ -34,12 +39,12 @@ jobs:

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

- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: "20"
node-version: "24"
cache: "npm"
cache-dependency-path: purchasely/example/package-lock.json

Expand All @@ -56,7 +61,7 @@ jobs:
# (legacy spec repo, ~1.5 GB) since CocoaPods CDN handles spec lookups
# on demand and the cache save was the real bottleneck.
- name: Cache CocoaPods
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ~/Library/Caches/CocoaPods
key: ${{ runner.os }}-cocoapods-${{ hashFiles('purchasely/plugin.xml') }}
Expand All @@ -81,17 +86,17 @@ jobs:

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

- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: "20"
node-version: "24"
cache: "npm"
cache-dependency-path: purchasely/example/package-lock.json

- name: Setup Java
uses: actions/setup-java@v4
uses: actions/setup-java@v5
with:
distribution: "temurin"
java-version: "17"
Expand Down Expand Up @@ -126,7 +131,7 @@ jobs:

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

- name: Check version consistency
run: |
Expand Down
115 changes: 115 additions & 0 deletions .github/workflows/e2e-android.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
name: E2E Android

# End-to-end JS <-> Android tests against the REAL Purchasely backend, run on a real
# Android emulator via Appium + WebdriverIO. NOT part of the PR-gating ci.yml (they need
# an emulator, real network and the uiautomator2 driver) — they run on demand + nightly.
#
# Requirements to go green:
# * the placement PURCHASELY_E2E_PLACEMENT (default ONBOARDING) must exist for the
# example app id com.purchasely.demo on the backend the example API key points to.
# * the deterministic `bridge` suite hard-gates; the `dismiss` suite is best-effort.
on:
pull_request:
branches: [main]
paths:
- "purchasely/www/**"
- "purchasely/src/android/**"
- "purchasely/example/**"
- ".github/workflows/e2e-android.yml"
workflow_dispatch:
schedule:
- cron: "0 3 * * *"

concurrency:
group: e2e-android-${{ github.ref }}
cancel-in-progress: true

jobs:
e2e-android:
name: E2E Android (real backend)
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Checkout repository
uses: actions/checkout@v7

- name: Enable KVM (hardware acceleration for the emulator)
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
uses: actions/setup-node@v5
with:
node-version: "24"

- name: Setup Java
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: "17"
cache: gradle

- name: Setup Android SDK
uses: android-actions/setup-android@v3

- name: Install Cordova CLI
run: npm install -g cordova

- name: Build debug APK
working-directory: purchasely/example
run: |
npm install
cordova platform remove android || true
cordova platform add android
cordova plugin add ../ --link
cordova plugin add ../../purchasely-google/ --link
cordova build android

- name: Install E2E deps (Appium + WebdriverIO)
working-directory: purchasely/example/e2e
run: npm install

- name: AVD cache
uses: actions/cache@v5
id: avd-cache
with:
path: |
~/.android/avd/*
~/.android/adb*
key: avd-34-google_apis-x86_64-pixel_6

- name: Create AVD + snapshot for caching
if: steps.avd-cache.outputs.cache-hit != 'true'
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 34
target: google_apis
arch: x86_64
profile: pixel_6
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
script: echo "Generated AVD snapshot for caching."

- name: Run E2E suite on emulator
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: 34
target: google_apis
arch: x86_64
profile: pixel_6
force-avd-creation: false
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
disable-animations: true
script: bash purchasely/example/e2e/tools/ci_run_e2e.sh emulator-5554

- name: Upload E2E logs
if: always()
uses: actions/upload-artifact@v7
with:
name: e2e-android-logs
path: purchasely/example/e2e/ci-logs/
retention-days: 7
79 changes: 79 additions & 0 deletions .github/workflows/e2e-ios.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: E2E iOS

# End-to-end JS <-> iOS tests against the REAL Purchasely backend, run on an iOS
# simulator via Appium (XCUITest) + WebdriverIO. NOT part of the PR-gating ci.yml.
# Runs on demand + nightly. See e2e-android.yml for the placement requirement.
on:
pull_request:
branches: [main]
paths:
- "purchasely/www/**"
- "purchasely/src/ios/**"
- "purchasely/example/**"
- ".github/workflows/e2e-ios.yml"
workflow_dispatch:
schedule:
- cron: "0 4 * * *"

concurrency:
group: e2e-ios-${{ github.ref }}
cancel-in-progress: true

jobs:
e2e-ios:
name: E2E iOS (real backend)
runs-on: macos-15
timeout-minutes: 60
steps:
- name: Checkout repository
uses: actions/checkout@v7

- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: "24"

- name: Install Cordova CLI
run: npm install -g cordova

- name: Cache CocoaPods
uses: actions/cache@v5
with:
path: ~/Library/Caches/CocoaPods
key: ${{ runner.os }}-cocoapods-${{ hashFiles('purchasely/plugin.xml') }}
restore-keys: |
${{ runner.os }}-cocoapods-

- name: Build simulator app
working-directory: purchasely/example
run: |
npm install
cordova platform remove ios || true
cordova platform add ios
cordova plugin add ../ --link
cordova build ios --emulator

- name: Install E2E deps (Appium + WebdriverIO)
working-directory: purchasely/example/e2e
run: npm install

- name: Boot iOS simulator
id: sim
run: |
UDID=$(xcrun simctl list devices available | grep -E "iPhone 16|iPhone 15" | head -1 | grep -oE "[0-9A-F-]{36}")
echo "Booting simulator $UDID"
xcrun simctl boot "$UDID" || true
xcrun simctl bootstatus "$UDID" -b || true
echo "udid=$UDID" >> "$GITHUB_OUTPUT"

- name: Run E2E suite on simulator
working-directory: purchasely/example/e2e
run: bash ./tools/ci_run_e2e_ios.sh "${{ steps.sim.outputs.udid }}"

- name: Upload E2E logs
if: always()
uses: actions/upload-artifact@v7
with:
name: e2e-ios-logs
path: purchasely/example/e2e/ci-logs/
retention-days: 7
20 changes: 16 additions & 4 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ jobs:

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

- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v5
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
Expand All @@ -50,10 +50,22 @@ jobs:

echo "✅ All versions match release tag: $TAG"

# Prerelease tags (e.g. 6.0.0-rc.1) publish under the `next` dist-tag so they
# do NOT become npm `latest`; stable tags publish under `latest`.
- name: Determine npm dist-tag
id: npmtag
run: |
if [[ "${GITHUB_REF_NAME}" == *-* ]]; then
echo "tag=next" >> "$GITHUB_OUTPUT"
else
echo "tag=latest" >> "$GITHUB_OUTPUT"
fi
echo "npm dist-tag: $(grep -oP 'tag=\K.*' "$GITHUB_OUTPUT" | tail -1)"

- name: Publish @purchasely/cordova-plugin-purchasely
working-directory: purchasely
run: npm publish --access public --provenance
run: npm publish --access public --provenance --tag ${{ steps.npmtag.outputs.tag }}

- name: Publish @purchasely/cordova-plugin-purchasely-google
working-directory: purchasely-google
run: npm publish --access public --provenance
run: npm publish --access public --provenance --tag ${{ steps.npmtag.outputs.tag }}
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# macOS
.DS_Store

# IDE artifacts (regenerated locally; not shared)
.idea/caches/
.idea/copilot.data.migration.*.xml
.idea/markdown.xml
.idea/inspectionProfiles/
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,5 @@ Cordova SDK, iOS SDK, and Android SDK versions are usually close but **may diffe
## CI/CD

- **`ci.yml`** — Runs on PRs: unit tests, iOS build, Android build, version consistency check
- **`publish.yml`** — Runs on GitHub release: calls CI first, then publishes both npm packages via OIDC trusted publishing (no npm token stored)
- **`publish.yml`** — Runs on GitHub release: calls CI first, then publishes both npm packages via OIDC trusted publishing (no npm token stored). Prerelease tags (`X.Y.Z-*`, e.g. `6.0.0-rc.1`) publish under the npm `next` dist-tag; stable tags under `latest`. Mark the GitHub release "pre-release" for RCs.
- **`e2e-android.yml` / `e2e-ios.yml`** — Device E2E (Appium + WebdriverIO) against the real backend; run on `workflow_dispatch`, nightly, and scoped PRs (not part of `ci.yml`). See `purchasely/example/e2e/README.md`.
Loading
Loading