diff --git a/.azurepipelines/build-rn-code-push-1es.yml b/.azurepipelines/build-rn-code-push-1es.yml deleted file mode 100644 index b9423bd..0000000 --- a/.azurepipelines/build-rn-code-push-1es.yml +++ /dev/null @@ -1,104 +0,0 @@ -trigger: -- master - -pr: -- master - -resources: - repositories: - - repository: 1ESPipelineTemplates - type: git - name: 1ESPipelineTemplates/1ESPipelineTemplates - ref: refs/tags/release -name: $(Build.SourceBranchName)_$(date:yyyyMMdd)$(rev:.r) - -extends: - ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/master') }}: - template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates - ${{ else }}: - template: v1/1ES.Unofficial.PipelineTemplate.yml@1ESPipelineTemplates - parameters: - pool: - name: 1ES-PT-CBL-Mariner-2.0-Gen2 - os: linux - customBuildTags: - - ES365AIMigrationTooling-BulkMigrated - sdl: - sourceAnalysisPool: 1ES-PT-Windows-2022 - credscan: - suppressionsFile: $(Build.SourcesDirectory)/.config/CredScanSuppressions.json - stages: - - stage: Stage - jobs: - - job: HostJob - templateContext: - outputs: - - output: pipelineArtifact - displayName: "Publish Artifact: artifacts" - path: '$(Build.ArtifactStagingDirectory)/npm' - artifactName: npm - - steps: - - task: NodeTool@0 - inputs: - versionSpec: '14.x' - displayName: 'Install Node.js' - - - script: | - npm pack - npm install -g react-native-code-push*.tgz - displayName: 'Package react-native-code-push' - workingDirectory: $(Build.SourcesDirectory) - - - task: DeleteFiles@1 - inputs: - contents: node_modules - displayName: 'Delete node_modules' - - - task: ArchiveFiles@2 - inputs: - rootFolderOrFile: '$(Build.SourcesDirectory)' - includeRootFolder: false - archiveType: 'tar' - archiveFile: '$(Build.ArtifactStagingDirectory)/npm/$(Build.BuildId).tgz' - replaceExistingArchive: true - verbose: true - displayName: 'Prepare npm artifact' - - - stage: APIScan - dependsOn: Stage - pool: - name: 1ES-PT-Windows-2022 - os: windows - variables: - "agent.source.skip": true - jobs: - - job: APIScan - steps: - - task: DownloadPipelineArtifact@2 - displayName: Download Build Artifacts for APIScan - inputs: - artifactName: npm - targetPath: '$(Agent.BuildDirectory)/npm' - - task: ExtractFiles@1 - inputs: - archiveFilePatterns: '$(Agent.BuildDirectory)/npm/*.tgz' - destinationFolder: '$(Agent.BuildDirectory)/npm_extracted' - - task: AzureKeyVault@2 - inputs: - azureSubscription: 'AC - Dev Infra & Build Pool' - KeyVaultName: 'mobile-center-sdk' - SecretsFilter: 'appcenter-sdk-managed-identity-clientid' - RunAsPreJob: false - - task: APIScan@2 - displayName: 'Run APIScan' - inputs: - softwareFolder: '$(Agent.BuildDirectory)\npm_extracted' - softwareName: 'react-native-code-push' - softwareVersionNum: '$(Build.BuildId)' - isLargeApp: false - toolVersion: 'Latest' - verbosityLevel: verbose - condition: and(succeeded(), ne(variables['DisableAPIScan'], 'true')) - env: - AzureServicesAuthConnectionString: 'runAs=App;AppId=$(appcenter-sdk-managed-identity-clientid)' \ No newline at end of file diff --git a/.azurepipelines/test-rn-code-push.yml b/.azurepipelines/test-rn-code-push.yml deleted file mode 100644 index baf19ed..0000000 --- a/.azurepipelines/test-rn-code-push.yml +++ /dev/null @@ -1,94 +0,0 @@ -trigger: -- master - -pr: -- master - -variables: -- name: api-level - value: '27' - -pool: - vmImage: 'macOS-12' - -stages: -- stage: RunTests - displayName: 'Run Android & IOS tests' - jobs: - - job: TestAndroid - timeoutInMinutes: 120 - displayName: 'Test android' - steps: - - - script: | - adb devices - displayName: 'Start adb server' - - - script: | - $ANDROID_HOME/tools/bin/sdkmanager "system-images;android-$(api-level);google_apis;x86" - displayName: 'Download system image' - - - script: | - $ANDROID_HOME/tools/bin/avdmanager create avd --force --name TestEmulator --abi google_apis/x86 --package 'system-images;android-$(api-level);google_apis;x86' --device "Nexus 6P" - displayName: 'Creating Android emulator' - - - script: | - $ANDROID_HOME/emulator/emulator -avd TestEmulator -noaudio -no-window -no-snapshot-save -no-boot-anim -memory 6144 & - displayName: 'Start Android emulator' - - - script: | - $ANDROID_HOME/platform-tools/adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do sleep 1; done' - displayName: 'Wait for emulator to boot' - - - script: | - adb shell settings put global window_animation_scale 0.0 - displayName: 'Disable animations and transitions' - - - script: | - adb shell settings put global transition_animation_scale 0.0 - displayName: 'Disable animations and transitions' - - - script: | - adb shell settings put global animator_duration_scale 0.0 - displayName: 'Disable animations and transitions' - - - - task: JavaToolInstaller@0 - inputs: - versionSpec: '11' - jdkArchitectureOption: 'x64' - jdkSourceOption: 'PreInstalled' - displayName: 'Change Java version' - - - script: | - npm install - displayName: 'Package Installation' - - - script: | - npm run build:tests && npm run test:setup:android - displayName: 'Setup Android tests' - - - script: | - npm run test:fast:android - displayName: 'Run Android test' - - - job: TestIOS - timeoutInMinutes: 120 - displayName: 'Test IOS' - steps: - - - script: | - npm install - displayName: 'Install dependencies' - - - script: | - npm run build:tests && npm run test:setup:ios - displayName: 'Setup iOS tests' - - - script: | - npm run test:fast:ios - displayName: 'Run tests' - - - - diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-test.yml index e49aac3..d7631bd 100644 --- a/.github/workflows/ci-test.yml +++ b/.github/workflows/ci-test.yml @@ -2,47 +2,60 @@ name: CI Tests on: pull_request: - types: [opened, edited] workflow_dispatch: jobs: - android-new-arch-test: - runs-on: self-hosted + lint: + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v7 - - name: Run Android Tests - run: | - npm install - npm run test:android + - uses: jdx/mise-action@v4 + + - name: Install dependencies + run: npm install + - name: Lint and type-check + run: npm run build:tests - ios-new-arch-test: - runs-on: self-hosted + android-test: + needs: lint + runs-on: bitrise-react-native-code-push-linux-runner steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v7 - - name: Run iOS Tests - run: | - npm install - npm run test:ios + - uses: jdx/mise-action@v4 - android-old-arch-test: - runs-on: self-hosted - steps: - - uses: actions/checkout@v3 + - name: Install dependencies + run: npm install - - name: Run Android Tests + - name: Enable KVM run: | - npm install - npm run test:oldArch:android + 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 - ios-old-arch-test: - runs-on: self-hosted + - name: Run Android Tests + uses: reactivecircus/android-emulator-runner@v2 + env: + # Tests need `emulator` to be in $PATH. + PATH: /usr/local/lib/android/sdk/emulator:/usr/local/lib/android/sdk/platform-tools:${{ env.PATH }} + with: + api-level: 27 + target: google_apis + arch: x86 + disable-animations: true + script: npm run test:android + + ios-test: + needs: lint + runs-on: bitrise-react-native-code-push-macos-runner steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v7 + + - uses: jdx/mise-action@v4 - name: Run iOS Tests run: | npm install - npm run test:oldArch:ios \ No newline at end of file + npm run test:ios diff --git a/.gitignore b/.gitignore index 2510af0..ddc58ec 100644 --- a/.gitignore +++ b/.gitignore @@ -195,3 +195,5 @@ Examples/testapp_rn #CodePushExpoDemoApp *.rm + +.claude/settings.local.json diff --git a/ios/CodePush/CodePush.m b/ios/CodePush/CodePush.m index bd92a79..d9d40b6 100644 --- a/ios/CodePush/CodePush.m +++ b/ios/CodePush/CodePush.m @@ -538,19 +538,10 @@ - (void)loadBundle // file (since Chrome wouldn't support it). Otherwise, update // the current bundle URL to point at the latest update if ([CodePush isUsingTestConfiguration] || ![super.bridge.bundleURL.scheme hasPrefix:@"http"]) { - RCTReloadCommandSetBundleURL([CodePush bundleURL]); - // [super.bridge setValue:[CodePush bundleURL] forKey:@"bundleURL"]; + [super.bridge setValue:[CodePush bundleURL] forKey:@"bundleURL"]; } - // Add a small delay to ensure Fabric surface initialization is complete - // before triggering reload. This fixes a race condition in React Native 0.82+ - // with New Architecture where RCTInstance invalidate and RCTFabricSurface start - // can run concurrently, causing a crash when MountingCoordinator's mutex is accessed - // after being destroyed. - // - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - RCTTriggerReloadCommandListeners(@"react-native-code-push: Restart"); - }); + RCTTriggerReloadCommandListeners(@"react-native-code-push: Restart"); }); } diff --git a/mise.toml b/mise.toml new file mode 100644 index 0000000..ee9b7ed --- /dev/null +++ b/mise.toml @@ -0,0 +1,4 @@ +[tools] +node = "22" +java = "17" +ruby = "4.0" diff --git a/test/template/ios/Podfile b/test/template/ios/Podfile index bb0376a..dff03d4 100644 --- a/test/template/ios/Podfile +++ b/test/template/ios/Podfile @@ -31,5 +31,38 @@ target 'TestCodePush' do :mac_catalyst_enabled => false, # :ccache_enabled => true ) + + # Workaround: fmt 11.0.2 (pinned transitively via RCT-Folly) fails to compile on + # Xcode 26.4+ due to a compiler compatibility bug. Fixed upstream in fmt 12.1.0. + # See https://github.com/facebook/react-native/issues/55601 + # + # REMOVE THIS once the React Native version used here bundles fmt >= 12.1.0 + # (i.e. after upgrading React Native past 0.82.x). + installer.pods_project.targets.each do |target| + if target.name == 'fmt' + target.build_configurations.each do |config| + config.build_settings['CLANG_CXX_LANGUAGE_STANDARD'] = 'c++17' + end + end + end + + # Skip the x86_64 simulator slice. Test runs only ever target an arm64 + # simulator (Apple Silicon), so building x86_64 as well just doubles + # compile/link time for a slice that never runs, and adds unnecessary + # failure surface (e.g. codegen sources that don't compile cleanly for it). + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'x86_64' + end + end + + installer.aggregate_targets.each do |aggregate_target| + aggregate_target.user_project.native_targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'x86_64' + end + end + aggregate_target.user_project.save + end end -end \ No newline at end of file +end diff --git a/test/test.ts b/test/test.ts index 7e59e78..00de751 100644 --- a/test/test.ts +++ b/test/test.ts @@ -285,7 +285,7 @@ class RNIOS extends Platform.IOS implements RNPlatform { return this.getEmulatorManager().getTargetEmulator() .then((targetEmulator: string) => { return TestUtil.getProcessOutput("xcodebuild -workspace " + path.join(iOSProject, TestConfig.TestAppName) + ".xcworkspace -scheme " + TestConfig.TestAppName + - " -configuration Release -destination \"platform=iOS Simulator,id=" + targetEmulator + "\" -derivedDataPath build EXCLUDED_ARCHS=arm64", { cwd: iOSProject, timeout: 30 * 60 * 1000, maxBuffer: 1024 * 1024 * 5000, noLogStdOut: true }); + " -configuration Release -destination \"platform=iOS Simulator,id=" + targetEmulator + "\" -derivedDataPath build", { cwd: iOSProject, timeout: 10 * 60 * 1000, maxBuffer: 1024 * 1024 * 5000, noLogStdOut: true }); }) .then( () => { return null; },