diff --git a/.github/workflows/openvmm-ci.yaml b/.github/workflows/openvmm-ci.yaml index 60106cd53b..bc9d5135ce 100644 --- a/.github/workflows/openvmm-ci.yaml +++ b/.github/workflows/openvmm-ci.yaml @@ -3481,9 +3481,9 @@ jobs: - name: πŸŒΌπŸ“¦ Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-13,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' + pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-14,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14" >> $GITHUB_PATH shell: bash name: πŸŒΌπŸ“¦ Add flowey to PATH - name: πŸŒΌπŸ›« Initialize job @@ -3492,7 +3492,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13/flowey.exe + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14/flowey.exe echo '"debug"' | flowey.exe v 19 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey.exe v 19 '_internal_WORKING_DIR' --is-raw-string update @@ -3953,9 +3953,9 @@ jobs: - name: πŸŒΌπŸ“¦ Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-13,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-mi-secure-openhcl-igvm,x64-mi-secure-openhcl-igvm-cvm,x64-mi-secure-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' + pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-14,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-mi-secure-openhcl-igvm,x64-mi-secure-openhcl-igvm-cvm,x64-mi-secure-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14" >> $GITHUB_PATH shell: bash name: πŸŒΌπŸ“¦ Add flowey to PATH - name: πŸŒΌπŸ›« Initialize job @@ -3964,7 +3964,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13/flowey.exe + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14/flowey.exe echo '"debug"' | flowey.exe v 20 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey.exe v 20 '_internal_WORKING_DIR' --is-raw-string update @@ -4235,9 +4235,9 @@ jobs: - name: πŸŒΌπŸ“¦ Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-13,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' + pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-14,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14" >> $GITHUB_PATH shell: bash name: πŸŒΌπŸ“¦ Add flowey to PATH - name: πŸŒΌπŸ›« Initialize job @@ -4246,7 +4246,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13/flowey.exe + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14/flowey.exe echo '"debug"' | flowey.exe v 21 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey.exe v 21 '_internal_WORKING_DIR' --is-raw-string update @@ -4521,9 +4521,9 @@ jobs: - name: πŸŒΌπŸ“¦ Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-13,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' + pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-14,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14" >> $GITHUB_PATH shell: bash name: πŸŒΌπŸ“¦ Add flowey to PATH - name: πŸŒΌπŸ›« Initialize job @@ -4532,7 +4532,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13/flowey.exe + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14/flowey.exe echo '"debug"' | flowey.exe v 22 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey.exe v 22 '_internal_WORKING_DIR' --is-raw-string update @@ -4808,9 +4808,9 @@ jobs: - name: πŸŒΌπŸ“¦ Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-13,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' + pattern: '{_internal-flowey-bootstrap-x86_64-windows-uid-14,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-tpm_guest_tests,x64-openhcl-igvm,x64-openhcl-igvm-cvm,x64-openhcl-igvm-test-linux-direct,x64-tmks,x64-windows-openvmm,x64-windows-pipette,x64-windows-prep_steps,x64-windows-test_igvm_agent_rpc_server,x64-windows-tmk_vmm,x64-windows-tpm_guest_tests,x64-windows-vmgstool,x64-windows-vmgstool-dev,x64-windows-vmm-tests-archive}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14" >> $GITHUB_PATH shell: bash name: πŸŒΌπŸ“¦ Add flowey to PATH - name: πŸŒΌπŸ›« Initialize job @@ -4819,7 +4819,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-13/flowey.exe + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-windows-uid-14/flowey.exe echo '"debug"' | flowey.exe v 23 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey.exe v 23 '_internal_WORKING_DIR' --is-raw-string update @@ -5093,9 +5093,9 @@ jobs: - name: πŸŒΌπŸ“¦ Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-11,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-openvmm,x64-linux-openvmm_vhost,x64-linux-prep_steps,x64-linux-vmm-tests-archive,x64-tmks,x64-windows-pipette}' + pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-12,x64-guest_test_uefi,x64-linux-musl-pipette,x64-linux-musl-tmk_vmm,x64-linux-openvmm,x64-linux-openvmm_vhost,x64-linux-prep_steps,x64-linux-vmm-tests-archive,x64-tmks,x64-windows-pipette}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-11" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12" >> $GITHUB_PATH shell: bash name: πŸŒΌπŸ“¦ Add flowey to PATH - name: πŸŒΌπŸ›« Initialize job @@ -5104,7 +5104,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-11/flowey + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12/flowey echo '"debug"' | flowey v 24 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey v 24 '_internal_WORKING_DIR' --is-raw-string update @@ -6009,9 +6009,9 @@ jobs: - name: πŸŒΌπŸ“¦ Download artifacts uses: actions/download-artifact@v8 with: - pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-12,aarch64-guest_test_uefi,aarch64-linux-musl-openvmm,aarch64-linux-musl-pipette,aarch64-linux-musl-tmk_vmm,aarch64-linux-vmm-tests-archive,aarch64-tmks,x64-linux-incubator}' + pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-13,aarch64-guest_test_uefi,aarch64-linux-musl-openvmm,aarch64-linux-musl-pipette,aarch64-linux-musl-tmk_vmm,aarch64-linux-vmm-tests-archive,aarch64-tmks,x64-linux-incubator}' path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12" >> $GITHUB_PATH + - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-13" >> $GITHUB_PATH shell: bash name: πŸŒΌπŸ“¦ Add flowey to PATH - name: πŸŒΌπŸ›« Initialize job @@ -6020,7 +6020,7 @@ jobs: AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12/flowey + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-13/flowey echo '"debug"' | flowey v 27 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey v 27 '_internal_WORKING_DIR' --is-raw-string update @@ -6383,57 +6383,72 @@ jobs: run: flowey e 28 flowey_lib_hvlite::_jobs::test_local_flowey_build_igvm 1 shell: bash job29: - name: publish vmgstool + name: build openvmm [distribution config, x64-linux-gnu] runs-on: ubuntu-latest permissions: - contents: write + contents: read id-token: write - needs: - - job0 - - job1 - - job10 - - job11 - - job12 - - job13 - - job14 - - job15 - - job16 - - job17 - - job18 - - job19 - - job2 - - job20 - - job21 - - job22 - - job24 - - job25 - - job26 - - job27 - - job28 - - job3 - - job4 - - job5 - - job6 - - job7 - - job8 - - job9 if: github.event.pull_request.draft == false steps: - - name: πŸŒΌπŸ“¦ Download artifacts - uses: actions/download-artifact@v8 + - run: | + set -x + i=0; while [ $i -lt 5 ] && ! sudo apt-get update; do let "i=i+1"; sleep 1; done; + sudo apt-get -o DPkg::Lock::Timeout=60 install gcc -y + curl --fail --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- --default-toolchain=1.95.0 -y + . "$HOME/.cargo/env" + echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" + rustup show + if: runner.os == 'Linux' + name: rustup (Linux) + shell: bash + - run: | + set -x + curl --fail -sSfLo rustup-init.exe https://win.rustup.rs/x86_64 --output rustup-init + ./rustup-init.exe -y --default-toolchain=1.95.0 + echo "$USERPROFILE\\.cargo\\bin" >> $GITHUB_PATH + if: runner.os == 'Windows' && runner.arch == 'X64' + name: rustup (Windows X64) + shell: bash + - run: | + set -x + curl --fail -sSfLo rustup-init.exe https://win.rustup.rs/aarch64 --output rustup-init + ./rustup-init.exe -y --default-toolchain=1.95.0 + echo "$USERPROFILE\\.cargo\\bin" >> $GITHUB_PATH + if: runner.os == 'Windows' && runner.arch == 'ARM64' + name: rustup (Windows ARM64) + shell: bash + - uses: actions/checkout@v6 with: - pattern: '{_internal-flowey-bootstrap-x86_64-linux-uid-12,aarch64-linux-vmgstool,aarch64-windows-vmgstool,x64-linux-vmgstool,x64-windows-vmgstool}' - path: ${{ runner.temp }}/used_artifacts/ - - run: echo "${{ runner.temp }}/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12" >> $GITHUB_PATH + path: flowey_bootstrap + - name: Build flowey + run: | + set -x + CARGO_INCREMENTAL=0 cargo build -p flowey_hvlite --target x86_64-unknown-linux-gnu --profile flowey-ci + OutDirNormal=$(echo "${{ runner.temp }}/bootstrapped-flowey" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') + mkdir -p "$OutDirNormal" + mv ./.github/workflows/openvmm-ci.yaml "$OutDirNormal/pipeline.yaml" + mv target/x86_64-unknown-linux-gnu/flowey-ci/flowey_hvlite "$OutDirNormal/flowey" + working-directory: flowey_bootstrap + shell: bash + - run: echo "${{ runner.temp }}/bootstrapped-flowey" >> $GITHUB_PATH shell: bash name: πŸŒΌπŸ“¦ Add flowey to PATH + - name: πŸŒΌπŸ”Ž Self-check YAML + run: |- + ESCAPED_AGENT_TEMPDIR=$( + cat <<'EOF' | sed 's/\\/\\\\/g' + ${{ runner.temp }} + EOF + ) + flowey pipeline github --runtime $ESCAPED_AGENT_TEMPDIR/bootstrapped-flowey/pipeline.yaml --out .github/workflows/openvmm-ci.yaml ci checkin-gates --config=ci + shell: bash - name: πŸŒΌπŸ›« Initialize job run: | AgentTempDirNormal="${{ runner.temp }}" AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV - chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-12/flowey + chmod +x $AgentTempDirNormal/bootstrapped-flowey/flowey echo '"debug"' | flowey v 29 'FLOWEY_LOG' update echo "${{ runner.temp }}/work" | flowey v 29 '_internal_WORKING_DIR' --is-raw-string update @@ -6441,47 +6456,18 @@ jobs: cat <<'EOF' | flowey v 29 'verbose' update ${{ inputs.verbose != '' && inputs.verbose || 'false' }} EOF - echo "$AgentTempDirNormal/used_artifacts/aarch64-linux-vmgstool" | flowey v 29 'artifact_use_from_aarch64-linux-vmgstool' --is-raw-string update - echo "$AgentTempDirNormal/used_artifacts/aarch64-windows-vmgstool" | flowey v 29 'artifact_use_from_aarch64-windows-vmgstool' --is-raw-string update - echo "$AgentTempDirNormal/used_artifacts/x64-linux-vmgstool" | flowey v 29 'artifact_use_from_x64-linux-vmgstool' --is-raw-string update - echo "$AgentTempDirNormal/used_artifacts/x64-windows-vmgstool" | flowey v 29 'artifact_use_from_x64-windows-vmgstool' --is-raw-string update - shell: bash - - name: create gh cache dir - run: flowey e 29 flowey_lib_common::download_gh_cli 0 shell: bash - - name: Pre-processing cache vars - run: |- - flowey e 29 flowey_lib_common::cache 0 - flowey v 29 'flowey_lib_common::cache:2:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env github floweyvar2 - flowey v 29 'flowey_lib_common::cache:1:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env github floweyvar3 + - name: add default cargo home to path + run: flowey e 29 flowey_lib_common::install_rust 0 shell: bash - - id: flowey_lib_common__cache__1 - uses: actions/cache@v5 - with: - key: ${{ env.floweyvar2 }} - path: ${{ env.floweyvar3 }} - name: 'Restore cache: gh-cli' - - name: installing gh - run: |- - flowey v 29 'flowey_lib_common::cache:4:flowey_lib_common/src/cache.rs' --is-raw-string update --env-source steps.flowey_lib_common__cache__1.outputs.cache-hit <> $GITHUB_PATH + shell: bash + name: πŸŒΌπŸ“¦ Add flowey to PATH + - name: πŸŒΌπŸ›« Initialize job + run: | + AgentTempDirNormal="${{ runner.temp }}" + AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') + echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV + + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-13/flowey + + echo '"debug"' | flowey v 30 'FLOWEY_LOG' update + echo "${{ runner.temp }}/work" | flowey v 30 '_internal_WORKING_DIR' --is-raw-string update + + cat <<'EOF' | flowey v 30 'verbose' update + ${{ inputs.verbose != '' && inputs.verbose || 'false' }} + EOF + echo "$AgentTempDirNormal/used_artifacts/aarch64-linux-vmgstool" | flowey v 30 'artifact_use_from_aarch64-linux-vmgstool' --is-raw-string update + echo "$AgentTempDirNormal/used_artifacts/aarch64-windows-vmgstool" | flowey v 30 'artifact_use_from_aarch64-windows-vmgstool' --is-raw-string update + echo "$AgentTempDirNormal/used_artifacts/x64-linux-vmgstool" | flowey v 30 'artifact_use_from_x64-linux-vmgstool' --is-raw-string update + echo "$AgentTempDirNormal/used_artifacts/x64-windows-vmgstool" | flowey v 30 'artifact_use_from_x64-windows-vmgstool' --is-raw-string update + shell: bash + - name: create gh cache dir + run: flowey e 30 flowey_lib_common::download_gh_cli 0 + shell: bash + - name: Pre-processing cache vars + run: |- + flowey e 30 flowey_lib_common::cache 0 + flowey v 30 'flowey_lib_common::cache:2:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env github floweyvar2 + flowey v 30 'flowey_lib_common::cache:1:flowey_lib_common/src/cache.rs' --is-raw-string write-to-env github floweyvar3 + shell: bash + - id: flowey_lib_common__cache__1 + uses: actions/cache@v5 + with: + key: ${{ env.floweyvar2 }} + path: ${{ env.floweyvar3 }} + name: 'Restore cache: gh-cli' + - name: installing gh + run: |- + flowey v 30 'flowey_lib_common::cache:4:flowey_lib_common/src/cache.rs' --is-raw-string update --env-source steps.flowey_lib_common__cache__1.outputs.cache-hit <> $GITHUB_PATH + shell: bash + name: πŸŒΌπŸ“¦ Add flowey to PATH + - name: πŸŒΌπŸ›« Initialize job + run: | + AgentTempDirNormal="${{ runner.temp }}" + AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') + echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV + + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-1/flowey + + echo '"debug"' | flowey v 29 'FLOWEY_LOG' update + echo "${{ runner.temp }}/work" | flowey v 29 '_internal_WORKING_DIR' --is-raw-string update + + cat <<'EOF' | flowey v 29 'verbose' update + ${{ inputs.verbose != '' && inputs.verbose || 'false' }} + EOF + shell: bash + - name: add default cargo home to path + run: flowey e 29 flowey_lib_common::install_rust 0 + shell: bash + - name: install Rust + run: flowey e 29 flowey_lib_common::install_rust 1 + shell: bash + - name: checking if packages need to be installed + run: flowey e 29 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 29 flowey_lib_common::install_dist_pkg 1 + shell: bash + - name: check if openvmm needs to be cloned + run: |- + flowey e 29 flowey_lib_common::git_checkout 0 + flowey v 29 'flowey_lib_common::git_checkout:0:flowey_lib_common/src/git_checkout.rs' --is-raw-string --condvar flowey_lib_common::git_checkout:1:flowey_lib_common/src/git_checkout.rs write-to-env github floweyvar1 + flowey v 29 'flowey_lib_common::git_checkout:1:flowey_lib_common/src/git_checkout.rs' write-to-env github FLOWEY_CONDITION + shell: bash + - id: flowey_lib_common__git_checkout__1 + uses: actions/checkout@v6 + with: + fetch-depth: '1' + path: repo0 + persist-credentials: ${{ env.floweyvar1 }} + name: checkout repo openvmm + if: ${{ fromJSON(env.FLOWEY_CONDITION) }} + - name: report cloned repo directories + run: |- + flowey v 29 'flowey_lib_common::git_checkout:4:flowey_core/src/node/github_context.rs' --is-raw-string update --env-source github.workspace <> $GITHUB_PATH + shell: bash + name: πŸŒΌπŸ“¦ Add flowey to PATH + - name: πŸŒΌπŸ›« Initialize job + run: | + AgentTempDirNormal="${{ runner.temp }}" + AgentTempDirNormal=$(echo "$AgentTempDirNormal" | sed -e 's|\\|\/|g' -e 's|^\([A-Za-z]\)\:/\(.*\)|/\L\1\E/\2|') + echo "AgentTempDirNormal=$AgentTempDirNormal" >> $GITHUB_ENV + + chmod +x $AgentTempDirNormal/used_artifacts/_internal-flowey-bootstrap-x86_64-linux-uid-1/flowey + + echo '"debug"' | flowey v 31 'FLOWEY_LOG' update + echo "${{ runner.temp }}/work" | flowey v 31 '_internal_WORKING_DIR' --is-raw-string update + + cat <<'EOF' | flowey v 31 'verbose' update + ${{ inputs.verbose != '' && inputs.verbose || 'false' }} + EOF + shell: bash + - name: add default cargo home to path + run: flowey e 31 flowey_lib_common::install_rust 0 + shell: bash + - name: install Rust + run: flowey e 31 flowey_lib_common::install_rust 1 + shell: bash + - name: checking if packages need to be installed + run: flowey e 31 flowey_lib_common::install_dist_pkg 0 + shell: bash + - name: installing packages + run: flowey e 31 flowey_lib_common::install_dist_pkg 1 + shell: bash + - name: check if openvmm needs to be cloned + run: |- + flowey e 31 flowey_lib_common::git_checkout 0 + flowey v 31 'flowey_lib_common::git_checkout:0:flowey_lib_common/src/git_checkout.rs' --is-raw-string --condvar flowey_lib_common::git_checkout:1:flowey_lib_common/src/git_checkout.rs write-to-env github floweyvar1 + flowey v 31 'flowey_lib_common::git_checkout:1:flowey_lib_common/src/git_checkout.rs' write-to-env github FLOWEY_CONDITION + shell: bash + - id: flowey_lib_common__git_checkout__1 + uses: actions/checkout@v6 + with: + fetch-depth: '1' + path: repo0 + persist-credentials: ${{ env.floweyvar1 }} + name: checkout repo openvmm + if: ${{ fromJSON(env.FLOWEY_CONDITION) }} + - name: report cloned repo directories + run: |- + flowey v 31 'flowey_lib_common::git_checkout:4:flowey_core/src/node/github_context.rs' --is-raw-string update --env-source github.workspace <, + } +} + +new_simple_flow_node!(struct Node); + +impl SimpleFlowNode for Node { + type Request = Request; + + fn imports(ctx: &mut ImportCtx<'_>) { + ctx.import::(); + ctx.import::(); + ctx.import::(); + ctx.import::(); + } + + fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> { + let Request { identity, done } = request; + + let target = target_lexicon::triple!("x86_64-unknown-linux-gnu"); + + // This job deliberately does not depend on + // `install_openvmm_rust_build_essential`. That node provisions `protoc` + // out of `.packages/`, which is the dependency this job exists to prove + // we do not need. It also skips the `-Dwarnings` cargo config, which a + // packager does not build with either; the clippy jobs cover warnings. + let mut deps = vec![ctx.reqv(flowey_lib_common::install_rust::Request::EnsureInstalled)]; + + if matches!( + ctx.platform(), + FlowPlatform::Linux(FlowPlatformLinuxDistro::Ubuntu) + ) { + deps.push(ctx.reqv(|v| { + flowey_lib_common::install_dist_pkg::Request::Install { + package_names: vec![ + // a C toolchain and a working linker + "build-essential".into(), + // Linux UAPI headers, for the SQLite bundled by + // `libsqlite3-sys`. `build-essential` pulls this in + // transitively; it is named here so the reason it is + // needed is written down. + "linux-libc-dev".into(), + // for `openssl-sys` + "libssl-dev".into(), + "pkg-config".into(), + // for `prost` / `pbjson` + "protobuf-compiler".into(), + ], + done: v, + } + })); + } + + ctx.req(flowey_lib_common::install_rust::Request::InstallTargetTriple(target.clone())); + + // A commit under test is not a release, so it is assembled under a + // snapshot identity: a version that cannot be mistaken for one, with no + // tag. Everything else about the assembly and the build is what a + // packager does. + let openvmm_repo_path = ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir); + let resolved = ctx.emit_rust_stepv("resolve source archive identity", |ctx| { + let openvmm_repo_path = openvmm_repo_path.claim(ctx); + move |rt| { + let output_dir = std::env::current_dir()?.join("openvmm-source-release"); + let path = rt.read(openvmm_repo_path); + rt.sh.change_dir(path); + + Ok((identity.resolve(rt)?, output_dir)) + } + }); + let identity = resolved.clone().map(ctx, |(identity, _)| identity); + let output_dir = resolved.map(ctx, |(_, output_dir)| output_dir); + + let assembled = ctx.reqv(|done| crate::assemble_openvmm_source_release::Request { + identity: identity.clone(), + output_dir: output_dir.clone(), + done, + }); + let output_dir = output_dir.depending_on(ctx, &assembled); + + ctx.emit_rust_step("build openvmm in a distribution configuration", |ctx| { + done.claim(ctx); + deps.claim(ctx); + let identity = identity.claim(ctx); + let output_dir = output_dir.claim(ctx); + move |rt| { + let identity = rt.read(identity); + let output_dir = rt.read(output_dir); + + // A packager starts by checking the archive against the + // checksums shipped alongside it, so start there too. + rt.sh.change_dir(&output_dir); + flowey::shell_cmd!(rt, "sha256sum --check --strict {CHECKSUM_FILE}").run()?; + + // Unpack the archive exactly as a packager would, into a + // directory outside the repository so nothing can reach back + // into the checkout. + let build_root = std::env::current_dir()?.join("distro-build"); + if build_root.exists() { + fs_err::remove_dir_all(&build_root)?; + } + fs_err::create_dir_all(&build_root)?; + let archive = output_dir.join(identity.archive_name()); + flowey::shell_cmd!(rt, "tar -xf {archive} -C {build_root}").run()?; + + let source_dir = build_root.join(identity.source_root()); + if source_dir.join(".git").exists() { + anyhow::bail!("the source archive must not contain a .git directory"); + } + + // The archive carries its own identity, which is how a packager + // recovers a version without a `.git` directory. If that were + // missing or wrong, the build would still succeed and the + // package would be labelled incorrectly. Compare the whole + // document rather than just the version: this is the only place + // the metadata contract is exercised end to end. + let metadata_path = source_dir.join(METADATA_FILE); + let metadata: serde_json::Value = + serde_json::from_slice(&fs_err::read(&metadata_path)?) + .with_context(|| format!("failed to parse {}", metadata_path.display()))?; + let expected = expected_metadata(&identity); + if metadata != expected { + anyhow::bail!( + "the source archive declares {metadata}, but it was assembled as {expected}" + ); + } + + rt.sh.change_dir(&source_dir); + + // `.cargo/config.toml` points `PROTOC` into `.packages/`. It + // does not set `force`, so an inherited `PROTOC` takes + // precedence, which is what lets a packager redirect it at the + // system compiler. + let protoc = flowey::shell_cmd!(rt, "which protoc").read()?; + let protoc = protoc.trim(); + + let target = target.to_string(); + // Build the way a packager does. A spec file builds the release + // profile, so building anything else here would leave + // release-only code -- `#[cfg(not(debug_assertions))]` blocks + // in particular -- never compiled by this gate. + flowey::shell_cmd!( + rt, + "cargo build --release --locked -p openvmm --target {target}" + ) + .env("PROTOC", protoc) + // Link the system OpenSSL rather than building a vendored + // copy. Nothing in `openvmm`'s tree enables `openssl-sys`'s + // `vendored` feature today, so this is currently inert -- + // it is set because a packager sets it, and because it + // becomes load-bearing the moment something turns that + // feature on. + .env("OPENSSL_NO_VENDOR", "1") + // The workspace's release profile carries debug info, which + // is the binding constraint on runner disk. Nothing debugs + // this artifact. + .env("CARGO_PROFILE_RELEASE_DEBUG", "0") + .env("CARGO_INCREMENTAL", "0") + .run()?; + + // Building is not enough. If `openssl-sys` were to start + // building a vendored copy, or if some dependency were to + // acquire a static native library, the build would still + // succeed but the packaged binary would no longer be one the + // distribution can service. Assert the shape of the result. + // + // Read the binary's own `NEEDED` entries rather than `ldd`'s + // output: `ldd` reports the whole transitive closure, so it + // would still be satisfied if `openvmm` linked a static + // OpenSSL while some unrelated shared library pulled in the + // system one. + let binary = format!("target/{target}/release/openvmm"); + let linkage = flowey::shell_cmd!(rt, "readelf -d {binary}").read()?; + for lib in ["libssl.so", "libcrypto.so"] { + let needed = linkage + .lines() + .filter(|line| line.contains("(NEEDED)")) + .any(|line| line.contains(lib)); + + if !needed { + anyhow::bail!( + "openvmm did not link the system {lib}; \ + a distribution build must use the distribution's OpenSSL.\n\ + readelf -d output:\n{linkage}" + ); + } + } + + Ok(()) + } + }); + + Ok(()) + } +} diff --git a/flowey/flowey_lib_hvlite/src/_jobs/mod.rs b/flowey/flowey_lib_hvlite/src/_jobs/mod.rs index be79bee33d..f71bc07a8b 100644 --- a/flowey/flowey_lib_hvlite/src/_jobs/mod.rs +++ b/flowey/flowey_lib_hvlite/src/_jobs/mod.rs @@ -17,6 +17,7 @@ pub mod cfg_hvlite_reposource; pub mod cfg_nix; pub mod cfg_versions; pub mod check_clippy; +pub mod check_distro_build; pub mod check_openvmm_hcl_size; pub mod check_xtask_fmt; pub mod consolidate_and_publish_gh_pages; diff --git a/flowey/flowey_lib_hvlite/src/assemble_openvmm_source_release.rs b/flowey/flowey_lib_hvlite/src/assemble_openvmm_source_release.rs new file mode 100644 index 0000000000..16bd7434a3 --- /dev/null +++ b/flowey/flowey_lib_hvlite/src/assemble_openvmm_source_release.rs @@ -0,0 +1,261 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +//! Assemble the OpenVMM source release. +//! +//! This produces the files a source release consists of: a `.tar.gz` of the +//! tracked source at a single revision, and a `SHA256SUMS` covering it. The +//! archive carries its identity in a `.openvmm-release.json` file, because a +//! packager building it has no `.git` directory to recover a version from. +//! +//! Assembly is reproducible: `git archive` emits a deterministic tar for a +//! given commit, and `gzip -n` omits the timestamp that would otherwise vary. +//! Two jobs handed the same [`SourceIdentity`] at the same commit therefore +//! produce the same bytes, so a consumer of this node never has to be handed an +//! archive to be sure it has the same one. + +use flowey::node::prelude::*; + +/// Checksums covering every assembled asset. +pub const CHECKSUM_FILE: &str = "SHA256SUMS"; + +/// Release identity, carried inside the archive itself. +pub const METADATA_FILE: &str = ".openvmm-release.json"; + +const METADATA_SCHEMA_VERSION: u32 = 1; + +/// The identity of a source release. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] +pub struct SourceIdentity { + /// Three-component version, e.g. `0.12.3`. + pub version: String, + /// The release tag, absent for an archive that is not a release. + pub tag: Option, + /// The full commit the archive was produced from. + pub revision: String, +} + +impl SourceIdentity { + /// The name of the directory at the root of the archive. + pub fn source_root(&self) -> String { + format!("openvmm-{}", self.version) + } + + /// The name of the source archive. + pub fn archive_name(&self) -> String { + format!("{}-source.tar.gz", self.source_root()) + } +} + +#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)] +struct ReleaseMetadata { + schema_version: u32, + version: String, + #[serde(skip_serializing_if = "Option::is_none")] + tag: Option, + revision: String, +} + +impl From<&SourceIdentity> for ReleaseMetadata { + fn from(identity: &SourceIdentity) -> Self { + Self { + schema_version: METADATA_SCHEMA_VERSION, + version: identity.version.clone(), + tag: identity.tag.clone(), + revision: identity.revision.clone(), + } + } +} + +flowey_request! { + pub struct Request { + /// Identity to embed in the release. + pub identity: ReadVar, + /// Directory to assemble the release assets into. Created if absent. + pub output_dir: ReadVar, + pub done: WriteVar, + } +} + +new_simple_flow_node!(struct Node); + +impl SimpleFlowNode for Node { + type Request = Request; + + fn imports(ctx: &mut ImportCtx<'_>) { + ctx.import::(); + } + + fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> { + let Request { + identity, + output_dir, + done, + } = request; + + let openvmm_repo_path = ctx.reqv(crate::git_checkout_openvmm_repo::req::GetRepoDir); + + ctx.emit_rust_step("assemble OpenVMM source release", |ctx| { + done.claim(ctx); + let openvmm_repo_path = openvmm_repo_path.claim(ctx); + let identity = identity.claim(ctx); + let output_dir = output_dir.claim(ctx); + move |rt| { + let identity = rt.read(identity); + let output_dir = rt.read(output_dir); + let repo_path = rt.read(openvmm_repo_path); + + fs_err::create_dir_all(&output_dir)?; + rt.sh.change_dir(&repo_path); + + // `git archive` exports the tree at HEAD, so an uncommitted + // change would silently not appear in the archive. That would + // publish something other than what was built and tested. + let dirty = + flowey::shell_cmd!(rt, "git status --porcelain --untracked-files=no").read()?; + if !dirty.trim().is_empty() { + anyhow::bail!( + "refusing to assemble a source release from a dirty working tree; \ + the archive would not match HEAD.\nmodified:\n{dirty}" + ); + } + + // Staged outside the archive and injected by `git archive`, + // which keeps assembly to a single pass over the tree. + let metadata_dir = output_dir.join("metadata"); + if metadata_dir.exists() { + fs_err::remove_dir_all(&metadata_dir)?; + } + fs_err::create_dir_all(&metadata_dir)?; + let metadata_path = metadata_dir.join(METADATA_FILE); + let mut metadata_json = + serde_json::to_vec_pretty(&ReleaseMetadata::from(&identity))?; + metadata_json.push(b'\n'); + fs_err::write(&metadata_path, metadata_json)?; + + // `--add-file` places the file at the basename, under the + // preceding `--prefix`, so the ordering here matters. + // + // `tar.umask` masks the mode of every entry, so pin it rather + // than inheriting whatever the machine has configured. This is + // the same class of hazard as `tar.tgz.command` below. + let prefix = format!("{}/", identity.source_root()); + let source_tar = output_dir.join("openvmm-source.tar"); + flowey::shell_cmd!( + rt, + "git -c tar.umask=0002 archive --format=tar --output {source_tar} --prefix={prefix} --add-file={metadata_path} HEAD" + ) + .run()?; + fs_err::remove_dir_all(&metadata_dir)?; + + // `-n` omits the timestamp and original name from the gzip + // header, which is what makes the result reproducible. Do not + // use `git archive --format=tar.gz`: it defers to the + // `tar.tgz.command` config, so reproducibility would depend on + // the machine's git configuration. + let source_archive = output_dir.join(identity.archive_name()); + let compressed = flowey::shell_cmd!(rt, "gzip -n --best --stdout {source_tar}") + .output()?; + fs_err::write(&source_archive, compressed.stdout)?; + fs_err::remove_file(source_tar)?; + + // Checksums are a published asset, so generate them here rather + // than in the publishing job. That way CI verifies the same + // file a consumer will check against. + let archive_name = identity.archive_name(); + rt.sh.change_dir(&output_dir); + let checksums = flowey::shell_cmd!(rt, "sha256sum {archive_name}").output()?; + fs_err::write(output_dir.join(CHECKSUM_FILE), checksums.stdout)?; + + Ok(()) + } + }); + + Ok(()) + } +} + +/// The metadata an archive assembled under `identity` declares. +pub fn expected_metadata(identity: &SourceIdentity) -> serde_json::Value { + serde_json::to_value(ReleaseMetadata::from(identity)).expect("release metadata is plain data") +} + +/// Which identity a source release is assembled under. +/// +/// A commit under test is not a release, so it is assembled under a version +/// that cannot be mistaken for one, with no tag. Everything else about the +/// assembly is what a release does. +#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq)] +pub enum IdentitySource { + /// A commit under test, which is not a release. + Snapshot, +} + +/// Version used for an archive that is not a release. +const SNAPSHOT_VERSION: &str = "0.0.0-dev"; + +impl IdentitySource { + /// Resolve the identity to assemble under. + /// + /// The working directory must already be the OpenVMM repository. + pub fn resolve(self, rt: &mut RustRuntimeServices<'_>) -> anyhow::Result { + let revision = flowey::shell_cmd!(rt, "git rev-parse HEAD").read()?; + + let (version, tag) = match self { + IdentitySource::Snapshot => (SNAPSHOT_VERSION.to_owned(), None), + }; + + Ok(SourceIdentity { + version, + tag, + revision, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn identity(version: &str, tag: Option<&str>) -> SourceIdentity { + SourceIdentity { + version: version.into(), + tag: tag.map(Into::into), + revision: "0123456789abcdef0123456789abcdef01234567".into(), + } + } + + #[test] + fn asset_names_follow_the_version() { + let identity = identity("0.12.3", Some("openvmm-v0.12.3")); + assert_eq!(identity.source_root(), "openvmm-0.12.3"); + assert_eq!(identity.archive_name(), "openvmm-0.12.3-source.tar.gz"); + } + + #[test] + fn release_metadata_matches_source_bundle_schema() { + let metadata = ReleaseMetadata::from(&identity("0.12.3", Some("openvmm-v0.12.3"))); + assert_eq!( + serde_json::to_value(metadata).unwrap(), + serde_json::json!({ + "schema_version": 1, + "version": "0.12.3", + "tag": "openvmm-v0.12.3", + "revision": "0123456789abcdef0123456789abcdef01234567", + }) + ); + } + + #[test] + fn untagged_metadata_omits_the_tag() { + let metadata = ReleaseMetadata::from(&identity("0.0.0-dev", None)); + assert_eq!( + serde_json::to_value(metadata).unwrap(), + serde_json::json!({ + "schema_version": 1, + "version": "0.0.0-dev", + "revision": "0123456789abcdef0123456789abcdef01234567", + }) + ); + } +} diff --git a/flowey/flowey_lib_hvlite/src/lib.rs b/flowey/flowey_lib_hvlite/src/lib.rs index b9d4afa76f..390dda0d7c 100644 --- a/flowey/flowey_lib_hvlite/src/lib.rs +++ b/flowey/flowey_lib_hvlite/src/lib.rs @@ -8,6 +8,7 @@ pub mod _jobs; pub mod artifact_openvmm_hcl_sizecheck; +pub mod assemble_openvmm_source_release; pub mod build_and_test_vmgs_lib; pub mod build_guest_test_uefi; pub mod build_guide;