release: vz v0.3.18 #21
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| push: | |
| tags: | |
| - "v*" | |
| workflow_dispatch: | |
| permissions: | |
| contents: write | |
| jobs: | |
| validate-release-version: | |
| name: Validate tag matches Cargo version | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.ref_name }} | |
| - name: Verify Cargo.lock is tracked | |
| run: git ls-files --error-unmatch crates/Cargo.lock >/dev/null | |
| - name: Ensure tag matches vz-cli Cargo.toml version | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| env: | |
| TAG: ${{ github.ref_name }} | |
| run: | | |
| TAG_VERSION="${TAG#v}" | |
| CARGO_VERSION="$(awk -F '"' '/^version = / {print $2; exit}' crates/vz-cli/Cargo.toml)" | |
| if [ -z "$CARGO_VERSION" ]; then | |
| echo "Could not read package version from crates/vz-cli/Cargo.toml" >&2 | |
| exit 1 | |
| fi | |
| if [ "$TAG_VERSION" != "$CARGO_VERSION" ]; then | |
| echo "Tag version ($TAG_VERSION) does not match vz-cli Cargo.toml version ($CARGO_VERSION)." >&2 | |
| echo "Bump version, run cargo check, commit Cargo.lock, then retag." >&2 | |
| exit 1 | |
| fi | |
| build-macos: | |
| name: Build + sign macOS binary (darwin-arm64) | |
| runs-on: macos-14 | |
| needs: validate-release-version | |
| environment: release | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Cache Rust | |
| uses: Swatinem/rust-cache@v2 | |
| with: | |
| workspaces: crates | |
| - name: Build release binaries | |
| run: | | |
| cd crates | |
| cargo build --release -p vz-cli | |
| cargo build --release -p vz-runtimed | |
| cargo build --release -p vz-guest-agent | |
| - name: Import code signing certificate | |
| env: | |
| CERTIFICATE_BASE64: ${{ secrets.APPLE_CERTIFICATE }} | |
| CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} | |
| run: | | |
| CERTIFICATE_PATH="$RUNNER_TEMP/build_certificate.p12" | |
| KEYCHAIN_PATH="$RUNNER_TEMP/app-signing.keychain-db" | |
| if [ -z "$CERTIFICATE_BASE64" ] || [ -z "$CERTIFICATE_PASSWORD" ] || [ -z "$KEYCHAIN_PASSWORD" ]; then | |
| echo "Missing required signing secrets." >&2 | |
| exit 1 | |
| fi | |
| echo -n "$CERTIFICATE_BASE64" | base64 --decode > "$CERTIFICATE_PATH" || \ | |
| echo -n "$CERTIFICATE_BASE64" | base64 -D > "$CERTIFICATE_PATH" | |
| security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" | |
| security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security import "$CERTIFICATE_PATH" -P "$CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH" | |
| security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| security list-keychain -d user -s "$KEYCHAIN_PATH" | |
| echo "KEYCHAIN_PATH=$KEYCHAIN_PATH" >> "$GITHUB_ENV" | |
| - name: Sign vz-cli with Developer ID | |
| env: | |
| APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} | |
| run: | | |
| codesign --sign "$APPLE_SIGNING_IDENTITY" \ | |
| --keychain "$KEYCHAIN_PATH" \ | |
| --entitlements entitlements/vz-cli.entitlements.plist \ | |
| --options runtime \ | |
| --timestamp \ | |
| --force \ | |
| crates/target/release/vz | |
| codesign --verify --verbose crates/target/release/vz | |
| echo "vz-cli signed successfully" | |
| - name: Sign vz-runtimed with Developer ID | |
| env: | |
| APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} | |
| run: | | |
| codesign --sign "$APPLE_SIGNING_IDENTITY" \ | |
| --keychain "$KEYCHAIN_PATH" \ | |
| --entitlements entitlements/vz-cli.entitlements.plist \ | |
| --options runtime \ | |
| --timestamp \ | |
| --force \ | |
| crates/target/release/vz-runtimed | |
| codesign --verify --verbose crates/target/release/vz-runtimed | |
| echo "vz-runtimed signed successfully" | |
| - name: Sign vz-guest-agent (ad-hoc, no entitlements) | |
| run: | | |
| codesign --sign - --force crates/target/release/vz-guest-agent | |
| codesign --verify --verbose crates/target/release/vz-guest-agent | |
| - name: Notarize vz-cli and vz-runtimed | |
| env: | |
| APPLE_ID: ${{ secrets.APPLE_ID }} | |
| APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }} | |
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
| run: | | |
| # Notarize vz-cli | |
| ditto -c -k --keepParent crates/target/release/vz vz-notarize.zip | |
| xcrun notarytool submit vz-notarize.zip \ | |
| --apple-id "$APPLE_ID" \ | |
| --password "$APPLE_APP_SPECIFIC_PASSWORD" \ | |
| --team-id "$APPLE_TEAM_ID" \ | |
| --wait | |
| rm vz-notarize.zip | |
| # Notarize vz-runtimed | |
| ditto -c -k --keepParent crates/target/release/vz-runtimed vz-runtimed-notarize.zip | |
| xcrun notarytool submit vz-runtimed-notarize.zip \ | |
| --apple-id "$APPLE_ID" \ | |
| --password "$APPLE_APP_SPECIFIC_PASSWORD" \ | |
| --team-id "$APPLE_TEAM_ID" \ | |
| --wait | |
| rm vz-runtimed-notarize.zip | |
| echo "Notarization complete" | |
| - name: Prepare release artifacts | |
| env: | |
| TAG: ${{ startsWith(github.ref, 'refs/tags/v') && github.ref_name || format('vdev-{0}', github.run_number) }} | |
| run: | | |
| VERSION="${TAG#v}" | |
| mkdir -p dist | |
| cp crates/target/release/vz "dist/vz-v${VERSION}-darwin-arm64" | |
| chmod +x "dist/vz-v${VERSION}-darwin-arm64" | |
| shasum -a 256 "dist/vz-v${VERSION}-darwin-arm64" > "dist/vz-v${VERSION}-darwin-arm64.sha256" | |
| cp crates/target/release/vz-runtimed "dist/vz-runtimed-v${VERSION}-darwin-arm64" | |
| chmod +x "dist/vz-runtimed-v${VERSION}-darwin-arm64" | |
| shasum -a 256 "dist/vz-runtimed-v${VERSION}-darwin-arm64" > "dist/vz-runtimed-v${VERSION}-darwin-arm64.sha256" | |
| cp crates/target/release/vz-guest-agent "dist/vz-guest-agent-v${VERSION}-darwin-arm64" | |
| chmod +x "dist/vz-guest-agent-v${VERSION}-darwin-arm64" | |
| shasum -a 256 "dist/vz-guest-agent-v${VERSION}-darwin-arm64" > "dist/vz-guest-agent-v${VERSION}-darwin-arm64.sha256" | |
| - name: Upload release artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-darwin-arm64 | |
| path: dist/* | |
| retention-days: 7 | |
| - name: Cleanup keychain | |
| if: always() | |
| run: | | |
| if [ -n "${KEYCHAIN_PATH:-}" ] && [ -f "$KEYCHAIN_PATH" ]; then | |
| security delete-keychain "$KEYCHAIN_PATH" | |
| fi | |
| build-linux-artifacts: | |
| name: Build Linux profile artifacts | |
| runs-on: ubuntu-24.04-arm | |
| needs: validate-release-version | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Cache developer Linux kernel image | |
| id: linux-developer-kernel-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: linux/out/vmlinux | |
| key: linux-kernel-developer-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('linux/kernel-version.mk', 'linux/Dockerfile', 'linux/vz-linux.config') }} | |
| - name: Cache container Linux kernel image | |
| id: linux-container-kernel-cache | |
| uses: actions/cache@v4 | |
| with: | |
| path: linux/out/container/vmlinux | |
| key: linux-kernel-container-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('linux/kernel-version.mk', 'linux/Dockerfile', 'linux/vz-linux-container.config') }} | |
| - name: Build missing Linux kernel images via Docker | |
| run: | | |
| cd linux | |
| docker build -t vz-linux-builder . | |
| for profile in developer container; do | |
| out_dir="out" | |
| if [ "$profile" = "container" ]; then | |
| out_dir="out/container" | |
| fi | |
| if [ -s "$out_dir/vmlinux" ]; then | |
| echo "Using cached $profile kernel image" | |
| continue | |
| fi | |
| docker run --rm \ | |
| -v "$(cd .. && pwd):/workspace" \ | |
| -w /workspace/linux \ | |
| vz-linux-builder \ | |
| make kernel KERNEL_PROFILE="$profile" CROSS_COMPILE= GUEST_AGENT_BUILD_TOOL=cargo | |
| done | |
| - name: Build Linux userland bundles via Docker | |
| run: | | |
| cd linux | |
| docker run --rm \ | |
| -v "$(cd .. && pwd):/workspace" \ | |
| -w /workspace/linux \ | |
| vz-linux-builder \ | |
| make all-profiles TRUST_EXISTING_KERNEL_IMAGE=1 CROSS_COMPILE= GUEST_AGENT_BUILD_TOOL=cargo | |
| - name: Validate Linux artifact metadata | |
| run: | | |
| for version_json in linux/out/version.json linux/out/container/version.json; do | |
| jq -e ' | |
| .kernel and | |
| .profile and | |
| .security_profile and | |
| .agent and | |
| .agent_protocol_revision and | |
| .youki and | |
| .sha256_vmlinux and | |
| .sha256_initramfs and | |
| .sha256_youki and | |
| ((.capabilities // []) | index("vsock")) and | |
| ((.capabilities // []) | index("virtiofs")) and | |
| ((.capabilities // []) | index("hvc0_serial")) and | |
| ((.capabilities // []) | index("ext4_root")) and | |
| ((.capabilities // []) | index("overlayfs")) and | |
| ((.capabilities // []) | index("netns")) and | |
| ((.capabilities // []) | index("seccomp")) and | |
| ((.capabilities // []) | index("io_uring")) and | |
| ((.capabilities // []) | index("btrfs_snapshots")) and | |
| ((.capabilities // []) | index("device_mapper")) and | |
| ((.capabilities // []) | index("dm_crypt")) | |
| ' "$version_json" >/dev/null | |
| done | |
| jq -e ' | |
| .profile == "developer" and | |
| .security_profile == "developer-nested-virt" and | |
| ((.capabilities // []) | index("nested_virt")) and | |
| ((.capabilities // []) | index("tun")) | |
| ' linux/out/version.json >/dev/null | |
| jq -e ' | |
| .profile == "container" and | |
| .security_profile == "container-hardened" and | |
| ((.capabilities // []) | index("nfsd")) and | |
| ((.capabilities // []) | index("container_sandbox")) | |
| ' linux/out/container/version.json >/dev/null | |
| - name: Package Linux artifacts | |
| env: | |
| TAG: ${{ startsWith(github.ref, 'refs/tags/v') && github.ref_name || format('vdev-{0}', github.run_number) }} | |
| run: | | |
| VERSION="${TAG#v}" | |
| mkdir -p dist | |
| # Keep the historical artifact name mapped to the developer profile | |
| # so existing installers continue to work. | |
| tar czf "dist/vz-linux-v${VERSION}-arm64.tar.gz" \ | |
| -C linux/out \ | |
| vmlinux initramfs.img youki version.json | |
| sha256sum "dist/vz-linux-v${VERSION}-arm64.tar.gz" > "dist/vz-linux-v${VERSION}-arm64.tar.gz.sha256" | |
| tar czf "dist/vz-linux-developer-v${VERSION}-arm64.tar.gz" \ | |
| -C linux/out \ | |
| vmlinux initramfs.img youki version.json | |
| sha256sum "dist/vz-linux-developer-v${VERSION}-arm64.tar.gz" > "dist/vz-linux-developer-v${VERSION}-arm64.tar.gz.sha256" | |
| tar czf "dist/vz-linux-container-v${VERSION}-arm64.tar.gz" \ | |
| -C linux/out/container \ | |
| vmlinux initramfs.img youki version.json | |
| sha256sum "dist/vz-linux-container-v${VERSION}-arm64.tar.gz" > "dist/vz-linux-container-v${VERSION}-arm64.tar.gz.sha256" | |
| - name: Upload Linux artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-linux-artifacts | |
| path: dist/* | |
| retention-days: 7 | |
| publish-release: | |
| name: Publish GitHub Release | |
| runs-on: ubuntu-latest | |
| needs: [build-macos, build-linux-artifacts] | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| ref: ${{ github.ref_name }} | |
| - name: Download macOS artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: release-darwin-arm64 | |
| path: dist | |
| - name: Download Linux artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: release-linux-artifacts | |
| path: dist | |
| - name: Create or update release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| TAG: ${{ github.ref_name }} | |
| run: | | |
| if gh release view "$TAG" >/dev/null 2>&1; then | |
| echo "Release $TAG already exists; uploading updated assets." | |
| else | |
| gh release create "$TAG" \ | |
| --title "$TAG" \ | |
| --generate-notes | |
| fi | |
| gh release upload "$TAG" dist/* --clobber |