cargo-hyperlight 0.1.14

cargo subcommand to build hyperlight guest binaries
Documentation
# yaml-language-server: $schema=https://json.schemastore.org/github-action.json

name: CI
permissions:
  contents: read

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  workflow_call:

# Cancels old running job if a new one is triggered (e.g. by a push onto the same branch).
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  CARGO_TERM_COLOR: always

jobs:
  run-tests:
    name: Run tests on ${{ matrix.environment }} ${{ matrix.os }}
    strategy:
      matrix:
        os: [ "ubuntu-latest", "windows-latest" ]
        environment: [ "HL", "GH" ]
    runs-on: ${{ fromJson(
        matrix.environment == 'HL' &&
          format('["self-hosted", "{0}", "X64", "1ES.Pool=hld-{1}-amd", "JobId=cargo-hyperlight-{2}-{3}-{4}"]',
            matrix.os == 'windows-latest' && 'Windows' || 'Linux',
            matrix.os == 'windows-latest' && 'win2025' || 'kvm',
            github.run_id,
            github.run_number,
            github.run_attempt)
        || format('["{0}"]', matrix.os) ) }}
    steps:
    - uses: actions/checkout@v7
    - uses: actions-rust-lang/setup-rust-toolchain@v1
      with:
        # Don't let the action put `-D warnings` in RUSTFLAGS. cargo-hyperlight
        # builds third-party crates (e.g. hyperlight-guest-capi and its
        # dependencies) by manifest path, so cargo treats them as local crates
        # and does not apply `--cap-lints allow`. A warning in any of them would
        # then fail the build. Lints are enforced by the `check` job instead.
        rustflags: ""
    - uses: Swatinem/rust-cache@v2
    - uses: extractions/setup-just@v4
    - name: Enable kvm
      if: runner.os == 'Linux' && runner.arch == 'X64' && matrix.environment == 'GH'
      shell: bash
      run: |
        # Make /dev/kvm accessible to the unprivileged runner user.
        # On GitHub-hosted runners the device node is managed by udev, so install
        # a rule and re-trigger it. Containerised runners (e.g. `act`) have no
        # udev daemon, in which case fall back to setting the mode directly.
        if sudo udevadm control --ping > /dev/null 2>&1; then
          echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
          sudo udevadm control --reload-rules
          sudo udevadm trigger --name-match=kvm
        else
          echo "udev is not running, setting the mode of /dev/kvm directly"
          sudo chmod 666 /dev/kvm
        fi
        ls -l /dev/kvm
    - name: Install cargo-hyperlight
      shell: bash
      run: just install
    - name: Build guest example
      shell: bash
      run: just build-guest
    - name: Run example
      if: runner.arch == 'X64'
      shell: bash
      run: just run-guest
    - name: Build C guest example
      shell: bash
      run: just build-c-guest
    - name: Run C guest example
      shell: bash
      run: just run-c-guest
    - name: Run other tests
      shell: bash
      run: just test

  toolchain-support:
    name: Detect target spec support on Rust ${{ matrix.toolchain }}
    strategy:
      fail-fast: false
      matrix:
        include:
          # Custom target specifications, which describe the hyperlight guest
          # targets, are stable up to Rust 1.94 ...
          - toolchain: "1.94.0"
            expected: supported
          # ... were made unstable in 1.95, so stable releases from then on
          # cannot build a guest ...
          - toolchain: "1.95.0"
            expected: unsupported
          # ... but nightly can, behind `-Zunstable-options`.
          - toolchain: "nightly"
            expected: supported
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      # Builds cargo-hyperlight itself, so it uses the pinned toolchain from
      # rust-toolchain.toml rather than the one under test.
      - uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          # See the comment in the `run-tests` job.
          rustflags: ""
      - uses: Swatinem/rust-cache@v2
      - uses: extractions/setup-just@v4
      - name: Install cargo-hyperlight
        shell: bash
        run: just install
      - name: Install Rust ${{ matrix.toolchain }}
        shell: bash
        # cargo-hyperlight installs the rust-src component itself when it needs it.
        run: rustup toolchain install ${{ matrix.toolchain }} --profile minimal
      - name: Build a guest with Rust ${{ matrix.toolchain }}
        shell: bash
        env:
          RUSTUP_TOOLCHAIN: ${{ matrix.toolchain }}
          EXPECTED: ${{ matrix.expected }}
        run: |
          if just build-guest > build.log 2>&1; then
            actual=supported
          else
            actual=unsupported
          fi
          cat build.log

          if [ "$actual" != "$EXPECTED" ]; then
            echo "::error::expected this toolchain to be $EXPECTED, but the build reported it as $actual"
            exit 1
          fi

          # A toolchain we reject must be rejected up front, with the
          # diagnostic that tells the user how to fix it, rather than failing
          # somewhere deeper in the build.
          if [ "$EXPECTED" = unsupported ] &&
             ! grep -q "This toolchain cannot build for" build.log; then
            echo "::error::the build failed, but not with the expected diagnostic"
            exit 1
          fi

  spelling:
    name: Spell check with typos
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v7
    - name: Spell Check Repo
      uses: crate-ci/typos@master
  
  check:
    name: Lint on ${{ matrix.os }}
    strategy:
      matrix:
        os: ["ubuntu-latest", "windows-latest"]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v7
      - uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          components: rustfmt, clippy
          # See the comment in the `run-tests` job. `just fmt` and `just clippy`
          # pass `-D warnings` explicitly where it is wanted.
          rustflags: ""
      - uses: extractions/setup-just@v4
      - name: Setup nightly toolchain
        shell: bash
        run: rustup toolchain install nightly --component rustfmt # needed to run rustfmt in nightly toolchain
      - name: Install cargo-hyperlight
        shell: bash
        run: just install
      - name: Check formatting
        shell: bash
        run: just fmt
      - name: Check clippy
        shell: bash
        run: just clippy