From 58a430767ddfa9d40fd1f4d0154f8e24b2a1d030 Mon Sep 17 00:00:00 2001 From: Max042004 Date: Tue, 9 Jun 2026 11:31:10 +0800 Subject: [PATCH] ci: add self-hosted macOS HVF runtime job Hypervisor.framework needs real Apple Silicon hardware, so the hosted build-macos job can only compile elfuse and check the entitlement, never boot a guest. Add a runtime-macos job on a self-hosted Apple Silicon runner ([self-hosted, macOS, arm64]) that actually exercises the VM under HVF. The job is scoped to the upstream repository with github.repository == 'sysprog21/elfuse', so it runs for pushes to main and for pull_requests targeting main -- including PRs opened from a collaborator's fork -- but never inside a fork's own Actions context, so a branch pushed to a fork without an upstream PR triggers nothing. Untrusted outside fork PRs are held by the repository's "require approval for outside collaborators" setting, so a maintainer still gates every outside run without needing a head-ref guard or a label. The job runs after build-macos, serializes per ref through a concurrency group, and cancels in-progress runs only for pull requests. It asserts the host is arm64, reports kern.hv_support, caches and installs just the missing Homebrew packages (binutils, qemu), and fails early with install guidance when Rosetta for Linux is absent. After make elfuse it confirms the com.apple.security.hypervisor entitlement is codesigned into build/elfuse, then runs test-hello, test-multi-vcpu, make check, and tests/test-matrix.sh all. --- .github/workflows/main.yml | 104 +++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 54f286f..511a853 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -259,3 +259,107 @@ jobs: path: build/scan-build retention-days: 7 if-no-files-found: ignore + runtime-macos: + name: Runtime (macOS Apple Silicon, HVF) + needs: build-macos + if: > + github.repository == 'sysprog21/elfuse' && + (github.event_name == 'push' || github.event_name == 'pull_request') + runs-on: [self-hosted, macOS, arm64] + timeout-minutes: 60 + + concurrency: + group: runtime-macos-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + + env: + LINUX_TOOLCHAIN: /opt/toolchain/aarch64-linux-gnu + GNU_OBJCOPY: /opt/homebrew/opt/binutils/bin/objcopy + HOMEBREW_NO_INSTALL_CLEANUP: 1 + HOMEBREW_NO_AUTO_UPDATE: 1 + BREW_PKGS: binutils qemu + + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Host info + run: | + sw_vers + uname -a + uname -m + sysctl kern.hv_support || true + test "$(uname -m)" = "arm64" + + - name: Cache Homebrew downloads + uses: actions/cache@v5 + with: + path: ~/Library/Caches/Homebrew/downloads + key: brew-runtime-${{ runner.os }}-${{ runner.arch }}-${{ env.BREW_PKGS }} + + - name: Install missing Homebrew packages + run: | + missing=() + + for pkg in $BREW_PKGS; do + if ! brew list --formula "$pkg" >/dev/null 2>&1; then + missing+=("$pkg") + fi + done + + if [ "${#missing[@]}" -gt 0 ]; then + brew install --quiet "${missing[@]}" + else + echo "All Homebrew packages are already installed: $BREW_PKGS" + fi + + - name: Tool versions + run: | + command -v make + command -v "$GNU_OBJCOPY" + make -V .MAKE.VERSION 2>/dev/null || true + "$GNU_OBJCOPY" --version | head -1 + qemu-aarch64 --version | head -1 || true + python3 --version + + - name: Check Rosetta for Linux + run: | + ROSETTA=/Library/Apple/usr/libexec/oah/RosettaLinux/rosetta + + if [ ! -x "$ROSETTA" ]; then + echo "::error::Rosetta for Linux runtime was not found at $ROSETTA" + echo + echo "Install Rosetta on the self-hosted Mac runner first:" + echo " sudo softwareupdate --install-rosetta --agree-to-license" + echo + echo "Current /Library/Apple/usr/libexec/oah contents:" + ls -R /Library/Apple/usr/libexec/oah || true + exit 1 + fi + + ls -l "$ROSETTA" + + - name: Build elfuse + run: | + make elfuse + + - name: Verify HVF entitlement is embedded + run: | + codesign -d --entitlements - build/elfuse 2>&1 \ + | grep -q 'com\.apple\.security\.hypervisor' + + - name: test-hello + run: | + make test-hello + + - name: test-multi-vcpu + run: | + make test-multi-vcpu + + - name: make check + run: | + make check + + - name: Test matrix + run: | + bash tests/test-matrix.sh all