name: "CI VM" description: "Run main CI steps in VMs for VM-only platforms." inputs: working-directory: description: "Working directory." default: "." platform: description: "Platform to run the checks on." default: "" codecov-token: description: "Codecov token, if Codecov upload is desired." default: "" bindgen-args: description: "bindgen arguments for generating BSD bindings. Non-empty enables binding generation." default: "" runs: using: composite steps: - shell: bash id: prep env: WD: ${{ inputs.working-directory }} PLATFORM: ${{ inputs.platform }} WORKSPACE: ${{ inputs.working-directory == '.' && '--workspace' || '' }} BINDGEN_ARGS: ${{ inputs.bindgen-args }} run: | cat < prepare.sh # This executes as root set -ex pwd case "$PLATFORM" in freebsd) pkg update -f && pkg install -y curl llvm nss pkgconf rust-bindgen-cli ;; openbsd) # TODO: Is there a way to not pin the version of llvm? -z to pkg_add does not work. pkg_add rust rust-clippy rust-rustfmt rust-bindgen llvm-21.1.8p4 nss # rustup does not support OpenBSD at all ;; netbsd) /usr/sbin/pkg_add pkgin && /usr/pkg/bin/pkgin -y update && /usr/pkg/bin/pkgin -y install curl clang nss pkgconf rust-bindgen cmake ninja ;; solaris) pkg refresh && pkg install clang-libs nss pkg-config ;; *) echo "Unsupported OS: $PLATFORM" exit 1 ;; esac EOF { echo 'prepare<> "$GITHUB_OUTPUT" cat < run.sh # This executes as user set -ex cd "$WD" pwd case "$PLATFORM" in openbsd) export LIBCLANG_PATH=/usr/local/llvm21/lib export LLVM_COV=/usr/local/llvm21/bin/llvm-cov export LLVM_PROFDATA=/usr/local/llvm21/bin/llvm-profdata export PATH="\$HOME/.cargo/bin:\$PATH" ;; *) sh rustup.sh --default-toolchain stable --profile minimal --component clippy,llvm-tools,rustfmt -y . "\$HOME/.cargo/env" ;; esac case "$PLATFORM" in netbsd) # FIXME: Why do we need to set this on NetBSD? export LD_LIBRARY_PATH=/usr/pkg/lib/nss:/usr/pkg/lib/nspr ;; solaris) export LIBCLANG_PATH=/usr/llvm/21/lib/amd64 ;; esac case "$PLATFORM" in freebsd) ;; *) [ "$WORKSPACE" ] && EXCLUDE="--exclude fuzz" # Fuzzing not supported on this platform ;; esac # Embed at script-generation time; single quotes protect | from shell interpretation. BINDGEN_ARGS='$BINDGEN_ARGS' # Generate bindings first if requested (before build, so we can bootstrap) if [ -n "$BINDGEN_ARGS" ]; then # Solaris doesn't have a system package for bindgen [ "$PLATFORM" = "solaris" ] && cargo install bindgen-cli --locked echo "$BINDGEN_ARGS" | xargs bindgen src/bindings/bsd.h > "$PLATFORM.rs" # Compare generated bindings with committed bindings. # If different, exit early — there's no point compiling with stale # bindings. The check-bindings job will detect the drift and handle it. if ! diff -q "src/bindings/$PLATFORM.rs" "$PLATFORM.rs" > /dev/null 2>&1; then echo "::warning::Bindings for $PLATFORM differ from committed version" exit 0 fi fi cargo version cargo check --locked --all-targets $WORKSPACE \${EXCLUDE:-} case "$PLATFORM" in openbsd) # clippy fails on OpenBSD, because libfuzzer-sys is not supported. ;; *) cargo clippy -- -D warnings ;; esac cargo fmt --all -- --check cargo install cargo-hack --locked case "$PLATFORM" in freebsd) cargo install cargo-llvm-cov --locked cargo llvm-cov test --locked --no-fail-fast --codecov --output-path codecov.json ;; *) # FIXME: No profiler support on other platforms, error is: cannot find crate for profiler_builtins cargo test --locked --no-fail-fast # We do this instead for now ;; esac cargo hack test --locked --no-fail-fast --feature-powerset --exclude-features gecko --mutually-exclusive-features blapi,disable-encryption cargo test --locked --no-fail-fast --release rm -rf target # Do not sync this back to host EOF { echo 'run<> "$GITHUB_OUTPUT" curl -o "$WD/rustup.sh" --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs echo "envs=CARGO_TERM_COLOR RUST_BACKTRACE RUST_LOG RUST_TEST_TIME_UNIT RUST_TEST_TIME_INTEGRATION RUST_TEST_TIME_DOCTEST WD" >> "$GITHUB_OUTPUT" - if: ${{ inputs.platform == 'freebsd' }} uses: vmactions/freebsd-vm@a6de9343ef5747433d9c25784c90e84998b9d69a # v1.4.6 with: usesh: true disable-cache: true copyback: true envs: ${{ steps.prep.outputs.envs }} prepare: ${{ steps.prep.outputs.prepare }} run: ${{ steps.prep.outputs.run }} - if: ${{ inputs.platform == 'openbsd' }} uses: vmactions/openbsd-vm@6fac4962055fe9952d29930942445739e509fecd # v1.4.2 with: usesh: true disable-cache: true copyback: true envs: ${{ steps.prep.outputs.envs }} prepare: ${{ steps.prep.outputs.prepare }} run: ${{ steps.prep.outputs.run }} - if: ${{ inputs.platform == 'netbsd' }} uses: vmactions/netbsd-vm@ad31081832386a0ba569aee243e6edf9524f3f80 # v1.3.9 with: usesh: true disable-cache: true copyback: true envs: ${{ steps.prep.outputs.envs }} prepare: ${{ steps.prep.outputs.prepare }} run: ${{ steps.prep.outputs.run }} - if: ${{ inputs.platform == 'solaris' }} uses: vmactions/solaris-vm@3702ccf20b84c7f7c0a9bb68894aba7623f8301d # v1.3.6 with: release: "11.4-gcc" usesh: true disable-cache: true copyback: true envs: ${{ steps.prep.outputs.envs }} prepare: ${{ steps.prep.outputs.prepare }} run: ${{ steps.prep.outputs.run }} - id: check-coverage shell: bash env: WORKING_DIR: ${{ inputs.working-directory }} run: test -f "$WORKING_DIR/codecov.json" && echo "exists=true" >> "$GITHUB_OUTPUT" || true - if: ${{ steps.check-coverage.outputs.exists == 'true' }} uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1 with: files: codecov.json working-directory: ${{ inputs.working-directory }} fail_ci_if_error: false token: ${{ inputs.codecov-token }} verbose: true flags: ${{ inputs.platform }} - if: ${{ always() && inputs.bindgen-args != '' }} uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: bindings-${{ inputs.platform }} path: ${{ inputs.working-directory }}/${{ inputs.platform }}.rs if-no-files-found: error