1name: CI
2on:
3  push:
4    branches: [main]
5    tags-ignore: [dev]
6    paths-ignore:
7      - 'meetings/**'
8  pull_request:
9    branches: ['main', 'release-*']
10    paths-ignore:
11      - 'meetings/**'
12defaults:
13  run:
14    shell: bash
15
16# Cancel any in-flight jobs for the same PR/branch so there's only one active
17# at a time
18concurrency:
19  group: ${{ github.workflow }}-${{ github.ref }}
20  cancel-in-progress: true
21
22jobs:
23  # Check Code style quickly by running `rustfmt` over all code
24  rustfmt:
25    name: Rustfmt
26    runs-on: ubuntu-latest
27    steps:
28    - uses: actions/checkout@v2
29      with:
30        submodules: true
31    - uses: ./.github/actions/install-rust
32    - run: rustup component add rustfmt
33    - run: cargo fmt --all -- --check
34
35  # Lint dependency graph for security advisories, duplicate versions, and
36  # incompatible licences
37  cargo_deny:
38    name: Cargo deny
39    runs-on: ubuntu-latest
40    steps:
41    - uses: actions/checkout@v2
42      with:
43        submodules: true
44    - uses: ./.github/actions/install-rust
45    - run: |
46        set -e
47        curl -L https://github.com/EmbarkStudios/cargo-deny/releases/download/0.8.5/cargo-deny-0.8.5-x86_64-unknown-linux-musl.tar.gz | tar xzf -
48        mv cargo-deny-*-x86_64-unknown-linux-musl/cargo-deny cargo-deny
49        echo `pwd` >> $GITHUB_PATH
50    - run: cargo deny check bans licenses
51
52  doc:
53    name: Doc build
54    runs-on: ubuntu-latest
55    env:
56      CARGO_MDBOOK_VERSION: 0.4.8
57      RUSTDOCFLAGS: -Dbroken_intra_doc_links --cfg nightlydoc
58      OPENVINO_SKIP_LINKING: 1
59    steps:
60    - uses: actions/checkout@v2
61      with:
62        submodules: true
63    - uses: ./.github/actions/install-rust
64      with:
65        toolchain: nightly-2021-12-15
66
67    # Build C API documentation
68    - run: sudo apt-get update -y && sudo apt-get install -y libclang1-9 libclang-cpp9
69    - run: curl -L https://www.doxygen.nl/files/doxygen-1.9.3.linux.bin.tar.gz | tar xzf -
70    - run: echo "`pwd`/doxygen-1.9.3/bin" >> $GITHUB_PATH
71    - run: cd crates/c-api && doxygen doxygen.conf
72
73    # install mdbook, build the docs, and test the docs
74    - uses: actions/cache@v2
75      with:
76        path: ${{ runner.tool_cache }}/mdbook
77        key: cargo-mdbook-bin-${{ env.CARGO_MDBOOK_VERSION }}
78    - run: |
79        echo "${{ runner.tool_cache }}/mdbook/bin" >> $GITHUB_PATH
80        cargo install --root ${{ runner.tool_cache }}/mdbook --version ${{ env.CARGO_MDBOOK_VERSION }} mdbook
81    - run: (cd docs && mdbook build)
82    - run: cargo build -p wasmtime-wasi --features wasmtime/wat,wasmtime/cranelift
83    - run: (cd docs/rust_wasi_markdown_parser && cargo build)
84    - run: (cd docs && mdbook test -L ../target/debug/deps,./rust_wasi_markdown_parser/target/debug/deps)
85
86    # Build Rust API documentation
87    - run: |
88        cargo doc --no-deps --workspace \
89          --exclude wasmtime-cli \
90          --exclude test-programs \
91          --exclude cranelift-codegen-meta
92    - run: cargo doc --package cranelift-codegen-meta --document-private-items
93
94    # Assemble the documentation, and always upload it as an artifact for
95    # inspection on PRs and such.
96    - run: |
97        mv docs/book gh-pages
98        mv crates/c-api/html gh-pages/c-api
99        mv target/doc gh-pages/api
100        tar czf gh-pages.tar.gz gh-pages
101    - uses: actions/upload-artifact@v2
102      with:
103        name: gh-pages
104        path: gh-pages.tar.gz
105
106    # If this is a push to the main branch push to the `gh-pages` using a
107    # deploy key. Note that a deploy key is necessary for now because otherwise
108    # using the default token for github actions doesn't actually trigger a page
109    # rebuild.
110    - name: Push to gh-pages
111      run: curl -LsSf https://git.io/fhJ8n | rustc - && (cd gh-pages && ../rust_out)
112      env:
113        GITHUB_DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
114        BUILD_REPOSITORY_ID: ${{ github.repository }}
115        BUILD_SOURCEVERSION: ${{ github.sha }}
116      if: github.event_name == 'push' && github.ref == 'refs/heads/main'
117
118  # Quick checks of various feature combinations and whether things
119  # compile. The goal here isn't to run tests, mostly just serve as a
120  # double-check that Rust code compiles and is likely to work everywhere else.
121  checks:
122    name: Check
123    runs-on: ubuntu-latest
124    steps:
125    - uses: actions/checkout@v2
126      with:
127        submodules: true
128    - uses: ./.github/actions/install-rust
129
130    # Check some feature combinations of the `wasmtime` crate
131    - run: cargo check -p wasmtime --no-default-features
132    - run: cargo check -p wasmtime --no-default-features --features wat
133    - run: cargo check -p wasmtime --no-default-features --features jitdump
134    - run: cargo check -p wasmtime --no-default-features --features vtune
135    - run: cargo check -p wasmtime --no-default-features --features cache
136    - run: cargo check -p wasmtime --no-default-features --features async
137    - run: cargo check -p wasmtime --no-default-features --features uffd
138    - run: cargo check -p wasmtime --no-default-features --features pooling-allocator
139    - run: cargo check -p wasmtime --no-default-features --features cranelift
140    - run: cargo check -p wasmtime --no-default-features --features wasm-backtrace
141    - run: cargo check -p wasmtime --no-default-features --features cranelift,wat,async,cache,wasm-backtrace
142
143    # Check that benchmarks of the cranelift project build
144    - run: cargo check --benches -p cranelift-codegen
145
146    # Check some feature combinations of the `wasmtime-c-api` crate
147    - run: cargo check -p wasmtime-c-api --no-default-features
148    - run: cargo check -p wasmtime-c-api --no-default-features --features wat
149    - run: cargo check -p wasmtime-c-api --no-default-features --features wasi
150
151    # Check a few builds of the cranelift backend
152    # - only x86 backend support,
153    # - only arm64 backend support,
154    # - no debug_assertions.
155    - run: cargo check --manifest-path=./cranelift/Cargo.toml --bin clif-util --no-default-features --features=cranelift-codegen/arm64
156    - run: cargo check --manifest-path=./cranelift/Cargo.toml --bin clif-util --no-default-features --features=cranelift-codegen/x86
157    - run: cargo check --manifest-path=./cranelift/Cargo.toml --bin clif-util
158      env:
159        CARGO_PROFILE_DEV_DEBUG_ASSERTIONS: false
160
161    # Check whether `crates/wasi-common` cross-compiles to the following targets:
162    # * wasm32-unknown-emscripten
163    # * armv7-unknown-linux-gnueabihf
164    - run: |
165        rustup target add wasm32-unknown-emscripten
166        rustup target add armv7-unknown-linux-gnueabihf
167        sudo apt-get update && sudo apt-get install -y gcc-arm-linux-gnueabihf
168    - run: cargo check --target wasm32-unknown-emscripten -p wasi-common
169    - run: cargo check --target armv7-unknown-linux-gnueabihf -p wasi-common
170
171  fuzz_targets:
172    name: Fuzz Targets
173    runs-on: ubuntu-latest
174    steps:
175    - uses: actions/checkout@v2
176      with:
177        submodules: true
178    # Note that building with fuzzers requires nightly since it uses unstable
179    # flags to rustc.
180    - uses: ./.github/actions/install-rust
181      with:
182        toolchain: nightly-2021-12-15
183    - run: cargo install cargo-fuzz --vers "^0.11"
184    # Install OCaml packages necessary for 'differential_spec' fuzz target.
185    - run: sudo apt install -y ocaml-nox ocamlbuild ocaml-findlib libzarith-ocaml-dev
186    - run: cargo fetch
187      working-directory: ./fuzz
188    - run: cargo fuzz build --dev
189    # Check that the ISLE fuzz targets build too.
190    - run: cargo fuzz build --dev --fuzz-dir ./cranelift/isle/fuzz
191
192  rebuild_isle:
193    name: Rebuild ISLE
194    runs-on: ubuntu-latest
195    steps:
196    - uses: actions/checkout@v2
197      with:
198        submodules: true
199    - uses: ./.github/actions/install-rust
200    - name: Rebuild ISLE DSL files
201      run: cargo build -p cranelift-codegen --features "rebuild-isle"
202    - name: Reformat
203      run: cargo fmt -p cranelift-codegen
204    - name: Check that the ISLE DSL files are up-to-date
205      run: git diff --exit-code
206
207  # Perform all tests (debug mode) for `wasmtime`. This runs stable/beta/nightly
208  # channels of Rust as well as macOS/Linux/Windows.
209  test:
210    name: Test
211    runs-on: ${{ matrix.os }}
212    env:
213      QEMU_BUILD_VERSION: 6.1.0
214    strategy:
215      matrix:
216        include:
217          - os: ubuntu-latest
218          - os: macos-latest
219          - os: windows-2019
220          - os: windows-2019
221            target: x86_64-pc-windows-gnu
222          - os: ubuntu-latest
223            target: aarch64-unknown-linux-gnu
224            gcc_package: gcc-aarch64-linux-gnu
225            gcc: aarch64-linux-gnu-gcc
226            qemu: qemu-aarch64 -L /usr/aarch64-linux-gnu
227            qemu_target: aarch64-linux-user
228            # FIXME(#3183) shouldn't be necessary to specify this
229            qemu_flags: -cpu max,pauth=off
230          - os: ubuntu-latest
231            target: s390x-unknown-linux-gnu
232            gcc_package: gcc-s390x-linux-gnu
233            gcc: s390x-linux-gnu-gcc
234            qemu: qemu-s390x -L /usr/s390x-linux-gnu
235            qemu_target: s390x-linux-user
236    steps:
237    - uses: actions/checkout@v2
238      with:
239        submodules: true
240    - uses: ./.github/actions/install-rust
241
242    # Install targets in order to build various tests throughout the repo
243    - run: rustup target add wasm32-wasi wasm32-unknown-unknown ${{ matrix.target }}
244    - run: echo CARGO_BUILD_TARGET=${{ matrix.target }} >> $GITHUB_ENV
245      if: matrix.target != ''
246
247    # Fix an ICE for now in gcc when compiling zstd with debuginfo (??)
248    - run: echo CFLAGS=-g0 >> $GITHUB_ENV
249      if: matrix.target == 'x86_64-pc-windows-gnu'
250
251    - run: cargo fetch --locked
252    - run: cargo fetch --locked --manifest-path crates/test-programs/wasi-tests/Cargo.toml
253
254    - uses: actions/cache@v2
255      with:
256        path: ${{ runner.tool_cache }}/qemu
257        key: qemu-${{ matrix.target }}-${{ env.QEMU_BUILD_VERSION }}-patchmadvise2
258      if: matrix.target != '' && matrix.os == 'ubuntu-latest'
259    - name: Install cross-compilation tools
260      run: |
261        set -ex
262        sudo apt-get update
263        sudo apt-get install -y ${{ matrix.gcc_package }} ninja-build
264
265        # Configure Cargo for cross compilation and tell it how it can run
266        # cross executables
267        upcase=$(echo ${{ matrix.target }} | awk '{ print toupper($0) }' | sed 's/-/_/g')
268        echo CARGO_TARGET_${upcase}_RUNNER=${{ runner.tool_cache }}/qemu/bin/${{ matrix.qemu }} ${{ matrix.qemu_flags }} >> $GITHUB_ENV
269        echo CARGO_TARGET_${upcase}_LINKER=${{ matrix.gcc }} >> $GITHUB_ENV
270
271        # QEMU emulation is not always the speediest, so total testing time
272        # goes down if we build the libs in release mode when running tests.
273        echo CARGO_PROFILE_DEV_OPT_LEVEL=2 >> $GITHUB_ENV
274
275        # See comments in the source for why we enable this during QEMU
276        # emulation.
277        echo WASMTIME_TEST_NO_HOG_MEMORY=1 >> $GITHUB_ENV
278
279        # See if qemu is already in the cache
280        if [ -f ${{ runner.tool_cache }}/qemu/built ]; then
281          exit 0
282        fi
283
284        # Download and build qemu from source since the most recent release is
285        # way faster at arm emulation than the current version github actions'
286        # ubuntu image uses. Disable as much as we can to get it to build
287        # quickly.
288        curl https://download.qemu.org/qemu-$QEMU_BUILD_VERSION.tar.xz | tar xJf -
289        cd qemu-$QEMU_BUILD_VERSION
290        patch -p1 < $GITHUB_WORKSPACE/ci/qemu-madvise.patch
291        ./configure --target-list=${{ matrix.qemu_target }} --prefix=${{ runner.tool_cache}}/qemu --disable-tools --disable-slirp --disable-fdt --disable-capstone --disable-docs
292        ninja -C build install
293        touch ${{ runner.tool_cache }}/qemu/built
294      if: matrix.gcc != ''
295
296    # Ensure all our examples build and execute
297    - run: cargo run -p run-examples
298      env:
299        RUST_BACKTRACE: 1
300      if: matrix.target == ''
301
302    # Build and test all features
303    - run: ./ci/run-tests.sh --locked
304      env:
305        RUST_BACKTRACE: 1
306
307    # Test debug (DWARF) related functionality.
308    - run: |
309        sudo apt-get update && sudo apt-get install -y gdb lldb llvm
310        cargo test test_debug_dwarf -- --ignored --test-threads 1
311      if: matrix.os == 'ubuntu-latest' && matrix.target == ''
312      env:
313        RUST_BACKTRACE: 1
314
315    # Test Linux-specific functionality
316    - run: |
317        cargo test --features uffd -p wasmtime-runtime instance::allocator::pooling
318        cargo test --features uffd -p wasmtime-cli pooling_allocator
319        cargo test --features uffd -p wasmtime-cli wast::Cranelift
320      if: matrix.os == 'ubuntu-latest' && matrix.target == ''
321      env:
322        RUST_BACKTRACE: 1
323
324  # Build and test the wasi-nn module.
325  test_wasi_nn:
326    name: Test wasi-nn module
327    runs-on: ubuntu-latest
328    steps:
329      - uses: actions/checkout@v2
330        with:
331          submodules: true
332      - uses: ./.github/actions/install-rust
333      - run: rustup target add wasm32-wasi
334      - uses: ./.github/actions/install-openvino
335      - run: ./ci/run-wasi-nn-example.sh
336        env:
337          RUST_BACKTRACE: 1
338
339  # Build and test the wasi-crypto module.
340  test_wasi_crypto:
341    name: Test wasi-crypto module
342    runs-on: ubuntu-latest
343    steps:
344    - uses: actions/checkout@v2
345      with:
346        submodules: true
347    - run: rustup target add wasm32-wasi
348    - name: Install Rust
349      run: rustup update stable && rustup default stable
350    - run: ./ci/run-wasi-crypto-example.sh
351      env:
352        RUST_BACKTRACE: 1
353
354  bench:
355    name: Run benchmarks
356    runs-on: ubuntu-latest
357    steps:
358    - uses: actions/checkout@v2
359      with:
360        submodules: true
361    - run: rustup target add wasm32-wasi
362    - name: Install Rust
363      run: rustup update stable && rustup default stable
364    - run: cargo test --benches --release
365    - run: cargo test --benches --release --features uffd
366
367  # Verify that cranelift's code generation is deterministic
368  meta_determinist_check:
369    name: Meta deterministic check
370    runs-on: ubuntu-latest
371    steps:
372    - uses: actions/checkout@v2
373      with:
374        submodules: true
375    - name: Install Rust
376      run: rustup update stable && rustup default stable
377    - run: cd cranelift/codegen && cargo build --features "all-arch completely-skip-isle-for-ci-deterministic-check"
378    - run: ci/ensure_deterministic_build.sh
379
380  # Perform release builds of `wasmtime` and `libwasmtime.so`. Builds on
381  # Windows/Mac/Linux, and artifacts are uploaded after the build is finished.
382  # Note that we also run tests here to test exactly what we're deploying.
383  build:
384    name: Build wasmtime
385    runs-on: ${{ matrix.os }}
386    strategy:
387      matrix:
388        include:
389        - build: x86_64-linux
390          os: ubuntu-latest
391        - build: x86_64-macos
392          os: macos-latest
393        - build: x86_64-windows
394          os: windows-latest
395        - build: x86_64-mingw
396          os: windows-latest
397          target: x86_64-pc-windows-gnu
398        - build: aarch64-linux
399          os: ubuntu-latest
400          target: aarch64-unknown-linux-gnu
401          gcc_package: gcc-aarch64-linux-gnu
402          gcc: aarch64-linux-gnu-gcc
403        - build: s390x-linux
404          os: ubuntu-latest
405          target: s390x-unknown-linux-gnu
406          gcc_package: gcc-s390x-linux-gnu
407          gcc: s390x-linux-gnu-gcc
408    steps:
409    - uses: actions/checkout@v2
410      with:
411        submodules: true
412    - uses: ./.github/actions/install-rust
413    - uses: ./.github/actions/binary-compatible-builds
414      if: matrix.target == ''
415
416    - name: Install cross-compilation tools
417      run: |
418        set -ex
419        sudo apt-get update
420        sudo apt-get install -y ${{ matrix.gcc_package }}
421        upcase=$(echo ${{ matrix.target }} | awk '{ print toupper($0) }' | sed 's/-/_/g')
422        echo CARGO_TARGET_${upcase}_LINKER=${{ matrix.gcc }} >> $GITHUB_ENV
423      if: matrix.target != '' && matrix.os == 'ubuntu-latest'
424    - run: |
425        echo CARGO_BUILD_TARGET=${{ matrix.target }} >> $GITHUB_ENV
426        rustup target add ${{ matrix.target }}
427      if: matrix.target != ''
428
429    # Build `wasmtime` and executables
430    - run: $CENTOS cargo build --release --bin wasmtime
431
432    # Build `libwasmtime.so`
433    - run: $CENTOS cargo build --release --manifest-path crates/c-api/Cargo.toml
434
435    # Assemble release artifats appropriate for this platform, then upload them
436    # unconditionally to this workflow's files so we have a copy of them.
437    - run: ./ci/build-tarballs.sh "${{ matrix.build }}" "${{ matrix.target }}"
438    - uses: actions/upload-artifact@v1
439      with:
440        name: bins-${{ matrix.build }}
441        path: dist
442
443    # ... and if this was an actual push (tag or `main`) then we publish a
444    # new release. This'll automatically publish a tag release or update `dev`
445    # with this `sha`. Note that `continue-on-error` is set here so if this hits
446    # a bug we can go back and fetch and upload the release ourselves.
447    - run: cd .github/actions/github-release && npm install --production
448    - name: Publish Release
449      uses: ./.github/actions/github-release
450      if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
451      with:
452        files: "dist/*"
453        token: ${{ secrets.GITHUB_TOKEN }}
454      continue-on-error: true
455
456  verify-publish:
457    runs-on: ubuntu-latest
458    steps:
459    - uses: actions/checkout@v2
460      with:
461        submodules: true
462    - run: rustup update stable && rustup default stable
463    - run: |
464        cd ${{ runner.tool_cache }}
465        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 -
466        echo "`pwd`/sccache-0.2.13-x86_64-unknown-linux-musl" >> $GITHUB_PATH
467        echo RUSTC_WRAPPER=sccache >> $GITHUB_ENV
468    - run: |
469        rustc scripts/publish.rs
470        ./publish verify
471