parameters: - name: NpmPackagingMode displayName: 'NPM packages publish configuration' type: string default: 'dev' - name: BuildConfig displayName: 'Build config' type: string values: - 'Release' - 'MinSizeRel' - 'Debug' - 'RelWithDebugInfo' default: 'Release' - name: PoolName displayName: 'Pool name' type: string - name: PackageName displayName: 'Package name' type: string default: 'NPM_packages' - name: InitialStageDependsOn displayName: 'Stage that the initial stage of react-native-ci depends on' type: string default: '' - name: enable_code_sign displayName: Use GPG to sign the jars type: boolean stages: - stage: Build_Packages displayName: Build Packages dependsOn: '${{parameters.InitialStageDependsOn}}' jobs: - template: android-java-api-aar.yml parameters: buildConfig: '${{parameters.BuildConfig}}' buildSettings: '$(Build.SourcesDirectory)/tools/ci_build/github/js/react_native_e2e_full_aar_build_settings.json' artifactName: 'onnxruntime-android-full-aar' job_name_suffix: 'For_React_Native' enable_code_sign: '${{parameters.enable_code_sign}}' pool_name: '${{parameters.PoolName}}' packageName: 'onnxruntime-android' - job: Build_Ios_Pod_For_React_Native pool: vmImage: 'macOS-13' timeoutInMinutes: 90 variables: runCodesignValidationInjection: false TODAY: $[format('{0:dd}{0:MM}{0:yyyy}', pipeline.startTime)] ORT_CACHE_DIR: '$(Pipeline.Workspace)/ccache_ort' steps: - template: use-xcode-version.yml - task: UsePythonVersion@0 displayName: Use python 3.12 inputs: versionSpec: "3.12" addToPath: true architecture: "x64" - script: | pip install -r tools/ci_build/github/apple/ios_packaging/requirements.txt displayName: "Install Python requirements" - template: mac-build-step-with-cache.yml parameters: WithCache: true Today: $(TODAY) AdditionalKey: react_${{parameters.BuildConfig}} CacheDir: $(ORT_CACHE_DIR) BuildStep: - script: | set -e -x python $(Build.SourcesDirectory)/tools/ci_build/github/apple/build_and_assemble_apple_pods.py \ --build-dir "$(Build.BinariesDirectory)/ios_framework_full" \ --staging-dir "$(Build.BinariesDirectory)/staging" \ --variant Full \ --build-settings-file $(Build.SourcesDirectory)/tools/ci_build/github/js/react_native_e2e_full_ios_framework_build_settings.json displayName: Build iOS package and assemble pods env: CC: clang CXX: clang++ CCACHE_CPP2: 1 CCACHE_DEPEND: 1 CCACHE_SLOPPINESS: modules CCACHE_DIR: $(ORT_CACHE_DIR) - task: PublishPipelineArtifact@1 inputs: targetPath: '$(Build.BinariesDirectory)/staging' artifact: 'onnxruntime-ios-full-pod' - stage: ReactNative_CI displayName: React Native CI dependsOn: - Build_Packages jobs: - job: ReactNative_CI pool: vmImage: 'macOS-13' variables: runCodesignValidationInjection: false timeoutInMinutes: 90 steps: - task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3 displayName: Clean Agent Directories condition: always() - template: use-xcode-version.yml - task: UsePythonVersion@0 displayName: Use python 3.12 inputs: versionSpec: "3.12" addToPath: true architecture: "x64" - task: JavaToolInstaller@0 displayName: Use jdk 17 inputs: versionSpec: '17' jdkArchitectureOption: 'x64' jdkSourceOption: 'PreInstalled' - task: NodeTool@0 inputs: versionSpec: '20.x' - script: brew install coreutils ninja npm yarn displayName: Install coreutils, ninja, npm, and yarn - script: yarn global add detox-cli displayName: Install detox cli tools - script: brew tap wix/brew displayName: brew tap wix/brew - script: brew install applesimutils displayName: Install applesimutils tools required by detox ios - task: DownloadPipelineArtifact@2 inputs: buildType: 'current' artifactName: 'onnxruntime-android-full-aar' targetPath: '$(Build.BinariesDirectory)/android-full-aar' displayName: Download Android AAR artifacts - task: CopyFiles@2 inputs: sourceFolder: $(Build.BinariesDirectory)/android-full-aar contents: onnxruntime-android-*.aar targetFolder: $(Build.SourcesDirectory)/js/react_native/android/libs displayName: Copy Android package to React Native directory - task: DownloadPipelineArtifact@2 inputs: buildType: 'current' artifactName: 'onnxruntime-ios-full-pod' targetPath: '$(Build.BinariesDirectory)/ios-full-pod' displayName: Download iOS pod artifacts - script: | npm ci workingDirectory: '$(Build.SourcesDirectory)/js' displayName: npm ci js - script: | npm ci workingDirectory: '$(Build.SourcesDirectory)/js/common' displayName: npm ci js/common - script: | yarn workingDirectory: '$(Build.SourcesDirectory)/js/react_native' displayName: yarn js/react_native - task: PowerShell@2 inputs: filePath: '$(Build.SourcesDirectory)/tools/ci_build/github/js/pack-npm-packages.ps1' arguments: '"-dev.$(Get-Date -Format yyyyMMdd)-$(git rev-parse --short HEAD)" $(Build.SourcesDirectory) react_native' workingDirectory: '$(Build.SourcesDirectory)' errorActionPreference: stop env: ORT_JS_PACK_MODE: e2e displayName: Pack NPM packages - script: | mv $(Build.SourcesDirectory)/js/common/onnxruntime-common*.tgz onnxruntime-common.tgz yarn add --no-lockfile file:./onnxruntime-common.tgz mv $(Build.SourcesDirectory)/js/react_native/onnxruntime-react-native*.tgz onnxruntime-react-native.tgz yarn add --no-lockfile file:./onnxruntime-react-native.tgz yarn workingDirectory: '$(Build.SourcesDirectory)/js/react_native/e2e' displayName: Bootstrap Android and iOS e2e tests - script: | ORT_C_LOCAL_POD_PATH=$(Build.BinariesDirectory)/ios-full-pod/onnxruntime-c \ pod install workingDirectory: '$(Build.SourcesDirectory)/js/react_native/ios' displayName: Pod install for onnxruntime react native ios bridge library - script: | ORT_C_LOCAL_POD_PATH=$(Build.BinariesDirectory)/ios-full-pod/onnxruntime-c \ pod install workingDirectory: '$(Build.SourcesDirectory)/js/react_native/e2e/ios' displayName: Pod install for onnxruntime react native ios e2e tests - script: | yarn add --dev jest-junit workingDirectory: '$(Build.SourcesDirectory)/js/react_native/e2e' displayName: install jest junit reporter js/react_native/e2e - script: | keytool -genkey -v -keystore debug.keystore -alias androiddebugkey -storepass android \ -keypass android -keyalg RSA -keysize 2048 -validity 999999 -dname "CN=Android Debug,O=Android,C=US" workingDirectory: '$(Build.SourcesDirectory)/js/react_native/e2e/android' displayName: Generate a debug keystore - task: CopyFiles@2 inputs: sourceFolder: $(Build.BinariesDirectory)/android-full-aar contents: onnxruntime-*.aar targetFolder: $(Build.SourcesDirectory)/js/react_native/e2e/android/app/libs displayName: Copy Android package to Android e2e test directory - script: | detox build --configuration android.emu.release workingDirectory: '$(Build.SourcesDirectory)/js/react_native/e2e' displayName: Build React Native Detox Android e2e Tests - script: | detox build --configuration ios.sim.release workingDirectory: '$(Build.SourcesDirectory)/js/react_native/e2e' displayName: Build React Native Detox iOS e2e Tests # # Unit tests and E2E tests with Android emulator # - template: use-android-emulator.yml parameters: create: true start: true - template: android-dump-logs-from-steps.yml parameters: steps: - task: Gradle@3 inputs: gradleWrapperFile: '$(Build.SourcesDirectory)/js/react_native/android/gradlew' workingDirectory: '$(Build.SourcesDirectory)/js/react_native/android' options: '--stacktrace' tasks: 'connectedDebugAndroidTest' publishJUnitResults: true testResultsFiles: '**/TEST-*.xml' testRunTitle: 'React Native Android Instrumented Test results' javaHomeOption: 'path' jdkDirectory: '$(JAVA_HOME_11_X64)' sonarQubeRunAnalysis: false spotBugsAnalysis: false displayName: Run React Native Android Instrumented Tests - script: | JEST_JUNIT_OUTPUT_FILE=$(Build.SourcesDirectory)/js/react_native/e2e/android-test-results.xml \ detox test --record-logs all \ --configuration android.emu.release \ --loglevel trace \ --take-screenshots failing workingDirectory: '$(Build.SourcesDirectory)/js/react_native/e2e' displayName: Run React Native Detox Android e2e Tests - template: use-android-emulator.yml parameters: stop: true - task: PublishTestResults@2 inputs: testResultsFiles: '$(Build.SourcesDirectory)/js/react_native/e2e/android-test-results.xml' failTaskOnFailedTests: true testRunTitle: 'React Native Detox Android e2e Test Results' condition: succeededOrFailed() displayName: Publish React Native Detox Android e2e Test Results # # Unit tests and E2E tests with iOS simulator # - script: | set -e DEVICE_ID_FILE="$(Build.BinariesDirectory)/ios_simulator_device_id.txt" xcrun simctl create iPhoneRNTest com.apple.CoreSimulator.SimDeviceType.iPhone-13 > "${DEVICE_ID_FILE}" displayName: Start iOS Simulator - task: Xcode@5 inputs: actions: 'test' configuration: 'Debug' sdk: 'iphonesimulator' xcWorkspacePath: '$(Build.SourcesDirectory)/js/react_native/ios/OnnxruntimeModule.xcworkspace' scheme: 'OnnxruntimeModuleTest' packageApp: false destinationPlatformOption: 'iOS' destinationSimulators: 'iPhone 14,OS=16.4' workingDirectory: '$(Build.SourcesDirectory)/js/react_native/ios' xcprettyArgs: '--output build/reports/test-results.xml' publishJUnitResults: true testRunTitle: 'React Native iOS Instrumented Test Results' displayName: Run React Native iOS Instrumented Tests - task: PublishTestResults@2 inputs: testResultsFiles: '$(Build.SourcesDirectory)/js/react_native/ios/build/reports/test-results.xml' failTaskOnFailedTests: true testRunTitle: 'React Native iOS Instrumented Test results' condition: succeededOrFailed() displayName: Publish React Native iOS Instrumented Test Results - script: | xcrun simctl list devices displayName: List iOS Simulators continueOnError: true - script: | JEST_JUNIT_OUTPUT_FILE=$(Build.SourcesDirectory)/js/react_native/e2e/ios-test-results.xml \ detox test --record-logs all \ --configuration ios.sim.release \ --loglevel trace \ --take-screenshots failing workingDirectory: '$(Build.SourcesDirectory)/js/react_native/e2e' displayName: Run React Native Detox iOS e2e Tests - script: | set -e DEVICE_ID_FILE="$(Build.BinariesDirectory)/ios_simulator_device_id.txt" if [[ -f "${DEVICE_ID_FILE}" ]]; then xcrun simctl delete "$(cat "${DEVICE_ID_FILE}")" rm "${DEVICE_ID_FILE}" fi displayName: Stop iOS Simulator condition: always() - task: PublishTestResults@2 inputs: testResultsFiles: '$(Build.SourcesDirectory)/js/react_native/e2e/ios-test-results.xml' failTaskOnFailedTests: true testRunTitle: 'React Native Detox iOS e2e Test Results' condition: succeededOrFailed() displayName: Publish React Native Detox iOS e2e Test Results - script: | git restore . workingDirectory: '$(Build.SourcesDirectory)/js' displayName: Restore git changes - task: PowerShell@2 inputs: filePath: '$(Build.SourcesDirectory)/tools/ci_build/github/js/pack-npm-packages.ps1' arguments: '"${{parameters.NpmPackagingMode}}" $(Build.SourcesDirectory) react_native' workingDirectory: '$(Build.SourcesDirectory)' errorActionPreference: stop displayName: Pack NPM packages - task: CopyFiles@2 inputs: sourceFolder: $(Build.SourcesDirectory)/js/common contents: onnxruntime-common*.tgz targetFolder: $(Build.ArtifactStagingDirectory) displayName: 'Create Artifacts onnxruntime-common' - task: CopyFiles@2 inputs: sourceFolder: $(Build.SourcesDirectory)/js/react_native contents: onnxruntime-react-native*.tgz targetFolder: $(Build.ArtifactStagingDirectory) displayName: Create Artifacts onnxruntime-react-native - task: PublishPipelineArtifact@1 inputs: artifact: e2e_test_logs_$(Build.BuildId)_$(Build.BuildNumber)_$(System.JobAttempt) targetPath: '$(Build.SourcesDirectory)/js/react_native/e2e/artifacts' condition: succeededOrFailed() displayName: Publish React Native Detox E2E test logs - task: PublishPipelineArtifact@0 inputs: artifactName: '${{parameters.PackageName}}' targetPath: '$(Build.ArtifactStagingDirectory)' displayName: Publish Pipeline Artifact - template: explicitly-defined-final-tasks.yml