1name: CI
2on:
3  # Run CI for PRs to `main` and to release branches.
4  #
5  # Note that PRs to `main` will run a subset of tests and PRs to the
6  # `release-*` branches will run full CI.
7  pull_request:
8    branches:
9    - main
10    - 'release-*'
11
12  # Run full CI on the `main` branch once a day to prime the GitHub Actions
13  # caches used by PRs and the merge queue.
14  schedule:
15  - cron: '13 4 * * *'
16
17  # This is the CI that runs for PRs-to-merge.
18  merge_group:
19
20  push:
21    branches:
22    # Right now merge queues can't be used with wildcards in branch protections
23    # so full CI runs both on PRs to release branches as well as merges to
24    # release branches. Note that the merge to a release branch may produce a
25    # tag at the end of CI if successful and the tag will trigger the artifact
26    # uploads as well as publication to crates.io.
27    - 'release-*'
28
29defaults:
30  run:
31    shell: bash
32
33# Cancel any in-flight jobs for the same PR/branch so there's only one active
34# at a time
35concurrency:
36  group: ${{ github.workflow }}-${{ github.ref }}
37  cancel-in-progress: true
38
39jobs:
40  # Check Code style quickly by running `rustfmt` over all code
41  rustfmt:
42    name: Rustfmt
43    runs-on: ubuntu-latest
44    steps:
45    - uses: actions/checkout@v4
46      with:
47        submodules: true
48    - uses: ./.github/actions/install-rust
49    - run: rustup component add rustfmt
50    - run: cargo fmt --all -- --check
51
52    # common logic to cancel the entire run if this job fails
53    - run: gh run cancel ${{ github.run_id }}
54      if: failure() && github.event_name != 'pull_request'
55      env:
56        GH_TOKEN: ${{ github.token }}
57
58  # Quick JS formatting/linting checks for the little bits of JS we have for the
59  # `wasmtime explore` UI.
60  check_js:
61    name: Check JS
62    runs-on: ubuntu-latest
63    steps:
64    - uses: actions/checkout@v4
65    - run: npm install
66      working-directory: ./crates/explorer
67    - run: npm run lint
68      working-directory: ./crates/explorer
69    - run: npm run fmt-check
70      working-directory: ./crates/explorer
71
72    # common logic to cancel the entire run if this job fails
73    - run: gh run cancel ${{ github.run_id }}
74      if: failure() && github.event_name != 'pull_request'
75      env:
76        GH_TOKEN: ${{ github.token }}
77
78  # Check Code style quickly by running `clang-format` over all the C/C++ code
79  #
80  # Note that `wasmtime-platform.h` is excluded here as it's auto-generated.
81  clangformat:
82    name: Clang format
83    runs-on: ubuntu-latest
84    steps:
85    - uses: actions/checkout@v4
86      with:
87        submodules: true
88    - run: |
89        git ls-files '*.h' '*.c' '*.cpp' | \
90          grep -v wasmtime-platform.h | \
91          grep -v wasm.h | \
92          xargs clang-format-15 --dry-run --Werror --verbose
93
94    # common logic to cancel the entire run if this job fails
95    - run: gh run cancel ${{ github.run_id }}
96      if: failure() && github.event_name != 'pull_request'
97      env:
98        GH_TOKEN: ${{ github.token }}
99
100  # Lint dependency graph for security advisories, duplicate versions, and
101  # incompatible licences
102  cargo_deny:
103    name: Cargo deny
104    needs: determine
105    if: needs.determine.outputs.audit
106    runs-on: ubuntu-latest
107    steps:
108    - uses: actions/checkout@v4
109      with:
110        submodules: true
111    - uses: ./.github/actions/install-rust
112    - run: |
113        set -e
114        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 -
115        mv cargo-deny-*-x86_64-unknown-linux-musl/cargo-deny cargo-deny
116        echo `pwd` >> $GITHUB_PATH
117    - run: cargo deny check bans licenses
118
119    # common logic to cancel the entire run if this job fails
120    - run: gh run cancel ${{ github.run_id }}
121      if: failure() && github.event_name != 'pull_request'
122      env:
123        GH_TOKEN: ${{ github.token }}
124
125  # Ensure dependencies are vetted. See https://mozilla.github.io/cargo-vet/
126  #
127  # Note that this step, on PRs only, is allowed to fail. This is then followed
128  # up with the `cargo_vet_failure_for_prs` step below. The intention is to
129  # avoid causing this check to fail PRs while still enabling it to fail the
130  # merge queue checks. That way PRs can enter the merge queue when this step is
131  # failing if `main` has picked up `cargo vet` entries in the meantime for the
132  # failures.
133  cargo_vet:
134    name: Cargo vet
135    needs: determine
136    if: needs.determine.outputs.audit
137    runs-on: ubuntu-latest
138    outputs:
139      outcome: ${{ steps.vet.outcome }}
140    steps:
141    - uses: actions/checkout@v4
142      with:
143        submodules: true
144    - uses: ./.github/actions/install-rust
145    - uses: ./.github/actions/install-cargo-vet
146    - id: vet
147      run: cargo vet --locked
148      continue-on-error: ${{ github.event_name == 'pull_request' }}
149
150    # common logic to cancel the entire run if this job fails
151    - run: gh run cancel ${{ github.run_id }}
152      if: failure() && github.event_name != 'pull_request'
153      env:
154        GH_TOKEN: ${{ github.token }}
155
156  cargo_vet_failure_for_prs:
157    name: Cargo vet failed on a Pull Request
158    needs:
159    - determine
160    - cargo_vet
161    if: |
162      needs.determine.outputs.audit
163      && github.event_name == 'pull_request'
164      && needs.cargo_vet.outputs.outcome == 'failure'
165    runs-on: ubuntu-latest
166    steps:
167    # NB: this message ideally would link back to the previous step, but I'm not
168    # sure how to easily do that.
169    - run: |
170        echo 'failed to run "cargo vet", see previous `Cargo vet` step'
171        echo 'exiting with a nonzero status now to alert PR authors'
172        echo 'note, though, that this PR can still enter the merge queue'
173        echo ''
174        echo 'See https://docs.wasmtime.dev/contributing-coding-guidelines.html#cargo-vet-for-contributors'
175        echo 'for more information about the vetting process for Wasmtime'
176        exit 1
177
178  # This job is a dependency of many of the jobs below. This calculates what's
179  # actually being run for this workflow. For example:
180  #
181  # * Pushes to branches, which is currently both pushes to merge queue branches
182  #   as well as release branches, perform full CI.
183  # * PRs to release branches (not `main`) run full CI.
184  # * PRs to `main` will only run a few smoke tests above plus some elements of
185  #   the test matrix. The test matrix here is determined dynamically by the
186  #   `./ci/build-test-matrix.js` script given the commits that happened and
187  #   the files modified.
188  determine:
189    name: Determine CI jobs to run
190    runs-on: ubuntu-latest
191    outputs:
192      run-full: ${{ steps.calculate.outputs.run-full }}
193      test-matrix: ${{ steps.calculate.outputs.test-matrix }}
194      build-matrix: ${{ steps.calculate.outputs.build-matrix }}
195      test-capi: ${{ steps.calculate.outputs.test-capi }}
196      test-nightly: ${{ steps.calculate.outputs.test-nightly }}
197      audit: ${{ steps.calculate.outputs.audit }}
198      preview1-adapter: ${{ steps.calculate.outputs.preview1-adapter }}
199      run-dwarf: ${{ steps.calculate.outputs.run-dwarf }}
200      run-wasi-keyvalue: ${{ steps.calculate.outputs.run-wasi-keyvalue }}
201    steps:
202    - uses: actions/checkout@v4
203    - id: calculate
204      env:
205        GH_TOKEN: ${{ github.token }}
206      run: |
207        touch commits.log names.log
208        # Note that CI doesn't run on pushes to `main`, only pushes to merge
209        # queue branches and release branches, so this only runs full CI in
210        # those locations.
211        if [ "${{ github.event_name }}" != "pull_request" ]; then
212          run_full=true
213        else
214          pr=${{ github.event.number }}
215          gh pr view $pr --json commits | tee commits.log
216          gh pr diff $pr --name-only | tee names.log || echo "failed to get files"
217          if [ "${{ github.base_ref }}" != "main" ]; then
218            run_full=true
219          elif grep -q 'prtest:full' commits.log; then
220            run_full=true
221          elif grep -q 'prtest:debug' commits.log; then
222            echo run-dwarf=true >> $GITHUB_OUTPUT
223          fi
224          if grep -q crates.c-api names.log; then
225            echo test-capi=true >> $GITHUB_OUTPUT
226          fi
227          if grep -q fuzz names.log; then
228            echo test-nightly=true >> $GITHUB_OUTPUT
229          fi
230          if grep -q sys.custom names.log; then
231            echo test-nightly=true >> $GITHUB_OUTPUT
232          fi
233          if grep -q Cargo.lock names.log; then
234            echo audit=true >> $GITHUB_OUTPUT
235          fi
236          if grep -q supply-chain names.log; then
237            echo audit=true >> $GITHUB_OUTPUT
238          fi
239          if grep -q component-adapter names.log; then
240            echo preview1-adapter=true >> $GITHUB_OUTPUT
241          fi
242          if grep -q debug names.log; then
243            echo run-dwarf=true >> $GITHUB_OUTPUT
244          fi
245          if grep -q wasi-keyvalue names.log; then
246            echo run-wasi-keyvalue=true >> $GITHUB_OUTPUT
247          fi
248        fi
249        matrix="$(node ./ci/build-test-matrix.js ./commits.log ./names.log $run_full)"
250        echo "test-matrix={\"include\":$(echo $matrix)}" >> $GITHUB_OUTPUT
251        echo "$matrix"
252
253        matrix="$(node ./ci/build-build-matrix.js)"
254        echo "build-matrix={\"include\":$(echo $matrix)}" >> $GITHUB_OUTPUT
255
256        if [ "$run_full" = "true" ]; then
257            echo run-full=true >> $GITHUB_OUTPUT
258            echo test-capi=true >> $GITHUB_OUTPUT
259            echo test-nightly=true >> $GITHUB_OUTPUT
260            echo audit=true >> $GITHUB_OUTPUT
261            echo preview1-adapter=true >> $GITHUB_OUTPUT
262            echo run-dwarf=true >> $GITHUB_OUTPUT
263            echo run-wasi-keyvalue=true >> $GITHUB_OUTPUT
264        fi
265
266  # Build all documentation of Wasmtime, including the C API documentation,
267  # mdbook documentation, etc. This produces a `gh-pages` artifact which is what
268  # gets uploaded to the `gh-pages` branch later on.
269  doc:
270    needs: determine
271    if: needs.determine.outputs.run-full
272    name: Doc build
273    runs-on: ubuntu-latest
274    env:
275      CARGO_MDBOOK_VERSION: 0.4.37
276      RUSTDOCFLAGS: -Dbroken_intra_doc_links --cfg docsrs
277      OPENVINO_SKIP_LINKING: 1
278    steps:
279    - uses: actions/checkout@v4
280      with:
281        submodules: true
282    - uses: ./.github/actions/install-rust
283      with:
284        toolchain: wasmtime-ci-pinned-nightly
285
286    # Build C API documentation
287    - run: curl -L https://sourceforge.net/projects/doxygen/files/rel-1.9.3/doxygen-1.9.3.linux.bin.tar.gz/download | tar xzf -
288    - run: echo "`pwd`/doxygen-1.9.3/bin" >> $GITHUB_PATH
289    - run: cmake -S crates/c-api -B target/c-api
290    - run: cmake --build target/c-api --target doc
291
292    # install mdbook, build the docs, and test the docs
293    - uses: actions/cache@v4
294      with:
295        path: ${{ runner.tool_cache }}/mdbook
296        key: cargo-mdbook-bin-${{ env.CARGO_MDBOOK_VERSION }}
297    - run: |
298        echo "${{ runner.tool_cache }}/mdbook/bin" >> $GITHUB_PATH
299        cargo install --root ${{ runner.tool_cache }}/mdbook --version ${{ env.CARGO_MDBOOK_VERSION }} mdbook --locked
300    - run: (cd docs && mdbook build)
301    - run: cargo build -p wasi-common --features wasmtime/wat,wasmtime/cranelift
302    - run: (cd docs && mdbook test -L ../target/debug/deps)
303
304    # Build Rust API documentation.
305    #
306    # Enable extra features in crates as well to ensure they're documented
307    - run: |
308        cargo doc --no-deps --workspace \
309          --exclude wasmtime-cli \
310          --exclude test-programs \
311          --exclude cranelift-codegen-meta \
312          --features call-hook
313      env:
314        RUSTDOCFLAGS: --cfg=docsrs
315    - run: cargo doc --package cranelift-codegen-meta --document-private-items
316      env:
317        RUSTDOCFLAGS: --cfg=docsrs
318
319    # Assemble the documentation, and always upload it as an artifact for
320    # inspection on PRs and such.
321    - run: |
322        mv docs/book gh-pages
323        mv crates/c-api/html gh-pages/c-api
324        mv target/doc gh-pages/api
325        tar czf gh-pages.tar.gz gh-pages
326    - uses: actions/upload-artifact@v4
327      with:
328        name: gh-pages
329        path: gh-pages.tar.gz
330
331    # common logic to cancel the entire run if this job fails
332    - run: gh run cancel ${{ github.run_id }}
333      if: failure() && github.event_name != 'pull_request'
334      env:
335        GH_TOKEN: ${{ github.token }}
336
337  # Checks of various feature combinations and whether things compile. The goal
338  # here isn't to run tests, mostly just serve as a double-check that Rust code
339  # compiles and is likely to work everywhere else.
340  micro_checks:
341    needs: determine
342    name: Check ${{matrix.name}}
343    strategy:
344      fail-fast: true
345      matrix:
346        include:
347          - name: wasmtime
348            checks: |
349              -p wasmtime --no-default-features
350              -p wasmtime --no-default-features --features wat
351              -p wasmtime --no-default-features --features profiling
352              -p wasmtime --no-default-features --features cache
353              -p wasmtime --no-default-features --features async
354              -p wasmtime --no-default-features --features pooling-allocator
355              -p wasmtime --no-default-features --features cranelift
356              -p wasmtime --no-default-features --features component-model
357              -p wasmtime --no-default-features --features runtime,component-model
358              -p wasmtime --no-default-features --features cranelift,wat,async,cache
359              -p wasmtime --no-default-features --features winch
360              -p wasmtime --no-default-features --features wmemcheck
361              -p wasmtime --no-default-features --features wmemcheck,cranelift,runtime
362              -p wasmtime --no-default-features --features demangle
363              -p wasmtime --no-default-features --features addr2line
364              -p wasmtime --no-default-features --features gc
365              -p wasmtime --no-default-features --features runtime,gc
366              -p wasmtime --no-default-features --features cranelift,gc
367              -p wasmtime --no-default-features --features runtime
368              -p wasmtime --no-default-features --features threads
369              -p wasmtime --no-default-features --features runtime,threads
370              -p wasmtime --no-default-features --features cranelift,threads
371              -p wasmtime --features incremental-cache
372              -p wasmtime --all-features
373
374          - name: wasmtime-cli
375            checks: |
376              -p wasmtime-cli --no-default-features
377              -p wasmtime-cli --no-default-features --features pooling-allocator
378              -p wasmtime-cli --no-default-features --features run
379              -p wasmtime-cli --no-default-features --features run,component-model
380              -p wasmtime-cli --no-default-features --features run,pooling-allocator
381              -p wasmtime-cli --no-default-features --features compile
382              -p wasmtime-cli --no-default-features --features compile,cranelift
383              -p wasmtime-cli --no-default-features --features compile,cranelift,component-model
384              -p wasmtime-cli --all-features
385              -p wasmtime-cli --features component-model
386
387          - name: cranelift-codegen benches
388            checks: |
389              --benches -p cranelift-codegen
390
391          - name: wasmtime-bench-api
392            checks: |
393              -p wasmtime-bench-api
394
395          - name: wasmtime-c-api
396            checks: |
397              -p wasmtime-c-api --no-default-features
398              -p wasmtime-c-api --no-default-features --features wat
399              -p wasmtime-c-api --no-default-features --features wasi
400    runs-on: ubuntu-latest
401    steps:
402    - uses: actions/checkout@v4
403      with:
404        submodules: true
405    - uses: ./.github/actions/install-rust
406
407    # Run the check.
408    - run: |
409        checks=$(cat <<END
410        ${{ matrix.checks }}
411        END
412        )
413        echo "$checks" | xargs -I CHECK sh -c 'echo "=== cargo check CHECK ==="; cargo check CHECK'
414
415    # Common logic to cancel the entire run if this job fails.
416    - run: gh run cancel ${{ github.run_id }}
417      if: failure() && github.event_name != 'pull_request'
418      env:
419        GH_TOKEN: ${{ github.token }}
420
421  # Similar to `micro_checks` but where we need to install some more state
422  # (e.g. Android NDK) and we haven't factored support for those things out into
423  # a parallel jobs yet.
424  monolith_checks:
425    needs: determine
426    name: Monolith Checks
427    runs-on: ubuntu-latest
428    env:
429      CARGO_NDK_VERSION: 2.12.2
430    steps:
431    - uses: actions/checkout@v4
432      with:
433        submodules: true
434    - uses: ./.github/actions/install-rust
435
436    # Checks for no_std support, ensure that crates can build on a no_std
437    # target
438    - run: rustup target add x86_64-unknown-none
439    - run: cargo check --target x86_64-unknown-none -p wasmtime --no-default-features --features runtime,gc,component-model
440    - run: cargo check --target x86_64-unknown-none -p cranelift-control --no-default-features
441    - run: cargo check --target x86_64-unknown-none -p pulley-interpreter --features encode,decode,disas,interp
442
443    # Check that wasmtime compiles with panic=abort since there's some `#[cfg]`
444    # for specifically panic=abort there.
445    - run: cargo check -p wasmtime
446      env:
447        RUSTFLAGS: -Cpanic=abort
448
449    # Check a few builds of the cranelift backend
450    # - only x86 backend support,
451    # - only arm64 backend support,
452    # - no debug_assertions.
453    - run: cargo check --manifest-path=./cranelift/Cargo.toml --bin clif-util --no-default-features --features=cranelift-codegen/arm64
454    - run: cargo check --manifest-path=./cranelift/Cargo.toml --bin clif-util --no-default-features --features=cranelift-codegen/x86
455    - run: cargo check --manifest-path=./cranelift/Cargo.toml --bin clif-util
456      env:
457        CARGO_PROFILE_DEV_DEBUG_ASSERTIONS: false
458
459    # Check whether `wasmtime` cross-compiles to x86_64-unknown-freebsd
460    # TODO: We aren't building with default features since the `ittapi` crate fails to compile on freebsd.
461    - run: rustup target add x86_64-unknown-freebsd
462    - run: cargo check -p wasmtime --no-default-features --features cranelift,wat,async,cache --target x86_64-unknown-freebsd
463
464    # Run clippy configuration
465    - run: rustup component add clippy
466    - run: cargo clippy --workspace
467
468    # Re-vendor all WIT files and ensure that they're all up-to-date by ensuring
469    # that there's no git changes.
470    - name: Re-vendor WIT
471      run: ./ci/vendor-wit.sh
472    - run: git diff --exit-code
473
474    # Re-vendor the C API and make sure it's up-to-date.
475    - name: Re-vendor C API
476      run: ./ci/vendor-c-api-headers.sh
477    - run: git diff --exit-code
478
479    # common logic to cancel the entire run if this job fails
480    - run: gh run cancel ${{ github.run_id }}
481      if: failure() && github.event_name != 'pull_request'
482      env:
483        GH_TOKEN: ${{ github.token }}
484
485  # Check whether `wasmtime` cross-compiles to aarch64-pc-windows-msvc
486  # We don't build nor test it because it lacks trap handling.
487  # Tracking issue: https://github.com/bytecodealliance/wasmtime/issues/4992
488  checks_winarm64:
489    needs: determine
490    if: needs.determine.outputs.run-full
491    name: Check Windows ARM64
492    runs-on: windows-latest
493    steps:
494    - uses: actions/checkout@v4
495      with:
496        submodules: true
497    - uses: ./.github/actions/install-rust
498    - run: rustup target add aarch64-pc-windows-msvc
499    - run: cargo check -p wasmtime --target aarch64-pc-windows-msvc
500
501    # common logic to cancel the entire run if this job fails
502    - run: gh run cancel ${{ github.run_id }}
503      if: failure() && github.event_name != 'pull_request'
504      env:
505        GH_TOKEN: ${{ github.token }}
506
507  # Run tests that require a nightly compiler, such as building fuzz targets.
508  test_nightly:
509    needs: determine
510    if: needs.determine.outputs.test-nightly
511    name: Nightly tests
512    runs-on: ubuntu-latest
513    steps:
514    - uses: actions/checkout@v4
515      with:
516        submodules: true
517    # Note that nightly is pinned here to insulate us from breakage that might
518    # happen upstream. This is periodically updated through a PR.
519    - uses: ./.github/actions/install-rust
520      with:
521        toolchain: wasmtime-ci-pinned-nightly
522
523    # Ensure that fuzzers still build.
524    #
525    # Install the OCaml packages necessary for fuzz targets that use the
526    # `wasm-spec-interpreter`.
527    - run: cargo install cargo-fuzz --vers "^0.11" --locked
528    - run: sudo apt-get update && sudo apt install -y ocaml-nox ocamlbuild ocaml-findlib libzarith-ocaml-dev
529    - run: cargo fetch
530      working-directory: ./fuzz
531    - run: cargo fuzz build --dev -s none
532    - run: cargo fuzz build --dev -s none --fuzz-dir ./cranelift/isle/fuzz
533    - run: cargo fuzz build --dev -s none --fuzz-dir ./crates/environ/fuzz --features component-model
534
535    # common logic to cancel the entire run if this job fails
536    - run: gh run cancel ${{ github.run_id }}
537      if: failure() && github.event_name != 'pull_request'
538      env:
539        GH_TOKEN: ${{ github.token }}
540
541  # Perform all tests of the c-api
542  test_capi:
543    needs: determine
544    name: Test C-API ${{ matrix.os }}
545    runs-on: ${{ matrix.os }}
546    if: needs.determine.outputs.test-capi
547
548    strategy:
549      fail-fast: true
550      matrix:
551        os: [ubuntu-latest, macos-latest, windows-latest]
552
553    steps:
554    - uses: actions/checkout@v4
555      with:
556        submodules: true
557    - uses: ./.github/actions/install-rust
558
559    # Build and test the C API with example C programs along with the example
560    # Rust programs. Note that this only executes if the `determine` step told
561    # us to test the capi which is off-by-default for PRs.
562    - run: cmake -Sexamples -Bexamples/build -DBUILD_SHARED_LIBS=OFF
563    - run: cmake --build examples/build --config Debug
564    - run: cmake -E env CTEST_OUTPUT_ON_FAILURE=1 cmake --build examples/build --config Debug --target RUN_TESTS
565      env:
566        RUST_BACKTRACE: 1
567      if: matrix.os == 'windows-latest'
568    - run: cmake -E env CTEST_OUTPUT_ON_FAILURE=1 cmake --build examples/build --config Debug --target test
569      env:
570        RUST_BACKTRACE: 1
571      if: matrix.os != 'windows-latest'
572
573  # Perform all tests (debug mode) for `wasmtime`.
574  #
575  # Note that the full matrix for what may run here is defined within
576  # `./ci/build-test-matrix.js` and the execution of the `determine` step will
577  # calculate whether the tests are actually run as part of PRs and such.
578  test:
579    needs: determine
580    name: ${{ matrix.name }}
581    runs-on: ${{ matrix.os }}
582    env:
583      QEMU_BUILD_VERSION: 8.1.5
584    strategy:
585      fail-fast: ${{ github.event_name != 'pull_request' }}
586      matrix: ${{ fromJson(needs.determine.outputs.test-matrix) }}
587    steps:
588    - uses: actions/checkout@v4
589      with:
590        submodules: true
591    - uses: ./.github/actions/install-rust
592      with:
593        toolchain: ${{ matrix.rust }}
594
595    # Install targets in order to build various tests throughout the repo
596    - run: rustup target add wasm32-wasip1 wasm32-unknown-unknown ${{ matrix.target }}
597    - run: echo CARGO_BUILD_TARGET=${{ matrix.target }} >> $GITHUB_ENV
598      if: matrix.target != ''
599
600    # Fix an ICE for now in gcc when compiling zstd with debuginfo (??)
601    - run: echo CFLAGS=-g0 >> $GITHUB_ENV
602      if: matrix.target == 'x86_64-pc-windows-gnu'
603
604    # Update binutils if MinGW due to https://github.com/rust-lang/rust/issues/112368
605    - run: C:/msys64/usr/bin/pacman.exe -S --needed mingw-w64-x86_64-gcc --noconfirm
606      if: matrix.target == 'x86_64-pc-windows-gnu'
607    - shell: pwsh
608      run: echo "C:\msys64\mingw64\bin" >> $Env:GITHUB_PATH
609      if: matrix.target == 'x86_64-pc-windows-gnu'
610
611    - run: cargo fetch --locked
612
613    - name: Install cross-compilation tools
614      run: |
615        set -ex
616
617        sudo apt-get update
618        sudo apt-get install -y ${{ matrix.gcc_package }} ninja-build
619
620        # Configure Cargo for cross compilation and tell it how it can run
621        # cross executables
622        upcase=$(echo ${{ matrix.target }} | awk '{ print toupper($0) }' | sed 's/-/_/g')
623        echo CARGO_TARGET_${upcase}_LINKER=${{ matrix.gcc }} >> $GITHUB_ENV
624      if: matrix.gcc != ''
625
626    - uses: actions/cache@v4
627      with:
628        path: ${{ runner.tool_cache }}/qemu
629        key: qemu-${{ matrix.target }}-${{ env.QEMU_BUILD_VERSION }}-patchcpuinfo
630      if: matrix.qemu != ''
631    - name: Install qemu
632      run: |
633        set -ex
634
635        upcase=$(echo ${{ matrix.target }} | awk '{ print toupper($0) }' | sed 's/-/_/g')
636        echo CARGO_TARGET_${upcase}_RUNNER=${{ runner.tool_cache }}/qemu/bin/${{ matrix.qemu }} >> $GITHUB_ENV
637
638        # QEMU emulation is not always the speediest, so total testing time
639        # goes down if we build the libs in release mode when running tests.
640        echo CARGO_PROFILE_DEV_OPT_LEVEL=2 >> $GITHUB_ENV
641
642        # See comments in the source for why we enable this during QEMU
643        # emulation.
644        echo WASMTIME_TEST_NO_HOG_MEMORY=1 >> $GITHUB_ENV
645
646        # See if qemu is already in the cache
647        if [ -f ${{ runner.tool_cache }}/qemu/built ]; then
648          exit 0
649        fi
650
651        # Download and build qemu from source since the most recent release is
652        # way faster at arm emulation than the current version github actions'
653        # ubuntu image uses. Disable as much as we can to get it to build
654        # quickly.
655        curl https://download.qemu.org/qemu-$QEMU_BUILD_VERSION.tar.xz | tar xJf -
656        cd qemu-$QEMU_BUILD_VERSION
657        ./configure --target-list=${{ matrix.qemu_target }} --prefix=${{ runner.tool_cache}}/qemu --disable-tools --disable-slirp --disable-fdt --disable-capstone --disable-docs
658        ninja -C build install
659        touch ${{ runner.tool_cache }}/qemu/built
660      if: matrix.qemu != ''
661
662    # Record some CPU details; this is helpful information if tests fail due
663    # to CPU-specific features.
664    - name: CPU information
665      run: lscpu
666      if: matrix.os == 'ubuntu-latest'
667    - name: CPU information
668      run: sysctl hw
669      if: contains(matrix.os, 'macos')
670    - name: CPU information
671      run: wmic cpu list /format:list
672      shell: pwsh
673      if: matrix.os == 'windows-latest'
674
675    # Since MPK (PKU) is not present on some GitHub runners, we check if it is
676    # available before force-enabling it. This occasional testing is better than
677    # none at all; ideally we would test in a system-mode QEMU VM.
678    - name: Force-run with MPK enabled, if available
679      if: ${{ contains(matrix.name, 'MPK') }}
680      run: |
681        if cargo run --example mpk-available; then
682          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."
683          echo WASMTIME_TEST_FORCE_MPK=1 >> $GITHUB_ENV
684        else
685          echo "::warning::This CI run will not test MPK; it has been detected as not available on this machine (\`cargo run --example mpk-available\`)."
686        fi
687
688    # Build and test all features
689    - run: ./ci/run-tests.sh --locked ${{ matrix.bucket }}
690      env:
691        RUST_BACKTRACE: 1
692
693    # NB: the test job here is explicitly lacking in cancellation of this run if
694    # something goes wrong. These take the longest anyway and otherwise if
695    # Windows fails GitHub Actions will confusingly mark the failed Windows job
696    # as cancelled instead of failed.
697
698  # Test `wasmtime-wasi-nn` in its own job, as not all of its backends are
699  # compatible with all targets, and each must be tested separately anyways.
700  test_wasi_nn:
701    strategy:
702      matrix:
703        feature: ["openvino", "onnx"]
704        os: ["ubuntu-latest", "windows-latest"]
705        include:
706          - os: windows-latest
707            feature: winml
708    name: Test wasi-nn (${{ matrix.feature }}, ${{ matrix.os }})
709    runs-on: ${{ matrix.os }}
710    needs: determine
711    if: needs.determine.outputs.run-full
712    steps:
713    - uses: actions/checkout@v4
714      with:
715        submodules: true
716    - uses: ./.github/actions/install-rust
717
718    # Install OpenVINO
719    - uses: abrown/install-openvino-action@v8
720      if: runner.arch == 'X64'
721
722    # Install WinML for testing wasi-nn WinML backend. WinML is only available
723    # on Windows clients and Windows Server with desktop experience enabled.
724    # GitHub Actions Window Server image doesn't have desktop experience
725    # enabled, so we download the standalone library from ONNX Runtime project.
726    - uses: nuget/setup-nuget@v2
727      if: (matrix.os == 'windows-latest') && (matrix.feature == 'winml')
728    - run: nuget install Microsoft.AI.MachineLearning
729      if: (matrix.os == 'windows-latest') && (matrix.feature == 'winml')
730
731    # Install Rust targets.
732    - run: rustup target add wasm32-wasip1
733
734    # Run the tests!
735    - run: cargo test -p wasmtime-wasi-nn --features ${{ matrix.feature }}
736      env:
737        RUST_BACKTRACE: 1
738
739    # common logic to cancel the entire run if this job fails
740    - run: gh run cancel ${{ github.run_id }}
741      if: failure() && github.event_name != 'pull_request'
742      env:
743        GH_TOKEN: ${{ github.token }}
744
745  # Test the `wasmtime-wasi-keyvalue` crate. Split out from the main tests
746  # because it needs additional database service.
747  test_wasi_keyvalue:
748    name: Test wasi-keyvalue
749    runs-on: ubuntu-latest
750    needs: determine
751    if: needs.determine.outputs.run-wasi-keyvalue
752    # Setup redis server
753    services:
754      redis:
755        # Docker Hub image
756        image: redis
757        # Set health checks to wait until redis has started
758        options: >-
759          --health-cmd "redis-cli ping"
760          --health-interval 10s
761          --health-timeout 5s
762          --health-retries 5
763        ports:
764          # Maps port 6379 on service container to the host
765          - 6379:6379
766    steps:
767    - uses: actions/checkout@v4
768      with:
769        submodules: true
770    - uses: ./.github/actions/install-rust
771    # Install Rust targets
772    - run: rustup target add wasm32-wasi
773    - run: cargo test --all-features -p wasmtime-wasi-keyvalue
774      env:
775        RUST_BACKTRACE: 1
776
777    # common logic to cancel the entire run if this job fails
778    - run: gh run cancel ${{ github.run_id }}
779      if: failure() && github.event_name != 'pull_request'
780      env:
781        GH_TOKEN: ${{ github.token }}
782
783  # Test the `wasmtime-fuzzing` crate. Split out from the main tests because
784  # `--all-features` brings in OCaml, which is a pain to get setup for all
785  # targets.
786  test_fuzzing:
787    needs: determine
788    if: needs.determine.outputs.run-full
789    name: Test wasmtime-fuzzing
790    runs-on: 'ubuntu-latest'
791    steps:
792    - uses: actions/checkout@v4
793      with:
794        submodules: true
795    - uses: ./.github/actions/install-rust
796
797    # Run the tests
798    - run: |
799        cargo test -p wasmtime-fuzzing -p wasm-spec-interpreter
800      env:
801        RUST_BACKTRACE: 1
802
803    # common logic to cancel the entire run if this job fails
804    - run: gh run cancel ${{ github.run_id }}
805      if: failure() && github.event_name != 'pull_request'
806      env:
807        GH_TOKEN: ${{ github.token }}
808
809  # Test debug (DWARF) related functionality.
810  test_debug_dwarf:
811    needs: determine
812    if: needs.determine.outputs.run-dwarf
813    name: Test DWARF debugging
814    runs-on: 'ubuntu-latest'
815    steps:
816    - uses: actions/checkout@v4
817      with:
818        submodules: true
819    - uses: ./.github/actions/install-rust
820    - run: rustup target add wasm32-wasip1 wasm32-unknown-unknown
821    - run: |
822        sudo apt-get update && sudo apt-get install -y gdb lldb-15 llvm
823        # workaround for https://bugs.launchpad.net/ubuntu/+source/llvm-defaults/+bug/1972855
824        sudo mkdir -p /usr/lib/local/lib/python3.10/dist-packages/lldb
825        sudo ln -s /usr/lib/llvm-15/lib/python3.10/dist-packages/lldb/* /usr/lib/python3/dist-packages/lldb/
826        cargo test --test all -- --ignored --test-threads 1 debug::
827      env:
828        RUST_BACKTRACE: 1
829        LLDB: lldb-15 # override default version, 14
830
831    # common logic to cancel the entire run if this job fails
832    - run: gh run cancel ${{ github.run_id }}
833      if: failure() && github.event_name != 'pull_request'
834      env:
835        GH_TOKEN: ${{ github.token }}
836
837  build-preview1-component-adapter:
838    name: Build wasi-preview1-component-adapter
839    needs: determine
840    if: needs.determine.outputs.preview1-adapter
841    runs-on: ubuntu-latest
842    permissions:
843      deployments: write
844      contents: write
845    steps:
846    - uses: actions/checkout@v4
847      with:
848        submodules: true
849    - uses: ./.github/actions/install-rust
850    - run: rustup target add wasm32-wasip1 wasm32-unknown-unknown
851
852    - name: Install wasm-tools
853      run: |
854        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 -
855        echo `pwd`/wasm-tools-1.0.27-x86_64-linux >> $GITHUB_PATH
856
857    - run: ./ci/build-wasi-preview1-component-adapter.sh
858      env:
859        VERSION: ${{ github.sha }}
860
861    - uses: actions/upload-artifact@v4
862      with:
863        name: bins-wasi-preview1-component-adapter
864        path: target/wasm32-unknown-unknown/release/wasi_snapshot_preview1.*.wasm
865
866
867    # common logic to cancel the entire run if this job fails
868    - run: gh run cancel ${{ github.run_id }}
869      if: failure() && github.event_name != 'pull_request'
870      env:
871        GH_TOKEN: ${{ github.token }}
872
873  build-preview1-component-adapter-provider:
874    name: Build wasi-preview1-component-adapter-provider
875    needs: build-preview1-component-adapter
876    runs-on: ubuntu-latest
877    steps:
878    - uses: actions/checkout@v4
879      with:
880        submodules: true
881    - uses: ./.github/actions/install-rust
882    - uses: ./.github/actions/build-adapter-provider
883      with:
884        run-id: ${{ github.run_id }}
885
886
887    # common logic to cancel the entire run if this job fails
888    - run: gh run cancel ${{ github.run_id }}
889      if: failure() && github.event_name != 'pull_request'
890      env:
891        GH_TOKEN: ${{ github.token }}
892
893  # Verify the "min platform" example still works.
894  test-min-platform-example:
895    name: Test the min-platform example
896    needs: determine
897    if: needs.determine.outputs.run-full
898    runs-on: ubuntu-latest
899    steps:
900    - uses: actions/checkout@v4
901      with:
902        submodules: true
903    - uses: ./.github/actions/install-rust
904    - run: cargo install cbindgen --vers "^0.26" --locked
905    - run: rustup target add x86_64-unknown-none
906    - run: ./build.sh x86_64-unknown-none
907      working-directory: ./examples/min-platform
908
909    # Afterwards make sure the generated header file is up to date by ensuring
910    # that the regeneration process didn't change anything in-tree.
911    - run: git diff --exit-code
912
913    # Add the `wasmtime-platform.h` file as a release artifact
914    - uses: actions/upload-artifact@v4
915      with:
916        name: wasmtime-platform-header
917        path: examples/min-platform/embedding/wasmtime-platform.h
918
919    # common logic to cancel the entire run if this job fails
920    - run: gh run cancel ${{ github.run_id }}
921      if: failure() && github.event_name != 'pull_request'
922      env:
923        GH_TOKEN: ${{ github.token }}
924
925
926  build-wasmtime-target-wasm32:
927    name: Build wasmtime-target-wasm32
928    if: needs.determine.outputs.run-full
929    needs: determine
930    runs-on: ubuntu-latest
931    steps:
932    - uses: actions/checkout@v4
933      with:
934        submodules: true
935    - uses: ./.github/actions/install-rust
936    - run: rustup target add wasm32-wasip1 wasm32-unknown-unknown
937    - run: cargo build --target wasm32-wasip1 --no-default-features --features compile,cranelift,all-arch
938      env:
939        VERSION: ${{ github.sha }}
940
941    # common logic to cancel the entire run if this job fails
942    - run: gh run cancel ${{ github.run_id }}
943      if: failure() && github.event_name != 'pull_request'
944      env:
945        GH_TOKEN: ${{ github.token }}
946
947
948  bench:
949    needs: determine
950    if: needs.determine.outputs.run-full
951    name: Run benchmarks
952    runs-on: ubuntu-latest
953    steps:
954    - uses: actions/checkout@v4
955      with:
956        submodules: true
957    - uses: ./.github/actions/install-rust
958    - run: rustup target add wasm32-wasip1
959    - run: cargo test --benches --release
960
961    # common logic to cancel the entire run if this job fails
962    - run: gh run cancel ${{ github.run_id }}
963      if: failure() && github.event_name != 'pull_request'
964      env:
965        GH_TOKEN: ${{ github.token }}
966
967  # Verify that cranelift's code generation is deterministic
968  meta_deterministic_check:
969    needs: determine
970    if: needs.determine.outputs.run-full
971    name: Meta deterministic check
972    runs-on: ubuntu-latest
973    steps:
974    - uses: actions/checkout@v4
975      with:
976        submodules: true
977    - uses: ./.github/actions/install-rust
978    - run: cd cranelift/codegen && cargo build --features all-arch
979    - run: ci/ensure_deterministic_build.sh
980
981    # common logic to cancel the entire run if this job fails
982    - run: gh run cancel ${{ github.run_id }}
983      if: failure() && github.event_name != 'pull_request'
984      env:
985        GH_TOKEN: ${{ github.token }}
986
987  verify-publish:
988    needs: determine
989    if: github.repository == 'bytecodealliance/wasmtime' && needs.determine.outputs.run-full
990    runs-on: ubuntu-latest
991    steps:
992    - uses: actions/checkout@v4
993      with:
994        submodules: true
995    - uses: ./.github/actions/install-rust
996    - run: |
997        cd ${{ runner.tool_cache }}
998        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 -
999        echo "`pwd`/sccache-0.2.13-x86_64-unknown-linux-musl" >> $GITHUB_PATH
1000        echo RUSTC_WRAPPER=sccache >> $GITHUB_ENV
1001    - run: rustc scripts/publish.rs
1002    # Make sure the tree is publish-able as-is
1003    - run: ./publish verify
1004    # Make sure we can bump version numbers for the next release
1005    - run: ./publish bump
1006
1007    # common logic to cancel the entire run if this job fails
1008    - run: gh run cancel ${{ github.run_id }}
1009      if: failure() && github.event_name != 'pull_request'
1010      env:
1011        GH_TOKEN: ${{ github.token }}
1012
1013  # Run a subset of tests under MIRI on CI to help check the `unsafe` code in
1014  # Wasmtime to make sure it's at least not obviously incorrect for basic usage.
1015  # Note that this doesn't run the full test suite since MIRI can't actually run
1016  # WebAssembly itself at this time (aka it doesn't support a JIT). There are a
1017  # number of annotations throughout the code which gates some tests on MIRI not
1018  # being run.
1019  #
1020  # Note that `cargo nextest` is used here additionally to get parallel test
1021  # execution by default to help cut down on the time in CI.
1022  miri:
1023    strategy:
1024      matrix:
1025        crate:
1026          - "wasmtime"
1027          - "wasmtime-cli"
1028          - "wasmtime-environ"
1029          - "pulley-interpreter --all-features"
1030    needs: determine
1031    if: needs.determine.outputs.run-full && github.repository == 'bytecodealliance/wasmtime'
1032    name: Miri
1033    runs-on: ubuntu-latest
1034    env:
1035      CARGO_NEXTEST_VERSION: 0.9.67
1036    steps:
1037    - uses: actions/checkout@v4
1038      with:
1039        submodules: true
1040    - uses: ./.github/actions/install-rust
1041      with:
1042        toolchain: wasmtime-ci-pinned-nightly
1043    - run: rustup component add rust-src miri
1044    - uses: actions/cache@v4
1045      with:
1046        path: ${{ runner.tool_cache }}/cargo-nextest
1047        key: cargo-nextest-bin-${{ env.CARGO_NEXTEST_VERSION }}
1048    - run: echo "${{ runner.tool_cache }}/cargo-nextest/bin" >> $GITHUB_PATH
1049    - run: cargo install --root ${{ runner.tool_cache }}/cargo-nextest --version ${{ env.CARGO_NEXTEST_VERSION }} cargo-nextest --locked
1050    - run: |
1051        cargo miri nextest run -j4 --no-fail-fast -p ${{ matrix.crate }}
1052      env:
1053        MIRIFLAGS: -Zmiri-strict-provenance
1054
1055    # common logic to cancel the entire run if this job fails
1056    - run: gh run cancel ${{ github.run_id }}
1057      if: failure() && github.event_name != 'pull_request'
1058      env:
1059        GH_TOKEN: ${{ github.token }}
1060
1061  # Perform release builds of `wasmtime` and `libwasmtime.so`. Builds a variety
1062  # of platforms and architectures and then uploads the release artifacts to
1063  # this workflow run's list of artifacts.
1064  #
1065  # Note that the full matrix is computed by `ci/build-build-matrix.js`.
1066  build:
1067    needs: determine
1068    if: needs.determine.outputs.run-full
1069    name: Release build for ${{ matrix.build }}
1070    runs-on: ${{ matrix.os }}
1071    strategy:
1072      fail-fast: ${{ github.event_name != 'pull_request' }}
1073      matrix: ${{ fromJson(needs.determine.outputs.build-matrix) }}
1074    steps:
1075    - uses: actions/checkout@v4
1076      with:
1077        submodules: true
1078
1079    - uses: ./.github/actions/install-rust
1080      with:
1081        toolchain: ${{ matrix.rust }}
1082    - run: |
1083        rustup component add rust-src
1084        rustup target add ${{ matrix.target }}
1085
1086    # On one builder produce the source tarball since there's no need to produce
1087    # it everywhere
1088    - run: ./ci/build-src-tarball.sh
1089      if: matrix.build == 'x86_64-linux'
1090    - uses: ./.github/actions/binary-compatible-builds
1091      with:
1092        name: ${{ matrix.build }}
1093
1094    - uses: ./.github/actions/android-ndk
1095      if: contains(matrix.target, 'android')
1096      with:
1097        target: ${{ matrix.target }}
1098
1099    - run: $CENTOS ./ci/build-release-artifacts.sh "${{ matrix.build }}" "${{ matrix.target }}"
1100
1101    # Assemble release artifacts appropriate for this platform, then upload them
1102    # unconditionally to this workflow's files so we have a copy of them.
1103    - run: ./ci/build-tarballs.sh "${{ matrix.build }}" "${{ matrix.target }}"
1104
1105    - uses: actions/upload-artifact@v4
1106      with:
1107        name: bins-${{ matrix.build }}
1108        path: dist
1109
1110    # common logic to cancel the entire run if this job fails
1111    - run: gh run cancel ${{ github.run_id }}
1112      if: failure() && github.event_name != 'pull_request'
1113      env:
1114        GH_TOKEN: ${{ github.token }}
1115
1116  # This is a "join node" which depends on all prior workflows. The merge queue,
1117  # for example, gates on this to ensure that everything has executed
1118  # successfully.
1119  #
1120  # Note that this is required currently for odd reasons with github. Notably
1121  # the set of checks to enter the merge queue and leave the merge queue must
1122  # be the same which means that the "build" step for example shows as skipped
1123  # for PRs but expands to many different steps for merge-queue-based PRs. That
1124  # means that for that step there's no single name to gate on, so it's required
1125  # to have a "join" node here which joins everything.
1126  #
1127  # Note that this currently always runs to always report a status, even on
1128  # cancellation and even if dependency steps fail. Each dependency tries to
1129  # cancel the whole run if it fails, so if a test matrix entry fails, for
1130  # example, it cancels the build matrix entries too. This step then tries to
1131  # fail on cancellation to ensure that the dependency failures are propagated
1132  # correctly.
1133  ci-status:
1134    name: Record the result of testing and building steps
1135    runs-on: ubuntu-latest
1136    needs:
1137      - test
1138      - test_capi
1139      - test_debug_dwarf
1140      - test_fuzzing
1141      - test_wasi_nn
1142      - test_nightly
1143      - build
1144      - rustfmt
1145      - clangformat
1146      - cargo_deny
1147      - cargo_vet
1148      - doc
1149      - micro_checks
1150      - monolith_checks
1151      - checks_winarm64
1152      - bench
1153      - meta_deterministic_check
1154      - verify-publish
1155      - determine
1156      - miri
1157      - build-preview1-component-adapter
1158      - build-preview1-component-adapter-provider
1159      - build-wasmtime-target-wasm32
1160      - test-min-platform-example
1161      - check_js
1162    if: always()
1163    steps:
1164    - name: Successful test and build
1165      if: ${{ !(contains(needs.*.result, 'failure')) }}
1166      run: exit 0
1167    - name: Failing test and build
1168      if: ${{ contains(needs.*.result, 'failure') }}
1169      run: exit 1
1170    - name: Report failure on cancellation
1171      if: ${{ contains(needs.*.result, 'cancelled') || cancelled() }}
1172      run: exit 1
1173
1174  # The purpose of this jobs is to watch for changes on the `release-*`
1175  # branches of this repository and look for the term
1176  # "automatically-tag-and-release-this-commit" within merged PRs/commits. Once
1177  # that term is found the current version of `Cargo.toml`, the `wasmtime-cli`
1178  # Cargo.toml, is created as a tag and the tag is pushed to the repo.
1179  # Currently the tag is created through the GitHub API with an access token to
1180  # ensure that CI is further triggered for the tag itself which performs the
1181  # full release process.
1182  #
1183  # Note that this depends on the `ci-status` step above which is the "join"
1184  # point of this workflow for when everything succeeds. the purpose of that is
1185  # so that the tag is only created after the aftifacts have been uploaded for
1186  # this workflow as the `publish-artifacts.yml` workflow will download these
1187  # artifacts and then publish them to the tag.
1188  push-tag:
1189    runs-on: ubuntu-latest
1190    needs: ci-status
1191    if: |
1192      always()
1193      && needs.ci-status.result == 'success'
1194      && github.event_name == 'push'
1195      && startsWith(github.ref, 'refs/heads/release-')
1196      && github.repository == 'bytecodealliance/wasmtime'
1197    steps:
1198    - uses: actions/checkout@v4
1199      with:
1200        submodules: true
1201        fetch-depth: 0
1202    - name: Test if tag is needed
1203      run: |
1204        git log ${{ github.event.before }}...${{ github.event.after }} | tee main.log
1205        version=$(grep '^version =' Cargo.toml | head -n 1 | sed 's/.*"\(.*\)"/\1/')
1206        echo "version: $version"
1207        echo "version=$version" >> $GITHUB_OUTPUT
1208        echo "sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
1209        if grep -q "automatically-tag-and-release-this-commit" main.log; then
1210          echo push-tag
1211          echo "push_tag=yes" >> $GITHUB_OUTPUT
1212        else
1213          echo no-push-tag
1214          echo "push_tag=no" >> $GITHUB_OUTPUT
1215        fi
1216      id: tag
1217    - name: Push the tag
1218      run: |
1219        git_refs_url=$(jq .repository.git_refs_url $GITHUB_EVENT_PATH | tr -d '"' | sed 's/{\/sha}//g')
1220        curl -iX POST $git_refs_url \
1221          -H "Authorization: token ${{ secrets.PERSONAL_ACCESS_TOKEN }}" \
1222          -d @- << EOF
1223        {
1224          "ref": "refs/tags/v${{ steps.tag.outputs.version }}",
1225          "sha": "${{ steps.tag.outputs.sha }}"
1226        }
1227        EOF
1228      if: steps.tag.outputs.push_tag == 'yes'
1229