77 resolve-hermes :
88 name : " Resolve Hermes"
99 runs-on : macos-15
10- timeout-minutes : 10
10+ timeout-minutes : 15
1111 outputs :
1212 hermes-commit : ${{ steps.resolve.outputs.hermes-commit }}
1313 cache-hit : ${{ steps.cache.outputs.cache-hit }}
14+ recomposed : ${{ steps.recompose.outputs.recomposed }}
1415 steps :
1516 - uses : actions/checkout@v4
1617 with :
2627 - name : Install npm dependencies
2728 run : yarn install
2829
30+ - name : Download upstream Hermes tarball
31+ id : download
32+ working-directory : packages/react-native
33+ run : |
34+ node -e "
35+ const {downloadUpstreamHermesTarball} = require('./scripts/ios-prebuild/macosVersionResolver');
36+ downloadUpstreamHermesTarball('Debug').then(r => {
37+ require('fs').writeFileSync('/tmp/hermes-download-result.json', JSON.stringify(r));
38+ });
39+ "
40+ RESULT=$(cat /tmp/hermes-download-result.json)
41+ if [ "$RESULT" != "null" ]; then
42+ TARBALL=$(node -e "console.log(JSON.parse(process.argv[1]).tarballPath)" "$RESULT")
43+ VERSION=$(node -e "console.log(JSON.parse(process.argv[1]).version)" "$RESULT")
44+ echo "tarball=$TARBALL" >> "$GITHUB_OUTPUT"
45+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
46+ echo "Downloaded upstream Hermes tarball for version $VERSION"
47+ else
48+ echo "No upstream tarball available"
49+ fi
50+
51+ - name : Recompose xcframework with macOS slice
52+ id : recompose
53+ if : steps.download.outputs.tarball != ''
54+ run : |
55+ TARBALL="${{ steps.download.outputs.tarball }}"
56+
57+ # Extract tarball
58+ mkdir -p hermes-destroot
59+ tar -xzf "$TARBALL" -C hermes-destroot --strip-components=2
60+
61+ echo "=== Upstream tarball contents ==="
62+ ls -la hermes-destroot/Library/Frameworks/
63+
64+ # Collect existing frameworks from the universal xcframework
65+ XCFW="hermes-destroot/Library/Frameworks/universal/hermes.xcframework"
66+ FRAMEWORKS=()
67+ for fw in "$XCFW"/*/hermes.framework; do
68+ if [ -d "$fw" ]; then
69+ echo "Found slice: $fw"
70+ FRAMEWORKS+=(-framework "$fw")
71+ fi
72+ done
73+
74+ # Add standalone macOS framework
75+ MAC_FW="hermes-destroot/Library/Frameworks/macosx/hermes.framework"
76+ if [ -d "$MAC_FW" ]; then
77+ echo "Found standalone macOS slice: $MAC_FW"
78+ FRAMEWORKS+=(-framework "$MAC_FW")
79+ else
80+ echo "::error::Upstream tarball missing macosx/hermes.framework"
81+ echo "recomposed=false" >> "$GITHUB_OUTPUT"
82+ exit 0
83+ fi
84+
85+ # Remove old xcframework and create new one with macOS included
86+ rm -rf "$XCFW"
87+ echo "Creating new universal xcframework with ${#FRAMEWORKS[@]} frameworks..."
88+ xcodebuild -create-xcframework "${FRAMEWORKS[@]}" \
89+ -output "$XCFW" \
90+ -allow-internal-distribution
91+
92+ # Clean up standalone macOS dir (now included in universal)
93+ rm -rf hermes-destroot/Library/Frameworks/macosx
94+
95+ echo "=== Recomposed xcframework ==="
96+ ls -la "$XCFW"/
97+
98+ echo "recomposed=true" >> "$GITHUB_OUTPUT"
99+
100+ - name : Upload recomposed Hermes artifacts
101+ if : steps.recompose.outputs.recomposed == 'true'
102+ uses : actions/upload-artifact@v4
103+ with :
104+ name : hermes-artifacts
105+ path : hermes-destroot
106+ retention-days : 30
107+
108+ # Fallback: resolve Hermes commit for build-from-source
29109 - name : Resolve Hermes commit at merge base
110+ if : steps.recompose.outputs.recomposed != 'true'
30111 id : resolve
31112 working-directory : packages/react-native
32113 run : |
@@ -35,14 +116,15 @@ jobs:
35116 echo "Resolved Hermes commit: $COMMIT"
36117
37118 - name : Restore Hermes cache
119+ if : steps.recompose.outputs.recomposed != 'true'
38120 id : cache
39121 uses : actions/cache/restore@v4
40122 with :
41123 key : hermes-v1-${{ steps.resolve.outputs.hermes-commit }}-Debug
42124 path : hermes-destroot
43125
44126 - name : Upload cached Hermes artifacts
45- if : steps.cache.outputs.cache-hit == 'true'
127+ if : steps.recompose.outputs.recomposed != 'true' && steps. cache.outputs.cache-hit == 'true'
46128 uses : actions/upload-artifact@v4
47129 with :
48130 name : hermes-artifacts
51133
52134 build-hermesc :
53135 name : " Build hermesc"
54- if : ${{ needs.resolve-hermes.outputs.cache-hit != 'true' }}
136+ if : ${{ needs.resolve-hermes.outputs.recomposed != 'true' && needs.resolve-hermes.outputs. cache-hit != 'true' }}
55137 needs : resolve-hermes
56138 runs-on : macos-15
57139 timeout-minutes : 30
92174
93175 build-hermes-slice :
94176 name : " Hermes ${{ matrix.slice }}"
95- if : ${{ needs.resolve-hermes.outputs.cache-hit != 'true' }}
177+ if : ${{ needs.resolve-hermes.outputs.recomposed != 'true' && needs.resolve-hermes.outputs. cache-hit != 'true' }}
96178 needs : [resolve-hermes, build-hermesc]
97179 runs-on : macos-15
98180 timeout-minutes : 45
@@ -160,7 +242,7 @@ jobs:
160242
161243 assemble-hermes :
162244 name : " Assemble Hermes xcframework"
163- if : ${{ needs.resolve-hermes.outputs.cache-hit != 'true' }}
245+ if : ${{ needs.resolve-hermes.outputs.recomposed != 'true' && needs.resolve-hermes.outputs. cache-hit != 'true' }}
164246 needs : [resolve-hermes, build-hermes-slice]
165247 runs-on : macos-15
166248 timeout-minutes : 15
0 commit comments