-
Notifications
You must be signed in to change notification settings - Fork 10
148 lines (143 loc) · 6.34 KB
/
Copy pathhermes-prebuilt.yml
File metadata and controls
148 lines (143 loc) · 6.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
name: Hermes prebuilt
# Builds the pinned Hermes for Apple platforms and publishes it as a release
# asset, so `pod install` downloads it instead of compiling Hermes as part of
# every app build. The asset is keyed by everything that changes its contents,
# so a bumped pin publishes alongside the previous one rather than replacing it.
env:
GIT_CONFIG_COUNT: 1
GIT_CONFIG_KEY_0: "url.https://github.com/.insteadOf"
GIT_CONFIG_VALUE_0: "git@github.com:"
on:
workflow_dispatch:
inputs:
force:
description: Rebuild and re-upload even when the archive is already published
type: boolean
default: false
push:
branches:
- main
- next
paths:
- "packages/host/src/node/cli/hermes.ts"
- "packages/host/src/node/cli/hermes-prebuilt.ts"
- ".github/workflows/hermes-prebuilt.yml"
# Two runs publishing the same tag would race on creating the release.
concurrency:
group: ${{ github.workflow }}
jobs:
publish:
name: Publish prebuilt Hermes
runs-on: macos-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: lts/krypton
- uses: pnpm/action-setup@v6
with:
cache: true
- run: pnpm install
- run: pnpm run build
# Resolved from the test app so the archive is built against the React
# Native version this repository actually pins.
# Each command substitution is assigned before it is echoed: inside
# `echo "x=$(cmd)"` the step's exit status is echo's, so a failing cmd
# passes the step with an empty value.
- name: Resolve prebuilt Hermes name
id: hermes
working-directory: apps/test-app
run: |
archive=$(pnpm exec react-native-node-api prebuilt-hermes --print name)
tag=$(pnpm exec react-native-node-api prebuilt-hermes --print tag)
echo "archive=$archive" >> "$GITHUB_OUTPUT"
echo "tag=$tag" >> "$GITHUB_OUTPUT"
# The paths filter above fires on any edit to these files, not just a
# bumped pin — and the archive name covers every input that changes its
# contents, so an asset already published under that name is exactly what
# this run would spend half an hour rebuilding. The Actions cache is not
# enough on its own: it is scoped to the branch that wrote it, and evicts
# after 7 days or under the repository's 10 GB cap.
- name: Look for an already-published archive
id: published
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ steps.hermes.outputs.tag }}
ARCHIVE: ${{ steps.hermes.outputs.archive }}
FORCE: ${{ inputs.force }}
run: |
if [ "$FORCE" = "true" ]; then
echo "::notice::Forced: rebuilding $ARCHIVE regardless of what is published"
echo "exists=false" >> "$GITHUB_OUTPUT"
elif gh release view "$TAG" --repo "$GITHUB_REPOSITORY" --json assets \
--jq '.assets[].name' 2>/dev/null | grep -qxF "$ARCHIVE"; then
echo "::notice::$ARCHIVE is already published under $TAG — nothing to build"
echo "exists=true" >> "$GITHUB_OUTPUT"
else
echo "exists=false" >> "$GITHUB_OUTPUT"
fi
- name: Cache prebuilt Hermes
if: steps.published.outputs.exists != 'true'
uses: actions/cache@v6
with:
path: ~/Library/Caches/react-native-node-api/hermes-prebuilt
key: ${{ steps.hermes.outputs.archive }}
# --no-download so a re-run rebuilds rather than round-tripping the asset
# it is about to publish.
- name: Build prebuilt Hermes
id: build
if: steps.published.outputs.exists != 'true'
working-directory: apps/test-app
run: |
path=$(pnpm exec react-native-node-api prebuilt-hermes --no-download)
echo "path=$path" >> "$GITHUB_OUTPUT"
# CMake reports a failed feature check as a bare "not found", with the
# compiler's actual complaint only in its configure log. Surface that log
# here so a failure is diagnosable without another round trip.
- name: Dump CMake configure log
if: failure() && steps.published.outputs.exists != 'true'
run: |
log=$(find "$PWD" -name CMakeConfigureLog.yaml -path '*build_host_hermesc*' | head -1)
if [ -z "$log" ]; then
echo "No CMakeConfigureLog.yaml found"
find "$PWD" -name 'CMakeError.log' -path '*build_host_hermesc*' -exec cat {} \;
exit 0
fi
echo "::group::Environment seen by CMake"
env | sort
xcode-select --print-path
xcrun --show-sdk-path || true
echo "::endgroup::"
echo "::group::unistd.h check"
grep -n -B 5 -A 45 'unistd\.h' "$log" | head -150
echo "::endgroup::"
echo "::group::atomics check"
grep -n -B 5 -A 60 'HAVE_CXX_ATOMICS_WITHOUT_LIB' "$log" | head -180
echo "::endgroup::"
cp "$log" "$RUNNER_TEMP/CMakeConfigureLog.yaml"
- name: Upload CMake configure log
if: failure() && steps.published.outputs.exists != 'true'
uses: actions/upload-artifact@v7
with:
name: hermesc-cmake-configure-log
path: ${{ runner.temp }}/CMakeConfigureLog.yaml
if-no-files-found: ignore
# --latest=false keeps these out of the "latest release" slot, which
# belongs to the package releases changesets publishes.
- name: Publish as a release asset
if: steps.published.outputs.exists != 'true'
env:
GH_TOKEN: ${{ github.token }}
TAG: ${{ steps.hermes.outputs.tag }}
ARCHIVE_PATH: ${{ steps.build.outputs.path }}
run: |
if ! gh release view "$TAG" --repo "$GITHUB_REPOSITORY" > /dev/null 2>&1; then
gh release create "$TAG" \
--repo "$GITHUB_REPOSITORY" \
--title "Prebuilt Hermes ($TAG)" \
--notes "Hermes, built for Apple platforms from the commit pinned in \`packages/host/src/node/cli/hermes.ts\`. Downloaded by \`react-native-node-api prebuilt-hermes\` and injected into the app's \`pod install\` through \`HERMES_ENGINE_TARBALL_PATH\`." \
--latest=false
fi
gh release upload "$TAG" "$ARCHIVE_PATH" --repo "$GITHUB_REPOSITORY" --clobber