diff --git a/.github/actions/setup-demo/action.yml b/.github/actions/setup-demo/action.yml new file mode 100644 index 000000000..b796ad7a1 --- /dev/null +++ b/.github/actions/setup-demo/action.yml @@ -0,0 +1,35 @@ +name: 'Setup Demo' +description: 'Installs XcodeGen, generates the demo Xcode project, and creates Secrets.plist for Appium E2E' +inputs: + onesignal-app-id: + description: 'OneSignal App ID for the demo Secrets.plist' + required: true + onesignal-api-key: + description: 'OneSignal API Key for the demo Secrets.plist' + required: true +runs: + using: 'composite' + steps: + - name: Install XcodeGen + shell: bash + run: brew install xcodegen + + - name: Create Secrets.plist + shell: bash + working-directory: examples/demo + env: + APP_ID: ${{ inputs.onesignal-app-id }} + API_KEY: ${{ inputs.onesignal-api-key }} + run: | + python3 - <<'PY' + import os, plistlib, pathlib + pathlib.Path('App/Secrets.plist').write_bytes(plistlib.dumps({ + 'ONESIGNAL_APP_ID': os.environ['APP_ID'], + 'ONESIGNAL_API_KEY': os.environ['API_KEY'], + })) + PY + + - name: Generate Xcode project + shell: bash + working-directory: examples/demo + run: xcodegen generate diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml new file mode 100644 index 000000000..589c6e523 --- /dev/null +++ b/.github/workflows/e2e.yml @@ -0,0 +1,94 @@ +name: E2E Tests + +on: + push: + branches: + - rel/** + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build-ios: + runs-on: macos-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Set up demo + uses: ./.github/actions/setup-demo + with: + onesignal-app-id: ${{ vars.APPIUM_ONESIGNAL_APP_ID }} + onesignal-api-key: ${{ secrets.APPIUM_ONESIGNAL_API_KEY }} + + - name: Cache Xcode DerivedData + uses: actions/cache@v5 + with: + path: examples/demo/build + key: deriveddata-${{ runner.os }}-${{ hashFiles('examples/demo/project.yml', 'iOS_SDK/OneSignalSDK/OneSignal.xcodeproj/project.pbxproj') }} + restore-keys: deriveddata-${{ runner.os }}- + + - name: Set up iOS codesigning + uses: OneSignal/sdk-shared/.github/actions/setup-ios-demo-codesigning@main + with: + p12-base64: ${{ secrets.APPIUM_IOS_DEV_CERT_P12_BASE64 }} + p12-password: ${{ secrets.APPIUM_IOS_DEV_CERT_PASSWORD }} + asc-key-id: ${{ secrets.APPIUM_APP_STORE_CONNECT_KEY_ID }} + asc-issuer-id: ${{ secrets.APPIUM_APP_STORE_CONNECT_ISSUER_ID }} + asc-private-key: ${{ secrets.APPIUM_APP_STORE_CONNECT_PRIVATE_KEY }} + + - name: Build signed IPA + run: | + xcodebuild archive \ + -workspace iOS_SDK/OneSignalSDK.xcworkspace \ + -scheme App \ + -configuration Release \ + -sdk iphoneos \ + -destination 'generic/platform=iOS' \ + -archivePath examples/demo/build/App.xcarchive \ + -derivedDataPath examples/demo/build \ + -quiet \ + -hideShellScriptEnvironment \ + CODE_SIGN_STYLE=Manual \ + COMPILER_INDEX_STORE_ENABLE=NO + xcodebuild -exportArchive \ + -archivePath examples/demo/build/App.xcarchive \ + -exportOptionsPlist examples/demo/ExportOptions.plist \ + -exportPath examples/demo/build/ipa \ + -quiet + + - name: Verify aps-environment in IPA + working-directory: examples/demo + run: | + IPA=$(ls build/ipa/*.ipa | head -n1) + unzip -oq "$IPA" -d /tmp/ipa + APP=$(ls -d /tmp/ipa/Payload/*.app | head -n1) + codesign -d --entitlements - "$APP" 2>&1 | tee /tmp/entitlements.txt + if ! grep -q 'aps-environment' /tmp/entitlements.txt; then + echo "::error::Built IPA is missing aps-environment entitlement; push subscription will not work" + exit 1 + fi + + - name: Upload IPA + uses: actions/upload-artifact@v7 + with: + name: demo-ipa + path: examples/demo/build/ipa/App.ipa + retention-days: 1 + compression-level: 0 + + e2e-ios: + needs: build-ios + uses: OneSignal/sdk-shared/.github/workflows/appium-e2e.yml@main + secrets: inherit + with: + platform: ios + app-artifact: demo-ipa + app-filename: App.ipa + sdk-type: ios + build-name: ios-${{ github.ref_name }}-${{ github.run_number }} diff --git a/examples/demo/App.xcodeproj/project.pbxproj b/examples/demo/App.xcodeproj/project.pbxproj index 73adfdf6e..c2eb9fe65 100644 --- a/examples/demo/App.xcodeproj/project.pbxproj +++ b/examples/demo/App.xcodeproj/project.pbxproj @@ -358,7 +358,7 @@ E194A3F19072CB17A8F1A12E /* SmsSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmsSection.swift; sourceTree = ""; }; ECAC7EF0B67920F9FEC4F129 /* TagsSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagsSection.swift; sourceTree = ""; }; F46DFACB9F304B9374F3C570 /* ToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastView.swift; sourceTree = ""; }; - "TEMP_196A01E1-FF4D-4A91-B9D6-E6100CF24C88" /* Build.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Build.xcconfig; sourceTree = ""; }; + "TEMP_E243B27C-2274-4671-9C94-8B86EB8D4EFA" /* Build.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Build.xcconfig; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -564,10 +564,10 @@ path = Views; sourceTree = ""; }; - "TEMP_BC60B80C-3553-4130-8508-42B5AB6C4C1B" /* demo */ = { + "TEMP_9E448277-C21D-48E5-98E2-992293BCF68A" /* demo */ = { isa = PBXGroup; children = ( - "TEMP_196A01E1-FF4D-4A91-B9D6-E6100CF24C88" /* Build.xcconfig */, + "TEMP_E243B27C-2274-4671-9C94-8B86EB8D4EFA" /* Build.xcconfig */, ); path = demo; sourceTree = ""; @@ -658,18 +658,6 @@ BuildIndependentTargetsInParallel = YES; LastUpgradeCheck = 1430; TargetAttributes = { - 61033D7807F09753830EDBC1 = { - DevelopmentTeam = ""; - ProvisioningStyle = Automatic; - }; - 93E9E330FC2CE7458D9C925F = { - DevelopmentTeam = ""; - ProvisioningStyle = Automatic; - }; - 97373B3889FBDD1762E98B03 = { - DevelopmentTeam = ""; - ProvisioningStyle = Automatic; - }; }; }; buildConfigurationList = B3FD05C59F197F398A0B04AB /* Build configuration list for PBXProject "App" */; @@ -948,10 +936,11 @@ /* Begin XCBuildConfiguration section */ 0D2EF3911CA89837C30DB0D1 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = "TEMP_196A01E1-FF4D-4A91-B9D6-E6100CF24C88" /* Build.xcconfig */; + baseConfigurationReference = "TEMP_E243B27C-2274-4671-9C94-8B86EB8D4EFA" /* Build.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + DEVELOPMENT_TEAM = 99SW8E36CT; INFOPLIST_FILE = OneSignalWidget/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 16.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; @@ -965,11 +954,12 @@ }; 4A0C935808978B5A7673E412 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = "TEMP_196A01E1-FF4D-4A91-B9D6-E6100CF24C88" /* Build.xcconfig */; + baseConfigurationReference = "TEMP_E243B27C-2274-4671-9C94-8B86EB8D4EFA" /* Build.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = App.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; + DEVELOPMENT_TEAM = 99SW8E36CT; ENABLE_USER_SCRIPT_SANDBOXING = NO; INFOPLIST_FILE = App/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 16.0; @@ -1044,14 +1034,20 @@ }; D0E56A85F1C385808720F94B /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = "TEMP_196A01E1-FF4D-4A91-B9D6-E6100CF24C88" /* Build.xcconfig */; + baseConfigurationReference = "TEMP_E243B27C-2274-4671-9C94-8B86EB8D4EFA" /* Build.xcconfig */; buildSettings = { CODE_SIGN_ENTITLEMENTS = OneSignalNotificationServiceExtension/OneSignalNotificationServiceExtension.entitlements; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 99SW8E36CT; INFOPLIST_FILE = OneSignalNotificationServiceExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.onesignal.example.NSE; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Appium Demo - NSE"; SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; @@ -1060,17 +1056,22 @@ }; EB1CC3A930E09FEBECF9195D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = "TEMP_196A01E1-FF4D-4A91-B9D6-E6100CF24C88" /* Build.xcconfig */; + baseConfigurationReference = "TEMP_E243B27C-2274-4671-9C94-8B86EB8D4EFA" /* Build.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = App.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 99SW8E36CT; ENABLE_USER_SCRIPT_SANDBOXING = NO; INFOPLIST_FILE = App/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.onesignal.example; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Appium Demo - Main"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -1078,15 +1079,21 @@ }; F305A3E63851EE49DA2D190E /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = "TEMP_196A01E1-FF4D-4A91-B9D6-E6100CF24C88" /* Build.xcconfig */; + baseConfigurationReference = "TEMP_E243B27C-2274-4671-9C94-8B86EB8D4EFA" /* Build.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME = WidgetBackground; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 99SW8E36CT; INFOPLIST_FILE = OneSignalWidget/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 16.2; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.onesignal.example.LA; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "Appium Demo - Live Activity"; SDKROOT = iphoneos; SKIP_INSTALL = YES; TARGETED_DEVICE_FAMILY = "1,2"; @@ -1095,9 +1102,10 @@ }; F5FD25168D9B32A08A468069 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = "TEMP_196A01E1-FF4D-4A91-B9D6-E6100CF24C88" /* Build.xcconfig */; + baseConfigurationReference = "TEMP_E243B27C-2274-4671-9C94-8B86EB8D4EFA" /* Build.xcconfig */; buildSettings = { CODE_SIGN_ENTITLEMENTS = OneSignalNotificationServiceExtension/OneSignalNotificationServiceExtension.entitlements; + DEVELOPMENT_TEAM = 99SW8E36CT; INFOPLIST_FILE = OneSignalNotificationServiceExtension/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; diff --git a/examples/demo/ExportOptions.plist b/examples/demo/ExportOptions.plist new file mode 100644 index 000000000..b7361222e --- /dev/null +++ b/examples/demo/ExportOptions.plist @@ -0,0 +1,23 @@ + + + + + method + development + teamID + 99SW8E36CT + signingStyle + manual + stripSwiftSymbols + + provisioningProfiles + + com.onesignal.example + Appium Demo - Main + com.onesignal.example.NSE + Appium Demo - NSE + com.onesignal.example.LA + Appium Demo - Live Activity + + + diff --git a/examples/demo/project.yml b/examples/demo/project.yml index c79bf193f..fe654b541 100644 --- a/examples/demo/project.yml +++ b/examples/demo/project.yml @@ -59,6 +59,16 @@ targets: TARGETED_DEVICE_FAMILY: "1,2" LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks" ENABLE_USER_SCRIPT_SANDBOXING: NO + configs: + Debug: + DEVELOPMENT_TEAM: 99SW8E36CT + Release: + CODE_SIGN_IDENTITY: "iPhone Developer" + CODE_SIGN_STYLE: Manual + DEVELOPMENT_TEAM: "" + "DEVELOPMENT_TEAM[sdk=iphoneos*]": 99SW8E36CT + PROVISIONING_PROFILE_SPECIFIER: "" + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]": "Appium Demo - Main" dependencies: # SDK Swift framework targets (built from local source via the workspace) - target: OneSignalSDK/OneSignalCore @@ -123,6 +133,16 @@ targets: TARGETED_DEVICE_FAMILY: "1,2" LD_RUNPATH_SEARCH_PATHS: "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks" SKIP_INSTALL: YES + configs: + Debug: + DEVELOPMENT_TEAM: 99SW8E36CT + Release: + "CODE_SIGN_IDENTITY[sdk=iphoneos*]": "iPhone Developer" + CODE_SIGN_STYLE: Manual + DEVELOPMENT_TEAM: "" + "DEVELOPMENT_TEAM[sdk=iphoneos*]": 99SW8E36CT + PROVISIONING_PROFILE_SPECIFIER: "" + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]": "Appium Demo - NSE" dependencies: - target: OneSignalSDK/OneSignalCore embed: false @@ -156,6 +176,16 @@ targets: SKIP_INSTALL: YES ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME: AccentColor ASSETCATALOG_COMPILER_WIDGET_BACKGROUND_COLOR_NAME: WidgetBackground + configs: + Debug: + DEVELOPMENT_TEAM: 99SW8E36CT + Release: + "CODE_SIGN_IDENTITY[sdk=iphoneos*]": "iPhone Developer" + CODE_SIGN_STYLE: Manual + DEVELOPMENT_TEAM: "" + "DEVELOPMENT_TEAM[sdk=iphoneos*]": 99SW8E36CT + PROVISIONING_PROFILE_SPECIFIER: "" + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]": "Appium Demo - Live Activity" dependencies: - target: OneSignalSDK/OneSignalLiveActivities embed: false