From 71581e87268b6659595d8ba3b8f7888ecc9cf65e Mon Sep 17 00:00:00 2001 From: theeket Date: Fri, 6 Nov 2026 10:59:48 +0700 Subject: [PATCH] Fix Mac Catalyst framework symlinks in published iOS prebuilds --- .github/workflows/prebuild-ios-core.yml | 30 +++++++++++++++---- .../workflows/prebuild-ios-dependencies.yml | 30 +++++++++++++++---- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/.github/workflows/prebuild-ios-core.yml b/.github/workflows/prebuild-ios-core.yml index ae1fdb916675..e28da449cc08 100644 --- a/.github/workflows/prebuild-ios-core.yml +++ b/.github/workflows/prebuild-ios-core.yml @@ -100,12 +100,15 @@ jobs: with: name: prebuild-ios-core-headers-${{ matrix.flavor }}-${{ matrix.slice }} path: packages/react-native/.build/headers + - name: Compress slice to preserve symlinks + run: | + tar -czf "$RUNNER_TEMP/prebuild-ios-core-slice-${{ matrix.flavor }}-${{ matrix.slice }}.tar.gz" \ + -C packages/react-native/.build/output/spm/${{ matrix.flavor }}/Build/Products . - name: Upload artifacts uses: ./.github/actions/upload-artifact with: name: prebuild-ios-core-slice-${{ matrix.flavor }}-${{ matrix.slice }} - path: | - packages/react-native/.build/output/spm/${{ matrix.flavor }}/Build/Products + path: ${{ runner.temp }}/prebuild-ios-core-slice-${{ matrix.flavor }}-${{ matrix.slice }}.tar.gz - name: Save Cache uses: actions/cache/save@v5 if: ${{ github.ref == 'refs/heads/main' }} # To avoid that the cache explode @@ -133,7 +136,7 @@ jobs: uses: actions/cache/restore@v5 with: path: packages/react-native/.build/output/xcframeworks - key: v4-ios-core-xcframework-${{ matrix.flavor }}-${{ hashFiles('packages/react-native/Package.swift', 'packages/react-native/scripts/ios-prebuild/*.js', 'packages/react-native/scripts/ios-prebuild.js', 'packages/react-native/React/**/*', 'packages/react-native/ReactCommon/**/*', 'packages/react-native/Libraries/**/*') }} + key: v5-ios-core-xcframework-${{ matrix.flavor }}-${{ hashFiles('packages/react-native/Package.swift', 'packages/react-native/scripts/ios-prebuild/*.js', 'packages/react-native/scripts/ios-prebuild.js', 'packages/react-native/React/**/*', 'packages/react-native/ReactCommon/**/*', 'packages/react-native/Libraries/**/*') }} - name: Setup node.js if: steps.restore-ios-xcframework.outputs.cache-hit != 'true' uses: ./.github/actions/setup-node @@ -148,8 +151,15 @@ jobs: uses: ./.github/actions/download-artifact with: pattern: prebuild-ios-core-slice-${{ matrix.flavor }}-* - path: packages/react-native/.build/output/spm/${{ matrix.flavor }}/Build/Products + path: ${{ runner.temp }}/prebuild-slices merge-multiple: true + - name: Extract slices + if: steps.restore-ios-xcframework.outputs.cache-hit != 'true' + run: | + mkdir -p packages/react-native/.build/output/spm/${{ matrix.flavor }}/Build/Products + for archive in "$RUNNER_TEMP"/prebuild-slices/*.tar.gz; do + tar -xzf "$archive" -C packages/react-native/.build/output/spm/${{ matrix.flavor }}/Build/Products + done - name: Download headers if: steps.restore-ios-xcframework.outputs.cache-hit != 'true' uses: ./.github/actions/download-artifact @@ -222,6 +232,16 @@ jobs: # regressions here instead of in downstream builds. cd packages/react-native node scripts/ios-prebuild/headers-verify.js --flavor "${{ matrix.flavor }}" ${{ inputs.version-type != '' && '--require-stamped-version' || '' }} + - name: Verify Mac Catalyst framework symlinks + if: steps.restore-ios-xcframework.outputs.cache-hit != 'true' + run: | + framework="packages/react-native/.build/output/xcframeworks/${{ matrix.flavor }}/React.xcframework/ios-arm64_x86_64-maccatalyst/React.framework" + for link in React Resources Versions/Current; do + if [ ! -L "$framework/$link" ]; then + echo "::error::Expected framework symlink: $framework/$link. Archive build slices before uploading them." + exit 1 + fi + done - name: Compress and Rename XCFramework if: steps.restore-ios-xcframework.outputs.cache-hit != 'true' run: | @@ -267,4 +287,4 @@ jobs: packages/react-native/.build/output/xcframeworks/ReactCore${{matrix.flavor}}.xcframework.tar.gz packages/react-native/.build/output/xcframeworks/ReactCore${{matrix.flavor}}.framework.dSYM.tar.gz packages/react-native/.build/output/xcframeworks/ReactNativeHeaders${{matrix.flavor}}.xcframework.tar.gz - key: v4-ios-core-xcframework-${{ matrix.flavor }}-${{ hashFiles('packages/react-native/Package.swift', 'packages/react-native/scripts/ios-prebuild/*.js', 'packages/react-native/scripts/ios-prebuild.js', 'packages/react-native/React/**/*', 'packages/react-native/ReactCommon/**/*', 'packages/react-native/Libraries/**/*') }} + key: v5-ios-core-xcframework-${{ matrix.flavor }}-${{ hashFiles('packages/react-native/Package.swift', 'packages/react-native/scripts/ios-prebuild/*.js', 'packages/react-native/scripts/ios-prebuild.js', 'packages/react-native/React/**/*', 'packages/react-native/ReactCommon/**/*', 'packages/react-native/Libraries/**/*') }} diff --git a/.github/workflows/prebuild-ios-dependencies.yml b/.github/workflows/prebuild-ios-dependencies.yml index d4afaed08eb5..536352effc16 100644 --- a/.github/workflows/prebuild-ios-dependencies.yml +++ b/.github/workflows/prebuild-ios-dependencies.yml @@ -91,12 +91,15 @@ jobs: - name: Build slice ${{ matrix.slice }} for ${{ matrix.flavor }} if: steps.restore-slice-folder.outputs.cache-hit != 'true' run: node scripts/releases/prepare-ios-prebuilds.js -b -p ${{ matrix.slice }} -r ${{ matrix.flavor }} + - name: Compress slice to preserve symlinks + run: | + tar -czf "$RUNNER_TEMP/prebuild-slice-${{ matrix.flavor }}-${{ matrix.slice }}.tar.gz" \ + -C packages/react-native/third-party/.build/Build/Products . - name: Upload Artifacts uses: ./.github/actions/upload-artifact with: name: prebuild-slice-${{ matrix.flavor }}-${{ matrix.slice }} - path: | - packages/react-native/third-party/.build/Build/Products + path: ${{ runner.temp }}/prebuild-slice-${{ matrix.flavor }}-${{ matrix.slice }}.tar.gz - name: Save Cache uses: actions/cache/save@v5 if: ${{ github.ref == 'refs/heads/main' }} # To avoid that the cache explode @@ -130,7 +133,7 @@ jobs: with: path: | packages/react-native/third-party/ - key: v5-ios-dependencies-xcframework-${{ matrix.flavor }}-${{ hashfiles('scripts/releases/ios-prebuild/configuration.js', 'scripts/releases/ios-prebuild/build.js', 'scripts/releases/ios-prebuild/compose-framework.js', 'packages/react-native/scripts/ios-prebuild/headers-xcframework.js', 'packages/react-native/scripts/ios-prebuild/headers-spec.js') }} + key: v6-ios-dependencies-xcframework-${{ matrix.flavor }}-${{ hashfiles('scripts/releases/ios-prebuild/configuration.js', 'scripts/releases/ios-prebuild/build.js', 'scripts/releases/ios-prebuild/compose-framework.js', 'packages/react-native/scripts/ios-prebuild/headers-xcframework.js', 'packages/react-native/scripts/ios-prebuild/headers-spec.js') }} # If cache hit, we already have our binary. We don't need to do anything. - name: Yarn Install if: steps.restore-xcframework.outputs.cache-hit != 'true' @@ -146,8 +149,15 @@ jobs: uses: ./.github/actions/download-artifact with: pattern: prebuild-slice-${{ matrix.flavor }}-* - path: packages/react-native/third-party/.build/Build/Products + path: ${{ runner.temp }}/prebuild-slices merge-multiple: true + - name: Extract slices + if: steps.restore-xcframework.outputs.cache-hit != 'true' + run: | + mkdir -p packages/react-native/third-party/.build/Build/Products + for archive in "$RUNNER_TEMP"/prebuild-slices/*.tar.gz; do + tar -xzf "$archive" -C packages/react-native/third-party/.build/Build/Products + done - name: Setup Keychain if: ${{ steps.restore-xcframework.outputs.cache-hit != 'true' && env.REACT_ORG_CODE_SIGNING_P12_CERT != '' }} uses: apple-actions/import-codesign-certs@v3 # https://github.com/marketplace/actions/import-code-signing-certificates @@ -160,6 +170,16 @@ jobs: - name: Create and Sign XCFramework if: ${{ steps.restore-xcframework.outputs.cache-hit != 'true' && env.REACT_ORG_CODE_SIGNING_P12_CERT != '' }} run: node scripts/releases/prepare-ios-prebuilds.js -c -i "React Org" + - name: Verify Mac Catalyst framework symlinks + if: steps.restore-xcframework.outputs.cache-hit != 'true' + run: | + framework="packages/react-native/third-party/ReactNativeDependencies.xcframework/ios-arm64_x86_64-maccatalyst/ReactNativeDependencies.framework" + for link in ReactNativeDependencies Resources Versions/Current; do + if [ ! -L "$framework/$link" ]; then + echo "::error::Expected framework symlink: $framework/$link. Archive build slices before uploading them." + exit 1 + fi + done - name: Compress and Rename XCFramework if: steps.restore-xcframework.outputs.cache-hit != 'true' run: | @@ -204,4 +224,4 @@ jobs: packages/react-native/third-party/ReactNativeDependencies${{ matrix.flavor }}.xcframework.tar.gz packages/react-native/third-party/ReactNativeDependenciesHeaders${{ matrix.flavor }}.xcframework.tar.gz packages/react-native/third-party/ReactNativeDependencies${{ matrix.flavor }}.framework.dSYM.tar.gz - key: v5-ios-dependencies-xcframework-${{ matrix.flavor }}-${{ hashfiles('scripts/releases/ios-prebuild/configuration.js', 'scripts/releases/ios-prebuild/build.js', 'scripts/releases/ios-prebuild/compose-framework.js', 'packages/react-native/scripts/ios-prebuild/headers-xcframework.js', 'packages/react-native/scripts/ios-prebuild/headers-spec.js') }} + key: v6-ios-dependencies-xcframework-${{ matrix.flavor }}-${{ hashfiles('scripts/releases/ios-prebuild/configuration.js', 'scripts/releases/ios-prebuild/build.js', 'scripts/releases/ios-prebuild/compose-framework.js', 'packages/react-native/scripts/ios-prebuild/headers-xcframework.js', 'packages/react-native/scripts/ios-prebuild/headers-spec.js') }}