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