forked from bytecodealliance/wasmtime
-
Notifications
You must be signed in to change notification settings - Fork 0
994 lines (899 loc) · 38.2 KB
/
main.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
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
name: CI
on:
# Run CI for PRs to `main` and to release branches.
#
# Note that PRs to `main` will run a subset of tests and PRs to the
# `release-*` branches will run full CI.
pull_request:
branches:
- main
- 'release-*'
# Run full CI on the `main` branch once a day to prime the GitHub Actions
# caches used by PRs and the merge queue.
schedule:
- cron: '13 4 * * *'
# This is the CI that runs for PRs-to-merge.
merge_group:
push:
branches:
# Right now merge queues can't be used with wildcards in branch protections
# so full CI runs both on PRs to release branches as well as merges to
# release branches. Note that the merge to a release branch may produce a
# tag at the end of CI if successful and the tag will trigger the artifact
# uploads as well as publication to crates.io.
- 'release-*'
- test-android-build
defaults:
run:
shell: bash
# Cancel any in-flight jobs for the same PR/branch so there's only one active
# at a time
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# Check Code style quickly by running `rustfmt` over all code
rustfmt:
name: Rustfmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ./.github/actions/install-rust
- run: rustup component add rustfmt
- run: cargo fmt --all -- --check
# common logic to cancel the entire run if this job fails
- run: gh run cancel ${{ github.run_id }}
if: failure() && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ github.token }}
# Check Code style quickly by running `clang-format` over all the C/C++ code
#
# Note that `wasmtime-platform.h` is excluded here as it's auto-generated.
clangformat:
name: Clang format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- run: |
git ls-files '*.h' '*.c' '*.cpp' | \
grep -v wasmtime-platform.h | \
grep -v wasm.h | \
xargs clang-format-15 --dry-run --Werror --verbose
# common logic to cancel the entire run if this job fails
- run: gh run cancel ${{ github.run_id }}
if: failure() && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ github.token }}
# Lint dependency graph for security advisories, duplicate versions, and
# incompatible licences
cargo_deny:
name: Cargo deny
needs: determine
if: needs.determine.outputs.audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ./.github/actions/install-rust
- run: |
set -e
curl -L https://github.com/EmbarkStudios/cargo-deny/releases/download/0.14.5/cargo-deny-0.14.5-x86_64-unknown-linux-musl.tar.gz | tar xzf -
mv cargo-deny-*-x86_64-unknown-linux-musl/cargo-deny cargo-deny
echo `pwd` >> $GITHUB_PATH
- run: cargo deny check bans licenses
# common logic to cancel the entire run if this job fails
- run: gh run cancel ${{ github.run_id }}
if: failure() && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ github.token }}
# Ensure dependencies are vetted. See https://mozilla.github.io/cargo-vet/
#
# Note that this step, on PRs only, is allowed to fail. This is then followed
# up with the `cargo_vet_failure_for_prs` step below. The intention is to
# avoid causing this check to fail PRs while still enabling it to fail the
# merge queue checks. That way PRs can enter the merge queue when this step is
# failing if `main` has picked up `cargo vet` entries in the meantime for the
# failures.
cargo_vet:
name: Cargo vet
needs: determine
if: needs.determine.outputs.audit
runs-on: ubuntu-latest
outputs:
outcome: ${{ steps.vet.outcome }}
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ./.github/actions/install-rust
- uses: ./.github/actions/install-cargo-vet
- id: vet
run: cargo vet --locked
continue-on-error: ${{ github.event_name == 'pull_request' }}
# common logic to cancel the entire run if this job fails
- run: gh run cancel ${{ github.run_id }}
if: failure() && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ github.token }}
cargo_vet_failure_for_prs:
name: Cargo vet failed on a Pull Request
needs:
- determine
- cargo_vet
if: |
needs.determine.outputs.audit
&& github.event_name == 'pull_request'
&& needs.cargo_vet.outputs.outcome == 'failure'
runs-on: ubuntu-latest
steps:
# NB: this message ideally would link back to the previous step, but I'm not
# sure how to easily do that.
- run: |
echo 'failed to run "cargo vet", see previous `Cargo vet` step'
echo 'exiting with a nonzero status now to alert PR authors'
echo 'note, though, that this PR can still enter the merge queue'
echo ''
echo 'See https://docs.wasmtime.dev/contributing-coding-guidelines.html#cargo-vet-for-contributors'
echo 'for more information about the vetting process for Wasmtime'
exit 1
# This job is a dependency of many of the jobs below. This calculates what's
# actually being run for this workflow. For example:
#
# * Pushes to branches, which is currently both pushes to merge queue branches
# as well as release branches, perform full CI.
# * PRs to release branches (not `main`) run full CI.
# * PRs to `main` will only run a few smoke tests above plus some elements of
# the test matrix. The test matrix here is determined dynamically by the
# `./ci/build-test-matrix.js` script given the commits that happened and
# the files modified.
determine:
name: Determine CI jobs to run
runs-on: ubuntu-latest
outputs:
run-full: ${{ steps.calculate.outputs.run-full }}
test-matrix: ${{ steps.calculate.outputs.test-matrix }}
build-matrix: ${{ steps.calculate.outputs.build-matrix }}
test-capi: ${{ steps.calculate.outputs.test-capi }}
test-nightly: ${{ steps.calculate.outputs.test-nightly }}
audit: ${{ steps.calculate.outputs.audit }}
preview1-adapter: ${{ steps.calculate.outputs.preview1-adapter }}
steps:
- uses: actions/checkout@v4
- id: calculate
env:
GH_TOKEN: ${{ github.token }}
run: |
touch commits.log names.log
# Note that CI doesn't run on pushes to `main`, only pushes to merge
# queue branches and release branches, so this only runs full CI in
# those locations.
if [ "${{ github.event_name }}" != "pull_request" ]; then
run_full=true
else
pr=${{ github.event.number }}
gh pr view $pr --json commits | tee commits.log
gh pr diff $pr --name-only | tee names.log || echo "failed to get files"
if [ "${{ github.base_ref }}" != "main" ]; then
run_full=true
elif grep -q 'prtest:full' commits.log; then
run_full=true
fi
if grep -q crates.c-api names.log; then
echo test-capi=true >> $GITHUB_OUTPUT
fi
if grep -q fuzz names.log; then
echo test-nightly=true >> $GITHUB_OUTPUT
fi
if grep -q sys.custom names.log; then
echo test-nightly=true >> $GITHUB_OUTPUT
fi
if grep -q Cargo.lock names.log; then
echo audit=true >> $GITHUB_OUTPUT
fi
if grep -q supply-chain names.log; then
echo audit=true >> $GITHUB_OUTPUT
fi
if grep -q component-adapter names.log; then
echo preview1-adapter=true >> $GITHUB_OUTPUT
fi
fi
matrix="$(node ./ci/build-test-matrix.js ./commits.log ./names.log $run_full)"
echo "test-matrix={\"include\":$(echo $matrix)}" >> $GITHUB_OUTPUT
echo "$matrix"
matrix="$(node ./ci/build-build-matrix.js)"
echo "build-matrix={\"include\":$(echo $matrix)}" >> $GITHUB_OUTPUT
if [ "$run_full" = "true" ]; then
echo run-full=true >> $GITHUB_OUTPUT
echo test-capi=true >> $GITHUB_OUTPUT
echo test-nightly=true >> $GITHUB_OUTPUT
echo audit=true >> $GITHUB_OUTPUT
echo preview1-adapter=true >> $GITHUB_OUTPUT
fi
# Build all documentation of Wasmtime, including the C API documentation,
# mdbook documentation, etc. This produces a `gh-pages` artifact which is what
# gets uploaded to the `gh-pages` branch later on.
doc:
needs: determine
if: needs.determine.outputs.run-full
name: Doc build
runs-on: ubuntu-latest
env:
CARGO_MDBOOK_VERSION: 0.4.37
RUSTDOCFLAGS: -Dbroken_intra_doc_links --cfg docsrs
OPENVINO_SKIP_LINKING: 1
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ./.github/actions/install-rust
with:
toolchain: wasmtime-ci-pinned-nightly
# Build C API documentation
- run: curl -L https://sourceforge.net/projects/doxygen/files/rel-1.9.3/doxygen-1.9.3.linux.bin.tar.gz/download | tar xzf -
- run: echo "`pwd`/doxygen-1.9.3/bin" >> $GITHUB_PATH
- run: cd crates/c-api && doxygen doxygen.conf
# install mdbook, build the docs, and test the docs
- uses: actions/cache@v4
with:
path: ${{ runner.tool_cache }}/mdbook
key: cargo-mdbook-bin-${{ env.CARGO_MDBOOK_VERSION }}
- run: |
echo "${{ runner.tool_cache }}/mdbook/bin" >> $GITHUB_PATH
cargo install --root ${{ runner.tool_cache }}/mdbook --version ${{ env.CARGO_MDBOOK_VERSION }} mdbook --locked
- run: (cd docs && mdbook build)
- run: cargo build -p wasi-common --features wasmtime/wat,wasmtime/cranelift
- run: (cd docs && mdbook test -L ../target/debug/deps)
# Build Rust API documentation.
# We pass in the `component-model` feature
# to match the docs.rs metadata in
# crates/wasmtime/Cargo.toml.
- run: |
cargo doc --no-deps --workspace \
--exclude wasmtime-cli \
--exclude test-programs \
--exclude wasi-http-tests \
--exclude cranelift-codegen-meta \
--features component-model
- run: cargo doc --package cranelift-codegen-meta --document-private-items
# Assemble the documentation, and always upload it as an artifact for
# inspection on PRs and such.
- run: |
mv docs/book gh-pages
mv crates/c-api/html gh-pages/c-api
mv target/doc gh-pages/api
tar czf gh-pages.tar.gz gh-pages
- uses: actions/upload-artifact@v4
with:
name: gh-pages
path: gh-pages.tar.gz
# common logic to cancel the entire run if this job fails
- run: gh run cancel ${{ github.run_id }}
if: failure() && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ github.token }}
# Checks of various feature combinations and whether things
# compile. The goal here isn't to run tests, mostly just serve as a
# double-check that Rust code compiles and is likely to work everywhere else.
checks:
needs: determine
name: Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ./.github/actions/install-rust
# Check some feature combinations of the `wasmtime` crate
- run: cargo check -p wasmtime --no-default-features
- run: cargo check -p wasmtime --no-default-features --features wat
- run: cargo check -p wasmtime --no-default-features --features profiling
- run: cargo check -p wasmtime --no-default-features --features cache
- run: cargo check -p wasmtime --no-default-features --features async
- run: cargo check -p wasmtime --no-default-features --features pooling-allocator
- run: cargo check -p wasmtime --no-default-features --features cranelift
- run: cargo check -p wasmtime --no-default-features --features component-model
- run: cargo check -p wasmtime --no-default-features --features runtime,component-model
- run: cargo check -p wasmtime --no-default-features --features cranelift,wat,async,cache
- run: cargo check -p wasmtime --no-default-features --features winch
- run: cargo check -p wasmtime --no-default-features --features wmemcheck
- run: cargo check -p wasmtime --no-default-features --features wmemcheck,cranelift,runtime
- run: cargo check -p wasmtime --no-default-features --features demangle
- run: cargo check -p wasmtime --no-default-features --features addr2line
- run: cargo check -p wasmtime --no-default-features --features gc
- run: cargo check -p wasmtime --no-default-features --features runtime,gc
- run: cargo check -p wasmtime --no-default-features --features cranelift,gc
- run: cargo check -p wasmtime --no-default-features --features runtime
- run: cargo check -p wasmtime --no-default-features --features threads
- run: cargo check -p wasmtime --no-default-features --features runtime,threads
- run: cargo check -p wasmtime --no-default-features --features cranelift,threads
- run: cargo check --features component-model
- run: cargo check -p wasmtime --features incremental-cache
- run: cargo check -p wasmtime --all-features
# Feature combinations of the `wasmtime-cli`
- run: cargo check -p wasmtime-cli --no-default-features
- run: cargo check -p wasmtime-cli --no-default-features --features run
- run: cargo check -p wasmtime-cli --no-default-features --features run,component-model
- run: cargo check -p wasmtime-cli --no-default-features --features compile
- run: cargo check -p wasmtime-cli --no-default-features --features compile,cranelift
- run: cargo check -p wasmtime-cli --no-default-features --features compile,cranelift,component-model
- run: cargo check -p wasmtime-cli --all-features
# Check that benchmarks of the cranelift project build
- run: cargo check --benches -p cranelift-codegen
# Check that the bench-api compiles
- run: cargo check -p wasmtime-bench-api
# Check some feature combinations of the `wasmtime-c-api` crate
- run: cargo check -p wasmtime-c-api --no-default-features
- run: cargo check -p wasmtime-c-api --no-default-features --features wat
- run: cargo check -p wasmtime-c-api --no-default-features --features wasi
# Checks for no_std support, ensure that crates can build on a no_std
# target
- run: rustup target add x86_64-unknown-none
- run: cargo check -p wasmtime --no-default-features --features runtime,gc,component-model
env:
CARGO_BUILD_TARGET: x86_64-unknown-none
# Check that wasmtime compiles with panic=abort since there's some `#[cfg]`
# for specifically panic=abort there.
- run: cargo check -p wasmtime
env:
RUSTFLAGS: -Cpanic=abort
# Check a few builds of the cranelift backend
# - only x86 backend support,
# - only arm64 backend support,
# - no debug_assertions.
- run: cargo check --manifest-path=./cranelift/Cargo.toml --bin clif-util --no-default-features --features=cranelift-codegen/arm64
- run: cargo check --manifest-path=./cranelift/Cargo.toml --bin clif-util --no-default-features --features=cranelift-codegen/x86
- run: cargo check --manifest-path=./cranelift/Cargo.toml --bin clif-util
env:
CARGO_PROFILE_DEV_DEBUG_ASSERTIONS: false
# Check whether `wasmtime` cross-compiles to x86_64-unknown-freebsd
# TODO: We aren't building with default features since the `ittapi` crate fails to compile on freebsd.
- run: rustup target add x86_64-unknown-freebsd
- run: cargo check -p wasmtime --no-default-features --features cranelift,wat,async,cache --target x86_64-unknown-freebsd
# Run clippy configuration
- run: rustup component add clippy
- run: cargo clippy --workspace
# Re-vendor all WIT files and ensure that they're all up-to-date by ensuring
# that there's no git changes.
- name: Re-vendor WIT
run: ./ci/vendor-wit.sh
- run: git diff --exit-code
# Re-vendor the C API and make sure it's up-to-date.
- name: Re-vendor WIT
run: ./ci/vendor-c-api-headers.sh
- run: git diff --exit-code
# common logic to cancel the entire run if this job fails
- run: gh run cancel ${{ github.run_id }}
if: failure() && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ github.token }}
# Check whether `wasmtime` cross-compiles to aarch64-pc-windows-msvc
# We don't build nor test it because it lacks trap handling.
# Tracking issue: https://github.com/bytecodealliance/wasmtime/issues/4992
checks_winarm64:
needs: determine
if: needs.determine.outputs.run-full
name: Check Windows ARM64
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ./.github/actions/install-rust
- run: rustup target add aarch64-pc-windows-msvc
- run: cargo check -p wasmtime --target aarch64-pc-windows-msvc
# common logic to cancel the entire run if this job fails
- run: gh run cancel ${{ github.run_id }}
if: failure() && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ github.token }}
# Run tests that require a nightly compiler, such as building fuzz targets.
test_nightly:
needs: determine
if: needs.determine.outputs.test-nightly
name: Nightly tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
# Note that nightly is pinned here to insulate us from breakage that might
# happen upstream. This is periodically updated through a PR.
- uses: ./.github/actions/install-rust
with:
toolchain: wasmtime-ci-pinned-nightly
# Ensure that fuzzers still build.
#
# Install the OCaml packages necessary for fuzz targets that use the
# `wasm-spec-interpreter`.
- run: cargo install cargo-fuzz --vers "^0.11" --locked
- run: sudo apt-get update && sudo apt install -y ocaml-nox ocamlbuild ocaml-findlib libzarith-ocaml-dev
- run: cargo fetch
working-directory: ./fuzz
- run: cargo fuzz build --dev -s none
- run: cargo fuzz build --dev -s none --fuzz-dir ./cranelift/isle/fuzz
- run: cargo fuzz build --dev -s none --fuzz-dir ./crates/environ/fuzz --features component-model
# common logic to cancel the entire run if this job fails
- run: gh run cancel ${{ github.run_id }}
if: failure() && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ github.token }}
# Perform all tests of the c-api
test_capi:
needs: determine
name: Test C-API ${{ matrix.os }}
runs-on: ${{ matrix.os }}
if: needs.determine.outputs.test-capi
strategy:
fail-fast: true
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ./.github/actions/install-rust
# Build and test the C API with example C programs along with the example
# Rust programs. Note that this only executes if the `determine` step told
# us to test the capi which is off-by-default for PRs.
- run: cmake -Sexamples -Bexamples/build -DBUILD_SHARED_LIBS=OFF
- run: cmake --build examples/build --config Debug
- run: cmake -E env CTEST_OUTPUT_ON_FAILURE=1 cmake --build examples/build --config Debug --target RUN_TESTS
env:
RUST_BACKTRACE: 1
if: matrix.os == 'windows-latest'
- run: cmake -E env CTEST_OUTPUT_ON_FAILURE=1 cmake --build examples/build --config Debug --target test
env:
RUST_BACKTRACE: 1
if: matrix.os != 'windows-latest'
# Perform all tests (debug mode) for `wasmtime`.
#
# Note that the full matrix for what may run here is defined within
# `./ci/build-test-matrix.js` and the execution of the `determine` step will
# calculate whether the tests are actually run as part of PRs and such.
test:
needs: determine
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
env:
QEMU_BUILD_VERSION: 8.1.5
strategy:
fail-fast: ${{ github.event_name != 'pull_request' }}
matrix: ${{ fromJson(needs.determine.outputs.test-matrix) }}
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ./.github/actions/install-rust
with:
toolchain: ${{ matrix.rust }}
# Install targets in order to build various tests throughout the repo
- run: rustup target add wasm32-wasi wasm32-unknown-unknown ${{ matrix.target }}
- run: echo CARGO_BUILD_TARGET=${{ matrix.target }} >> $GITHUB_ENV
if: matrix.target != ''
# Install OpenVINO for testing wasmtime-wasi-nn.
- uses: abrown/install-openvino-action@v8
if: runner.arch == 'X64'
# Fix an ICE for now in gcc when compiling zstd with debuginfo (??)
- run: echo CFLAGS=-g0 >> $GITHUB_ENV
if: matrix.target == 'x86_64-pc-windows-gnu'
# Update binutils if MinGW due to https://github.com/rust-lang/rust/issues/112368
- run: C:/msys64/usr/bin/pacman.exe -S --needed mingw-w64-x86_64-gcc --noconfirm
if: matrix.target == 'x86_64-pc-windows-gnu'
- shell: pwsh
run: echo "C:\msys64\mingw64\bin" >> $Env:GITHUB_PATH
if: matrix.target == 'x86_64-pc-windows-gnu'
- run: cargo fetch --locked
- uses: actions/cache@v4
with:
path: ${{ runner.tool_cache }}/qemu
key: qemu-${{ matrix.target }}-${{ env.QEMU_BUILD_VERSION }}-patchcpuinfo
if: matrix.target != '' && matrix.os == 'ubuntu-latest'
- name: Install cross-compilation tools
run: |
set -ex
sudo apt-get update
sudo apt-get install -y ${{ matrix.gcc_package }} ninja-build
# Configure Cargo for cross compilation and tell it how it can run
# cross executables
upcase=$(echo ${{ matrix.target }} | awk '{ print toupper($0) }' | sed 's/-/_/g')
echo CARGO_TARGET_${upcase}_RUNNER=${{ runner.tool_cache }}/qemu/bin/${{ matrix.qemu }} >> $GITHUB_ENV
echo CARGO_TARGET_${upcase}_LINKER=${{ matrix.gcc }} >> $GITHUB_ENV
# QEMU emulation is not always the speediest, so total testing time
# goes down if we build the libs in release mode when running tests.
echo CARGO_PROFILE_DEV_OPT_LEVEL=2 >> $GITHUB_ENV
# See comments in the source for why we enable this during QEMU
# emulation.
echo WASMTIME_TEST_NO_HOG_MEMORY=1 >> $GITHUB_ENV
# See if qemu is already in the cache
if [ -f ${{ runner.tool_cache }}/qemu/built ]; then
exit 0
fi
# Download and build qemu from source since the most recent release is
# way faster at arm emulation than the current version github actions'
# ubuntu image uses. Disable as much as we can to get it to build
# quickly.
curl https://download.qemu.org/qemu-$QEMU_BUILD_VERSION.tar.xz | tar xJf -
cd qemu-$QEMU_BUILD_VERSION
./configure --target-list=${{ matrix.qemu_target }} --prefix=${{ runner.tool_cache}}/qemu --disable-tools --disable-slirp --disable-fdt --disable-capstone --disable-docs
ninja -C build install
touch ${{ runner.tool_cache }}/qemu/built
if: matrix.gcc != ''
# Record some CPU details; this is helpful information if tests fail due
# to CPU-specific features.
- name: CPU information
run: lscpu
if: matrix.os == 'ubuntu-latest'
- name: CPU information
run: sysctl hw
if: contains(matrix.os, 'macos')
- name: CPU information
run: wmic cpu list /format:list
shell: pwsh
if: matrix.os == 'windows-latest'
# Since MPK (PKU) is not present on some GitHub runners, we check if it is
# available before force-enabling it. This occasional testing is better than
# none at all; ideally we would test in a system-mode QEMU VM.
- name: Force-run with MPK enabled, if available
if: ${{ contains(matrix.name, 'MPK') }}
run: |
if cargo run --example mpk-available; then
echo "::notice::This CI run will force-enable MPK; this ensures tests conditioned with the \`WASMTIME_TEST_FORCE_MPK\` environment variable will run with MPK-protected memory pool stripes."
echo WASMTIME_TEST_FORCE_MPK=1 >> $GITHUB_ENV
else
echo "::warning::This CI run will not test MPK; it has been detected as not available on this machine (\`cargo run --example mpk-available\`)."
fi
# Build and test all features
- run: ./ci/run-tests.sh ${{ matrix.extra_features }} --locked
env:
RUST_BACKTRACE: 1
# Test debug (DWARF) related functionality.
- run: |
sudo apt-get update && sudo apt-get install -y gdb lldb-15 llvm
# woraround for https://bugs.launchpad.net/ubuntu/+source/llvm-defaults/+bug/1972855
sudo mkdir -p /usr/lib/local/lib/python3.10/dist-packages/lldb
sudo ln -s /usr/lib/llvm-15/lib/python3.10/dist-packages/lldb/* /usr/lib/python3/dist-packages/lldb/
cargo test test_debug_dwarf -- --ignored --test-threads 1
if: matrix.os == 'ubuntu-latest' && matrix.target == ''&& needs.determine.outputs.run-full
env:
RUST_BACKTRACE: 1
LLDB: lldb-15 # override default version, 14
# NB: the test job here is explicitly lacking in cancellation of this run if
# something goes wrong. These take the longest anyway and otherwise if
# Windows fails GitHub Actions will confusingly mark the failed Windows job
# as cancelled instead of failed.
build-preview1-component-adapter:
name: Build wasi-preview1-component-adapter
needs: determine
if: needs.determine.outputs.preview1-adapter
runs-on: ubuntu-latest
permissions:
deployments: write
contents: write
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ./.github/actions/install-rust
- run: rustup target add wasm32-wasi wasm32-unknown-unknown
- name: Install wasm-tools
run: |
curl -L https://github.com/bytecodealliance/wasm-tools/releases/download/wasm-tools-1.0.27/wasm-tools-1.0.27-x86_64-linux.tar.gz | tar xfz -
echo `pwd`/wasm-tools-1.0.27-x86_64-linux >> $GITHUB_PATH
- run: ./ci/build-wasi-preview1-component-adapter.sh
env:
VERSION: ${{ github.sha }}
- uses: actions/upload-artifact@v4
with:
name: bins-wasi-preview1-component-adapter
path: target/wasm32-unknown-unknown/release/wasi_snapshot_preview1.*.wasm
# common logic to cancel the entire run if this job fails
- run: gh run cancel ${{ github.run_id }}
if: failure() && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ github.token }}
# Verify the "min platform" example still works.
test-min-platform-example:
name: Test the min-platform example
needs: determine
if: needs.determine.outputs.run-full
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ./.github/actions/install-rust
- run: cargo install cbindgen --vers "^0.26" --locked
- run: rustup target add x86_64-unknown-none
- run: ./build.sh x86_64-unknown-none
working-directory: ./examples/min-platform
# Afterwards make sure the generated header file is up to date by ensuring
# that the regeneration process didn't change anything in-tree.
- run: git diff --exit-code
# Add the `wasmtime-platform.h` file as a release artifact
- uses: actions/upload-artifact@v4
with:
name: wasmtime-platform-header
path: examples/min-platform/embedding/wasmtime-platform.h
# common logic to cancel the entire run if this job fails
- run: gh run cancel ${{ github.run_id }}
if: failure() && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ github.token }}
build-wasmtime-target-wasm32:
name: Build wasmtime-target-wasm32
if: needs.determine.outputs.run-full
needs: determine
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ./.github/actions/install-rust
- run: rustup target add wasm32-wasi wasm32-unknown-unknown
- run: cargo build --target wasm32-wasi --no-default-features --features compile,cranelift,all-arch
env:
VERSION: ${{ github.sha }}
# common logic to cancel the entire run if this job fails
- run: gh run cancel ${{ github.run_id }}
if: failure() && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ github.token }}
bench:
needs: determine
if: needs.determine.outputs.run-full
name: Run benchmarks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ./.github/actions/install-rust
- run: rustup target add wasm32-wasi
- run: cargo test --benches --release
# common logic to cancel the entire run if this job fails
- run: gh run cancel ${{ github.run_id }}
if: failure() && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ github.token }}
# Verify that cranelift's code generation is deterministic
meta_deterministic_check:
needs: determine
if: needs.determine.outputs.run-full
name: Meta deterministic check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ./.github/actions/install-rust
- run: cd cranelift/codegen && cargo build --features all-arch
- run: ci/ensure_deterministic_build.sh
# common logic to cancel the entire run if this job fails
- run: gh run cancel ${{ github.run_id }}
if: failure() && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ github.token }}
verify-publish:
needs: determine
if: github.repository == 'bytecodealliance/wasmtime' && needs.determine.outputs.run-full
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ./.github/actions/install-rust
- run: |
cd ${{ runner.tool_cache }}
curl -L https://github.com/mozilla/sccache/releases/download/0.2.13/sccache-0.2.13-x86_64-unknown-linux-musl.tar.gz | tar xzf -
echo "`pwd`/sccache-0.2.13-x86_64-unknown-linux-musl" >> $GITHUB_PATH
echo RUSTC_WRAPPER=sccache >> $GITHUB_ENV
- run: rustc scripts/publish.rs
# Make sure the tree is publish-able as-is
- run: ./publish verify
# Make sure we can bump version numbers for the next release
- run: ./publish bump
# common logic to cancel the entire run if this job fails
- run: gh run cancel ${{ github.run_id }}
if: failure() && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ github.token }}
# Run a subset of tests under MIRI on CI to help check the `unsafe` code in
# Wasmtime to make sure it's at least not obviously incorrect for basic usage.
# Note that this doesn't run the full test suite since MIRI can't actually run
# WebAssembly itself at this time (aka it doesn't support a JIT). There are a
# number of annotations throughout the code which gates some tests on MIRI not
# being run.
#
# Note that `cargo nextest` is used here additionally to get parallel test
# execution by default to help cut down on the time in CI.
miri:
needs: determine
if: needs.determine.outputs.run-full && github.repository == 'bytecodealliance/wasmtime'
name: Miri
runs-on: ubuntu-latest
env:
CARGO_NEXTEST_VERSION: 0.9.67
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ./.github/actions/install-rust
with:
toolchain: wasmtime-ci-pinned-nightly
- run: rustup component add rust-src miri
- uses: actions/cache@v4
with:
path: ${{ runner.tool_cache }}/cargo-nextest
key: cargo-nextest-bin-${{ env.CARGO_NEXTEST_VERSION }}
- run: echo "${{ runner.tool_cache }}/cargo-nextest/bin" >> $GITHUB_PATH
- run: cargo install --root ${{ runner.tool_cache }}/cargo-nextest --version ${{ env.CARGO_NEXTEST_VERSION }} cargo-nextest --locked
- run: |
cargo miri nextest run -j4 --no-fail-fast \
-p wasmtime \
-p wasmtime-cli \
-p wasmtime-environ
env:
MIRIFLAGS: -Zmiri-strict-provenance
# common logic to cancel the entire run if this job fails
- run: gh run cancel ${{ github.run_id }}
if: failure() && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ github.token }}
# Perform release builds of `wasmtime` and `libwasmtime.so`. Builds a variety
# of platforms and architectures and then uploads the release artifacts to
# this workflow run's list of artifacts.
#
# Note that the full matrix is computed by `ci/build-build-matrix.js`.
build:
needs: determine
if: needs.determine.outputs.run-full
name: Release build for ${{ matrix.build }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: ${{ github.event_name != 'pull_request' }}
matrix: ${{ fromJson(needs.determine.outputs.build-matrix) }}
steps:
- uses: actions/checkout@v4
with:
submodules: true
- uses: ./.github/actions/install-rust
with:
toolchain: ${{ matrix.rust }}
- run: |
rustup component add rust-src
rustup target add ${{ matrix.target }}
# On one builder produce the source tarball since there's no need to produce
# it everywhere
- run: ./ci/build-src-tarball.sh
if: matrix.build == 'x86_64-linux'
- uses: ./.github/actions/binary-compatible-builds
with:
name: ${{ matrix.build }}
- uses: ./.github/actions/android-ndk
if: matrix.android-target != ''
with:
target: ${{ matrix.target }}
- run: $CENTOS ./ci/build-release-artifacts.sh "${{ matrix.build }}" "${{ matrix.target }}"
# Assemble release artifacts appropriate for this platform, then upload them
# unconditionally to this workflow's files so we have a copy of them.
- run: ./ci/build-tarballs.sh "${{ matrix.build }}" "${{ matrix.target }}"
- uses: actions/upload-artifact@v4
with:
name: bins-${{ matrix.build }}
path: dist
# common logic to cancel the entire run if this job fails
- run: gh run cancel ${{ github.run_id }}
if: failure() && github.event_name != 'pull_request'
env:
GH_TOKEN: ${{ github.token }}
# This is a "join node" which depends on all prior workflows. The merge queue,
# for example, gates on this to ensure that everything has executed
# successfully.
#
# Note that this is required currently for odd reasons with github. Notably
# the set of checks to enter the merge queue and leave the merge queue must
# be the same which means that the "build" step for example shows as skipped
# for PRs but expands to many different steps for merge-queue-based PRs. That
# means that for that step there's no single name to gate on, so it's required
# to have a "join" node here which joins everything.
#
# Note that this currently always runs to always report a status, even on
# cancellation and even if dependency steps fail. Each dependency tries to
# cancel the whole run if it fails, so if a test matrix entry fails, for
# example, it cancels the build matrix entries too. This step then tries to
# fail on cancellation to ensure that the dependency failures are propagated
# correctly.
ci-status:
name: Record the result of testing and building steps
runs-on: ubuntu-latest
needs:
- test
- test_capi
- build
- rustfmt
- clangformat
- cargo_deny
- cargo_vet
- doc
- checks
- checks_winarm64
- test_nightly
- bench
- meta_deterministic_check
- verify-publish
- determine
- miri
- build-preview1-component-adapter
- build-wasmtime-target-wasm32
- test-min-platform-example
if: always()
steps:
- name: Successful test and build
if: ${{ !(contains(needs.*.result, 'failure')) }}
run: exit 0
- name: Failing test and build
if: ${{ contains(needs.*.result, 'failure') }}
run: exit 1
- name: Report failure on cancellation
if: ${{ contains(needs.*.result, 'cancelled') || cancelled() }}
run: exit 1
# The purpose of this jobs is to watch for changes on the `release-*`
# branches of this repository and look for the term
# "automatically-tag-and-release-this-commit" within merged PRs/commits. Once
# that term is found the current version of `Cargo.toml`, the `wasmtime-cli`
# Cargo.toml, is created as a tag and the tag is pushed to the repo.
# Currently the tag is created through the GitHub API with an access token to
# ensure that CI is further triggered for the tag itself which performs the
# full release process.
#
# Note that this depends on the `ci-status` step above which is the "join"
# point of this workflow for when everything succeeds. the purpose of that is
# so that the tag is only created after the aftifacts have been uploaded for
# this workflow as the `publish-artifacts.yml` workflow will download these
# artifacts and then publish them to the tag.
push-tag:
runs-on: ubuntu-latest
needs: ci-status
if: |
always()
&& needs.ci-status.result == 'success'
&& github.event_name == 'push'
&& startsWith(github.ref, 'refs/heads/release-')
&& github.repository == 'bytecodealliance/wasmtime'
steps:
- uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: Test if tag is needed
run: |
git log ${{ github.event.before }}...${{ github.event.after }} | tee main.log
version=$(grep '^version =' Cargo.toml | head -n 1 | sed 's/.*"\(.*\)"/\1/')
echo "version: $version"
echo "version=$version" >> $GITHUB_OUTPUT
echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
if grep -q "automatically-tag-and-release-this-commit" main.log; then
echo push-tag
echo "push_tag=yes" >> $GITHUB_OUTPUT
else
echo no-push-tag
echo "push_tag=no" >> $GITHUB_OUTPUT
fi
id: tag
- name: Push the tag
run: |
git_refs_url=$(jq .repository.git_refs_url $GITHUB_EVENT_PATH | tr -d '"' | sed 's/{\/sha}//g')
curl -iX POST $git_refs_url \
-H "Authorization: token ${{ secrets.PERSONAL_ACCESS_TOKEN }}" \
-d @- << EOF
{
"ref": "refs/tags/v${{ steps.tag.outputs.version }}",
"sha": "${{ steps.tag.outputs.sha }}"
}
EOF
if: steps.tag.outputs.push_tag == 'yes'