-
Notifications
You must be signed in to change notification settings - Fork 0
385 lines (347 loc) · 16.5 KB
/
build-toolchain.yml
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
name: Build Toolchain
on:
push:
branches: [main]
paths-ignore:
- 'docs/**'
- '**.md'
pull_request:
branches: [main]
paths-ignore:
- 'docs/**'
- '**.md'
workflow_dispatch:
inputs:
scheme:
description: 'Scheme to build'
required: true
default: 'main'
jobs:
start-runner:
name: Start self-hosted EC2 runner
runs-on: ubuntu-latest
# Run only on main branches to avoid triggers by non-collaborator
if: ${{ github.event_name == 'push' || github.event_name == 'workflow_dispatch' || contains(github.event.pull_request.labels.*.name, 'check-self-hosted-ci') }}
outputs:
ubuntu20_04_aarch64-label: ${{ steps.start-ubuntu20_04_aarch64-runner.outputs.label }}
ubuntu20_04_aarch64-ec2-instance-id: ${{ steps.start-ubuntu20_04_aarch64-runner.outputs.ec2-instance-id }}
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Start EC2 runner (ubuntu20_04_aarch64)
id: start-ubuntu20_04_aarch64-runner
uses: machulav/ec2-github-runner@v2
with:
mode: start
github-token: ${{ secrets.SWIFTWASM_BUILDBOT_TOKEN }}
ec2-image-id: ami-03803f6b50b56647a # swiftwasm-ci/ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-arm64-server-20221201
ec2-instance-type: c6g.xlarge
subnet-id: subnet-327f4a13
security-group-id: sg-0429f5ec2bee9dc0c
stop-runner:
name: Stop self-hosted EC2 runner
needs: [start-runner, build-toolchain]
runs-on: ubuntu-latest
# Required to stop the runner even if the error happened in the previous jobs
if: ${{ always() && needs.start-runner.result == 'success' }}
# The runner can be already stopped when re-running a part of failed jobs
continue-on-error: true
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Stop EC2 runner (ubuntu20_04_aarch64)
uses: machulav/ec2-github-runner@v2
with:
mode: stop
github-token: ${{ secrets.SWIFTWASM_BUILDBOT_TOKEN }}
label: ${{ needs.start-runner.outputs.ubuntu20_04_aarch64-label }}
ec2-instance-id: ${{ needs.start-runner.outputs.ubuntu20_04_aarch64-ec2-instance-id }}
build-matrix:
name: Build matrix
needs: [start-runner]
runs-on: ubuntu-latest
if: ${{ !cancelled() }}
outputs:
entries: ${{ steps.generate.outputs.entries }}
steps:
- uses: actions/checkout@v4
- uses: dorny/paths-filter@v3
id: changes
with:
list-files: json
filters: |
changed:
- "schemes/**"
- "tools/build/**"
- "tools/swift-sdk-generator"
- "tools/git-swift-workspace"
- name: Generate entries
id: generate
run: |
START_RUNNER_JSON="${{ runner.temp }}/start-runner.json"
cat <<EOF > "$START_RUNNER_JSON"
${{ toJson(needs.start-runner) }}
EOF
CHANGES_JSON="${{ runner.temp }}/changes.json"
cat <<EOF > "$CHANGES_JSON"
${{ steps.changes.outputs.changed_files }}
EOF
if [[ "$GITHUB_EVENT_NAME" == "workflow_dispatch" ]]; then
echo "Toolchain build triggered by workflow_dispatch with following inputs:"
cat "$GITHUB_EVENT_PATH"
fi
echo "entries=$(ruby .github/scripts/build-matrix.rb --runner $START_RUNNER_JSON --changes $CHANGES_JSON)" >> $GITHUB_OUTPUT
build-toolchain:
env:
DEVELOPER_DIR: /Applications/Xcode_15.2.app/Contents/Developer/
# https://github.com/actions/cache/blob/main/tips-and-workarounds.md#cache-segment-restore-timeout
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 30
needs: [build-matrix]
if: ${{ !cancelled() && needs.build-matrix.outputs.entries != '[]' }}
strategy:
fail-fast: false
matrix:
include: ${{ fromJSON(needs.build-matrix.outputs.entries) }}
name: ${{ matrix.job_name }}
timeout-minutes: 0
runs-on: ${{ matrix.agent_query }}
steps:
- name: Free disk space
if: ${{ matrix.free_disk_space && !startsWith(matrix.build_os, 'macos-') }}
run: |
df -h
sudo rm -rf /opt/hostedtoolcache
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /usr/local/.ghcup
sudo apt clean
if docker info > /dev/null 2>&1; then
docker rmi $(docker image ls -aq)
fi
df -h
- name: Free disk space by removing unused Xcode
if: ${{ matrix.free_disk_space && startsWith(matrix.build_os, 'macos-') }}
run: |
IN_USE_XCODE=$(xcode-select -p)
echo "Removing all Xcode installations except $IN_USE_XCODE"
for xcode in /Applications/Xcode*.app; do
if [[ $IN_USE_XCODE != "$xcode"* ]]; then
echo "Removing $xcode"
rm -rf $xcode
fi
done
- uses: actions/checkout@v4
with:
path: swiftwasm-build
submodules: true
- name: Configure git user for git-am
run: |
# Linux self-hosted runners somehow clear HOME environment variable
if [[ -z "$HOME" ]]; then
export HOME="$RUNNER_TEMP/home/buildbot"
mkdir -p "$HOME"
echo "HOME=$HOME" >> $GITHUB_ENV
fi
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Prepare sccache timestamp
id: cache_key
run: |
export SCCACHE_KEY_PREFIX="${{ matrix.target }}-${{ matrix.toolchain_channel }}-sccache-v15-"
echo "SCCACHE_KEY_PREFIX=$SCCACHE_KEY_PREFIX" >> $GITHUB_OUTPUT
echo "SCCACHE_KEY=$SCCACHE_KEY_PREFIX$(date +'%Y-%m-%d-%I-%M-%S')" >> $GITHUB_OUTPUT
- name: Check Xcode version
if: ${{ startsWith(matrix.build_os, 'macos-') }}
run: |
xcodebuild -version
- name: Clean build directory
if: ${{ matrix.clean_build_dir }}
run: |
rm -rf ${{ github.workspace }}/build \
${{ github.workspace }}/swift \
${{ github.workspace }}/swiftwasm-build/tools/swift-sdk-generator/Bundles \
${{ github.workspace }}/build-cache \
${{ github.workspace }}/build-sdk
- uses: actions/cache/restore@v4
id: build-cache
with:
path: build-cache
key: ${{ steps.cache_key.outputs.SCCACHE_KEY }}
restore-keys: |
${{ steps.cache_key.outputs.SCCACHE_KEY_PREFIX }}
- run: chmod -R 777 ./build-cache
if: ${{ steps.build-cache.outputs.cache-hit }}
- run: ./swiftwasm-build/tools/build/install-build-sdk.sh ${{ matrix.scheme }}
- run: ./swiftwasm-build/tools/git-swift-workspace --skip-history --verbose --scheme ${{ matrix.scheme }}
env:
# icu uses git-lfs and it fails to checkout due to https://github.com/git-lfs/git-lfs/issues/5749
GIT_CLONE_PROTECTION_ACTIVE: false
- name: Install Homebrew dependencies
if: ${{ startsWith(matrix.build_os, 'macos-') }}
run: |
brew bundle --file swift/Brewfile
brew install curl # For Foundation build
# LLVM implicitly depends on libzstd if it's found in the system
- name: Uninstall libzstd on macOS
if: ${{ startsWith(matrix.build_os, 'macos-') }}
run: rm -f /usr/local/lib/pkgconfig/libzstd.pc /usr/local/include/zstd.h
# release-5.9 requires 3.11 or lower Python
- uses: actions/setup-python@v5
if: ${{ startsWith(matrix.build_os, 'macos-') && (matrix.scheme == 'release-5.9' || matrix.scheme == 'release-5.10') && (matrix.agent_query == 'macos-13' || matrix.agent_query == 'macos-14') }}
with:
python-version: '3.11'
- name: Build ${{ matrix.target }} installable archive on Docker container
if: ${{ matrix.container != null }}
timeout-minutes: 300 # Exit before 6 hours limit to allow cache upload
run: |
docker container rm --force swiftwasm-ci-buildbot
docker volume rm --force oss-swift-package
docker volume create oss-swift-package
docker run --name swiftwasm-ci-buildbot \
--security-opt=no-new-privileges \
--cap-add=SYS_PTRACE \
--security-opt seccomp=unconfined \
-dit \
-e CI=$CI \
-e ONLY_SWIFT_SDK=${{ matrix.only_swift_sdk }} \
-w /home/build-user/ \
-v ${{ github.workspace }}:/source \
-v oss-swift-package:/home/build-user \
${{ matrix.container }}
docker exec swiftwasm-ci-buildbot /bin/bash -lc 'env; cp -r /source/* /home/build-user/; ./swiftwasm-build/tools/build/ci.sh ${{ matrix.scheme }}'
- name: Extract installable archive from Docker container
if: ${{ matrix.container != null && !matrix.only_swift_sdk }}
run: |
docker cp swiftwasm-ci-buildbot:/home/build-user/swift-wasm-${{ matrix.toolchain_channel }}-SNAPSHOT-${{ matrix.target }}.tar.gz .
docker cp swiftwasm-ci-buildbot:/home/build-user/swift-wasm-${{ matrix.toolchain_channel }}-SNAPSHOT-${{ matrix.target }}.artifactbundle.zip . || true
- name: Extract installable archive from Docker container (wasm32-unknown-wasi)
if: ${{ matrix.container != null && matrix.only_swift_sdk }}
run: |
docker cp swiftwasm-ci-buildbot:/home/build-user/swift-wasm-${{ matrix.toolchain_channel }}-SNAPSHOT-wasm32-unknown-wasi.artifactbundle.zip .
# release-6.0 doesn't have wasm32-unknown-wasip1-threads SDK support yet
- name: Extract installable archive from Docker container (wasm32-unknown-wasip1-threads)
if: ${{ matrix.container != null && matrix.only_swift_sdk && matrix.scheme != 'release-6.0' }}
run: |
docker cp swiftwasm-ci-buildbot:/home/build-user/swift-wasm-${{ matrix.toolchain_channel }}-SNAPSHOT-wasm32-unknown-wasip1-threads.artifactbundle.zip .
- name: Extract build-cache from Docker container
if: ${{ matrix.container != null && !cancelled() }}
run: |
rm -rf ${{ github.workspace }}/build-cache
docker cp swiftwasm-ci-buildbot:/home/build-user/build-cache ${{ github.workspace }}/build-cache
- name: Build ${{ matrix.target }} installable archive
if: ${{ matrix.container == null }}
timeout-minutes: 300 # Exit before 6 hours limit to allow cache upload
env:
SKIP_XCODE_VERSION_CHECK: 1
run: ./swiftwasm-build/tools/build/ci.sh ${{ matrix.scheme }}
- uses: actions/cache/save@v4
if: ${{ !cancelled() }}
with:
path: build-cache
key: ${{ steps.cache_key.outputs.SCCACHE_KEY }}
- name: Upload ${{ matrix.target }} installable archive
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.target }}-${{ matrix.scheme }}-installable
path: swift-wasm-${{ matrix.toolchain_channel }}-SNAPSHOT-${{ matrix.target }}.tar.gz
- name: Upload ${{ matrix.target }} SDK artifact bundle
uses: actions/upload-artifact@v4
if: ${{ !matrix.only_swift_sdk }}
with:
name: ${{ matrix.target }}-${{ matrix.scheme }}-artifactbundle
path: swift-wasm-${{ matrix.toolchain_channel }}-SNAPSHOT-${{ matrix.target }}.artifactbundle.zip
if-no-files-found: ignore
- name: Upload Swift SDK artifact bundle (wasm32-unknown-wasi)
uses: actions/upload-artifact@v4
if: ${{ matrix.only_swift_sdk }}
with:
name: ${{ matrix.scheme }}-wasm32-unknown-wasi-artifactbundle
path: swift-wasm-${{ matrix.toolchain_channel }}-SNAPSHOT-wasm32-unknown-wasi.artifactbundle.zip
- name: Upload Swift SDK artifact bundle (wasm32-unknown-wasip1-threads)
uses: actions/upload-artifact@v4
if: ${{ matrix.only_swift_sdk }}
with:
name: ${{ matrix.scheme }}-wasm32-unknown-wasip1-threads-artifactbundle
path: swift-wasm-${{ matrix.toolchain_channel }}-SNAPSHOT-wasm32-unknown-wasip1-threads.artifactbundle.zip
# Prepare for running tests
- uses: bytecodealliance/actions/wasmtime/setup@v1
with:
version: "v25.0.3"
github_token: ${{ secrets.GITHUB_TOKEN }}
# WORKAROUND: wasmkit-cli should be built from checked out source but we don't have
# build script for it yet. So we create a symlink to wasmtime for now.
# We should remove this step once we unify the build script with apple/swift's build-preset
# based build script.
- run: ln -sf "$(which wasmtime)" "$(dirname "$(which wasmtime)")/wasmkit-cli"
if: ${{ matrix.run_stdlib_test && matrix.container == null }}
- run: docker exec -u root swiftwasm-ci-buildbot bash -c 'ln -sf "$(which wasmtime)" "$(dirname "$(which wasmtime)")/wasmkit-cli"'
if: ${{ matrix.run_stdlib_test && matrix.container != null }}
- name: Run stdlib tests for wasi-wasm32
if: ${{ matrix.run_stdlib_test && matrix.container != null }}
run: |
docker exec swiftwasm-ci-buildbot /bin/bash -lc \
"./swiftwasm-build/schemes/${{ matrix.scheme }}/build/run-test.sh"
# We need this step to save disk space for the next steps when building toolchain
- name: Cleanup build directory
if: ${{ matrix.run_stdlib_test && matrix.container != null && !matrix.only_swift_sdk }}
run: docker exec swiftwasm-ci-buildbot /bin/bash -lc "rm -rf build"
- name: Run stdlib tests for wasi-wasm32
if: ${{ matrix.run_stdlib_test && matrix.container == null }}
run: ./swiftwasm-build/schemes/${{ matrix.scheme }}/build/run-test.sh
- name: Pack test results
if: ${{ matrix.run_full_test }}
run: |
tar cJf ./swift-test-results.tar.gz build/WebAssembly/swift-stdlib-wasi-wasm32/swift-test-results
- name: Upload test results
uses: actions/upload-artifact@v4
if: ${{ matrix.run_full_test }}
with:
name: ${{ matrix.target }}-test-results
path: ./swift-test-results.tar.gz
- name: Run integration tests (Swift SDK)
if: ${{ matrix.run_e2e_test && matrix.only_swift_sdk }}
run: |
docker exec swiftwasm-ci-buildbot /bin/bash -lc \
"./llvm-project/llvm/utils/lit/lit.py \
--param swift-sdk=wasm32-unknown-wasi \
--param swift-sdks-path=./swiftwasm-build/tools/swift-sdk-generator/Bundles \
--param scheme=${{ matrix.scheme }} ./swiftwasm-build/test -vv"
- name: Cleanup docker volume
if: ${{ matrix.container != null }}
run: |
docker stop swiftwasm-ci-buildbot
docker rm swiftwasm-ci-buildbot
docker volume rm --force oss-swift-package
# Run e2e test
- name: Prepare E2E test
if: ${{ !matrix.only_swift_sdk }}
run: |
INSTALL_DIR=$(mktemp -d)
tar xf swift-wasm-${{ matrix.toolchain_channel }}-SNAPSHOT-${{ matrix.target }}.tar.gz -C "$INSTALL_DIR"
echo "TOOLCHAIN=$(find "$INSTALL_DIR" -name "swift-wasm-${{ matrix.toolchain_channel }}-*" -type d | head -n1)" >> $GITHUB_ENV
- name: Build hello.wasm
shell: bash
if: ${{ matrix.build_hello_wasm && !matrix.only_swift_sdk }}
run: |
echo 'print("Hello, world!")' > hello.swift
$TOOLCHAIN/usr/bin/swiftc \
-target wasm32-unknown-wasi \
-sdk $TOOLCHAIN/usr/share/wasi-sysroot \
-resource-dir $TOOLCHAIN/usr/lib/swift_static \
hello.swift -o hello.wasm && \
echo "Successfully linked hello.wasm"
- name: Upload hello.wasm
if: ${{ matrix.build_hello_wasm && !matrix.only_swift_sdk && matrix.scheme == 'main' }}
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.target }}-hello.wasm
path: hello.wasm
- name: Run integration tests
if: ${{ matrix.run_e2e_test && !matrix.only_swift_sdk }}
run: ${{ github.workspace }}/llvm-project/llvm/utils/lit/lit.py --param package-path=$TOOLCHAIN --param scheme=${{ matrix.scheme }} ${{ github.workspace }}/swiftwasm-build/test -vv