Skip to content

release: vz v0.3.18 #21

release: vz v0.3.18

release: vz v0.3.18 #21

Workflow file for this run

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