2323permissions :
2424 contents : write
2525
26+ env :
27+ SCCACHE_VERSION : 0.10.0
28+
2629# Nine jobs a run, several hours each -- superseded runs are not worth finishing.
2730# Tags are excluded from cancellation so a release is never interrupted.
2831concurrency :
@@ -35,13 +38,19 @@ jobs:
3538 outputs :
3639 v8_version : ${{ steps.cfg.outputs.v8_version }}
3740 ndk_release : ${{ steps.cfg.outputs.ndk_release }}
41+ inputs_hash : ${{ steps.cfg.outputs.inputs_hash }}
3842 steps :
3943 - uses : actions/checkout@v7
4044 - id : cfg
4145 run : |
4246 set -a; . ./config.env; set +a
4347 echo "v8_version=$V8_VERSION" >> "$GITHUB_OUTPUT"
4448 echo "ndk_release=$ANDROID_NDK_RELEASE" >> "$GITHUB_OUTPUT"
49+ # Everything the artifacts are a function of, hashed by blob id.
50+ # Commits with an unchanged hash produce identical artifacts, so a
51+ # finished build in R2 can be reused instead of repeated.
52+ echo "inputs_hash=$(git ls-files -s config.env patches scripts/matrix .github/workflows/build-matrix.yml \
53+ | git hash-object --stdin)" >> "$GITHUB_OUTPUT"
4554
4655 android :
4756 needs : config
@@ -52,61 +61,129 @@ jobs:
5261 fail-fast : false
5362 matrix :
5463 abi : [arm64-v8a, x86_64, armeabi-v7a, x86]
64+ # The R2 bucket has two prefixes with separate lifecycle rules:
65+ # artifacts/<inputs-hash>/ holds finished tarballs (expired quickly; a miss
66+ # just means building, as before) and sccache/ holds the compiler cache
67+ # (kept long). Every R2 step is skipped when the secrets are absent, e.g.
68+ # on a fork PR, and the build then runs exactly as it would without R2.
69+ env :
70+ R2_BUCKET : ${{ vars.R2_BUCKET }}
71+ R2_ENDPOINT : https://${{ secrets.R2_ACCOUNT_ID }}.r2.cloudflarestorage.com
72+ AWS_ACCESS_KEY_ID : ${{ secrets.R2_ACCESS_KEY_ID }}
73+ AWS_SECRET_ACCESS_KEY : ${{ secrets.R2_SECRET_ACCESS_KEY }}
74+ AWS_DEFAULT_REGION : auto
75+ # aws-cli >= 2.23 defaults to CRC checksums R2 rejects.
76+ AWS_REQUEST_CHECKSUM_CALCULATION : when_required
77+ AWS_RESPONSE_CHECKSUM_VALIDATION : when_required
78+ SCCACHE_BUCKET : ${{ vars.R2_BUCKET }}
79+ SCCACHE_ENDPOINT : https://${{ secrets.R2_ACCOUNT_ID }}.r2.cloudflarestorage.com
80+ SCCACHE_REGION : auto
81+ SCCACHE_S3_KEY_PREFIX : sccache
5582 steps :
5683 - uses : actions/checkout@v7
5784
85+ - name : Check R2 for prebuilt artifacts
86+ id : cache
87+ if : env.AWS_ACCESS_KEY_ID != ''
88+ run : |
89+ keys="v8-${{ needs.config.outputs.v8_version }}-android-${{ matrix.abi }}.tar.gz"
90+ if [ "${{ matrix.abi }}" = "arm64-v8a" ]; then
91+ keys="$keys v8-${{ needs.config.outputs.v8_version }}-src-headers.tar.gz"
92+ fi
93+ prefix="artifacts/${{ needs.config.outputs.inputs_hash }}"
94+ hit=true
95+ for k in $keys; do
96+ aws s3api head-object --endpoint-url "$R2_ENDPOINT" \
97+ --bucket "$R2_BUCKET" --key "$prefix/$k" >/dev/null 2>&1 || hit=false
98+ done
99+ if [ "$hit" = true ]; then
100+ for k in $keys; do
101+ aws s3 cp --endpoint-url "$R2_ENDPOINT" "s3://$R2_BUCKET/$prefix/$k" "$k"
102+ done
103+ fi
104+ echo "hit=$hit" >> "$GITHUB_OUTPUT"
105+
58106 # A 32-bit target builds mksnapshot and the bytecode-builtins generator
59107 # as 32-bit x86 host binaries. Without the i386 runtime they link and
60108 # then fail to execute, which surfaces only as a failed
61109 # generate_bytecode_builtins_list action.
62110 - name : Enable i386 multiarch
111+ if : steps.cache.outputs.hit != 'true'
63112 run : |
64113 sudo dpkg --add-architecture i386
65114 sudo apt-get update -qq
66115 sudo apt-get install -y -qq --no-install-recommends \
67116 libc6:i386 libstdc++6:i386 libatomic1:i386 zlib1g:i386 rsync
68117
69118 - name : Install the Android NDK ${{ needs.config.outputs.ndk_release }}
119+ if : steps.cache.outputs.hit != 'true'
70120 run : |
71121 curl -fsSL -o /tmp/ndk.zip \
72122 "https://dl.google.com/android/repository/android-ndk-${{ needs.config.outputs.ndk_release }}-linux.zip"
73123 unzip -q /tmp/ndk.zip -d "$HOME"
74124 echo "ANDROID_NDK_ROOT=$HOME/android-ndk-${{ needs.config.outputs.ndk_release }}" >> "$GITHUB_ENV"
75125
76126 - name : Install depot_tools
127+ if : steps.cache.outputs.hit != 'true'
77128 run : |
78129 git clone -q --depth 1 https://chromium.googlesource.com/chromium/tools/depot_tools.git "$HOME/depot_tools"
79130 echo "$HOME/depot_tools" >> "$GITHUB_PATH"
80131
132+ - name : Install sccache
133+ if : env.AWS_ACCESS_KEY_ID != '' && steps.cache.outputs.hit != 'true'
134+ run : |
135+ curl -fsSL "https://github.com/mozilla/sccache/releases/download/v${SCCACHE_VERSION}/sccache-v${SCCACHE_VERSION}-x86_64-unknown-linux-musl.tar.gz" \
136+ | tar -xz -C /tmp
137+ mkdir -p "$HOME/.local/bin"
138+ install "/tmp/sccache-v${SCCACHE_VERSION}-x86_64-unknown-linux-musl/sccache" "$HOME/.local/bin/"
139+ echo "$HOME/.local/bin" >> "$GITHUB_PATH"
140+
81141 - name : Fetch and patch V8
82- run : scripts/matrix/fetch.sh --platform android
142+ if : steps.cache.outputs.hit != 'true'
143+ run : scripts/matrix/fetch.sh --platform android --no-history
83144
84145 - name : Build ${{ matrix.abi }}
85- run : scripts/matrix/build-android.sh --abi ${{ matrix.abi }}
146+ if : steps.cache.outputs.hit != 'true'
147+ run : >
148+ scripts/matrix/build-android.sh --abi ${{ matrix.abi }}
149+ ${{ env.AWS_ACCESS_KEY_ID != '' && '--cc-wrapper sccache' || '' }}
150+
151+ - name : sccache stats
152+ if : env.AWS_ACCESS_KEY_ID != '' && steps.cache.outputs.hit != 'true'
153+ run : sccache --show-stats
86154
87155 - name : Package
156+ if : steps.cache.outputs.hit != 'true'
88157 run : |
89158 tar -czf "v8-${{ needs.config.outputs.v8_version }}-android-${{ matrix.abi }}.tar.gz" \
90159 -C dist "android-${{ matrix.abi }}"
91160
92- - uses : actions/upload-artifact@v7
93- with :
94- name : v8-android-${{ matrix.abi }}
95- path : v8-*-android-${{ matrix.abi }}.tar.gz
96- retention-days : 7
97-
98161 # The internal headers are architecture-independent, so one job produces
99162 # them. It piggybacks on a build rather than getting its own job because
100163 # src/inspector/protocol/*.h are generated into gen/ and only exist once
101164 # something has been built.
102165 - name : Package the internal headers
103- if : matrix.abi == 'arm64-v8a'
166+ if : matrix.abi == 'arm64-v8a' && steps.cache.outputs.hit != 'true'
104167 run : |
105168 scripts/matrix/package-src-headers.sh \
106169 --gen-dir .v8/v8/out.gn/android-arm64-release/gen
107170 tar -czf "v8-${{ needs.config.outputs.v8_version }}-src-headers.tar.gz" \
108171 -C dist src-headers
109172
173+ - name : Upload the artifacts to R2
174+ if : env.AWS_ACCESS_KEY_ID != '' && steps.cache.outputs.hit != 'true'
175+ run : |
176+ prefix="artifacts/${{ needs.config.outputs.inputs_hash }}"
177+ for f in v8-*.tar.gz; do
178+ aws s3 cp --endpoint-url "$R2_ENDPOINT" "$f" "s3://$R2_BUCKET/$prefix/$f"
179+ done
180+
181+ - uses : actions/upload-artifact@v7
182+ with :
183+ name : v8-android-${{ matrix.abi }}
184+ path : v8-*-android-${{ matrix.abi }}.tar.gz
185+ retention-days : 7
186+
110187 - uses : actions/upload-artifact@v7
111188 if : matrix.abi == 'arm64-v8a'
112189 with :
@@ -123,25 +200,78 @@ jobs:
123200 fail-fast : false
124201 matrix :
125202 variant : [arm64-device, arm64-simulator, x64-simulator, arm64-catalyst, x64-catalyst]
203+ # See the android job for the R2 bucket layout and the missing-secrets
204+ # fallback; this job mirrors it.
205+ env :
206+ R2_BUCKET : ${{ vars.R2_BUCKET }}
207+ R2_ENDPOINT : https://${{ secrets.R2_ACCOUNT_ID }}.r2.cloudflarestorage.com
208+ AWS_ACCESS_KEY_ID : ${{ secrets.R2_ACCESS_KEY_ID }}
209+ AWS_SECRET_ACCESS_KEY : ${{ secrets.R2_SECRET_ACCESS_KEY }}
210+ AWS_DEFAULT_REGION : auto
211+ AWS_REQUEST_CHECKSUM_CALCULATION : when_required
212+ AWS_RESPONSE_CHECKSUM_VALIDATION : when_required
213+ SCCACHE_BUCKET : ${{ vars.R2_BUCKET }}
214+ SCCACHE_ENDPOINT : https://${{ secrets.R2_ACCOUNT_ID }}.r2.cloudflarestorage.com
215+ SCCACHE_REGION : auto
216+ SCCACHE_S3_KEY_PREFIX : sccache
126217 steps :
127218 - uses : actions/checkout@v7
128219
220+ - name : Check R2 for a prebuilt artifact
221+ id : cache
222+ if : env.AWS_ACCESS_KEY_ID != ''
223+ run : |
224+ key="artifacts/${{ needs.config.outputs.inputs_hash }}/v8-${{ needs.config.outputs.v8_version }}-ios-${{ matrix.variant }}.tar.gz"
225+ if aws s3api head-object --endpoint-url "$R2_ENDPOINT" \
226+ --bucket "$R2_BUCKET" --key "$key" >/dev/null 2>&1; then
227+ aws s3 cp --endpoint-url "$R2_ENDPOINT" "s3://$R2_BUCKET/$key" .
228+ echo "hit=true" >> "$GITHUB_OUTPUT"
229+ else
230+ echo "hit=false" >> "$GITHUB_OUTPUT"
231+ fi
232+
129233 - name : Install depot_tools
234+ if : steps.cache.outputs.hit != 'true'
130235 run : |
131236 git clone -q --depth 1 https://chromium.googlesource.com/chromium/tools/depot_tools.git "$HOME/depot_tools"
132237 echo "$HOME/depot_tools" >> "$GITHUB_PATH"
133238
239+ - name : Install sccache
240+ if : env.AWS_ACCESS_KEY_ID != '' && steps.cache.outputs.hit != 'true'
241+ run : |
242+ curl -fsSL "https://github.com/mozilla/sccache/releases/download/v${SCCACHE_VERSION}/sccache-v${SCCACHE_VERSION}-aarch64-apple-darwin.tar.gz" \
243+ | tar -xz -C /tmp
244+ mkdir -p "$HOME/.local/bin"
245+ install "/tmp/sccache-v${SCCACHE_VERSION}-aarch64-apple-darwin/sccache" "$HOME/.local/bin/"
246+ echo "$HOME/.local/bin" >> "$GITHUB_PATH"
247+
134248 - name : Fetch and patch V8
135- run : scripts/matrix/fetch.sh --platform ios
249+ if : steps.cache.outputs.hit != 'true'
250+ run : scripts/matrix/fetch.sh --platform ios --no-history
136251
137252 - name : Build ${{ matrix.variant }}
138- run : scripts/matrix/build-ios.sh --variant ${{ matrix.variant }}
253+ if : steps.cache.outputs.hit != 'true'
254+ run : >
255+ scripts/matrix/build-ios.sh --variant ${{ matrix.variant }}
256+ ${{ env.AWS_ACCESS_KEY_ID != '' && '--cc-wrapper sccache' || '' }}
257+
258+ - name : sccache stats
259+ if : env.AWS_ACCESS_KEY_ID != '' && steps.cache.outputs.hit != 'true'
260+ run : sccache --show-stats
139261
140262 - name : Package
263+ if : steps.cache.outputs.hit != 'true'
141264 run : |
142265 tar -czf "v8-${{ needs.config.outputs.v8_version }}-ios-${{ matrix.variant }}.tar.gz" \
143266 -C dist "ios-${{ matrix.variant }}"
144267
268+ - name : Upload the artifact to R2
269+ if : env.AWS_ACCESS_KEY_ID != '' && steps.cache.outputs.hit != 'true'
270+ run : |
271+ f="v8-${{ needs.config.outputs.v8_version }}-ios-${{ matrix.variant }}.tar.gz"
272+ aws s3 cp --endpoint-url "$R2_ENDPOINT" "$f" \
273+ "s3://$R2_BUCKET/artifacts/${{ needs.config.outputs.inputs_hash }}/$f"
274+
145275 - uses : actions/upload-artifact@v7
146276 with :
147277 name : v8-ios-${{ matrix.variant }}
0 commit comments