This commit is contained in:
313
.github/actions/cache-benchmark-harness/action.yml
vendored
Normal file
313
.github/actions/cache-benchmark-harness/action.yml
vendored
Normal file
@@ -0,0 +1,313 @@
|
||||
name: Cache Benchmark Harness Binary
|
||||
description: >
|
||||
Build and cache the benchmark-harness binary with intelligent caching based on source hashes.
|
||||
Generates cache keys based on harness source + kreuzberg dependency + Cargo files,
|
||||
restores from cache if available, builds if needed, and saves to cache.
|
||||
Validates artifacts after restore or build to ensure integrity.
|
||||
|
||||
inputs:
|
||||
cache-version:
|
||||
description: "Manual version for cache invalidation"
|
||||
required: false
|
||||
default: "v1"
|
||||
|
||||
build-profile:
|
||||
description: "Build profile (release, debug)"
|
||||
required: false
|
||||
default: "release"
|
||||
|
||||
outputs:
|
||||
cache-hit:
|
||||
description: "Boolean indicating exact cache hit"
|
||||
value: ${{ steps.cache-restore.outputs.cache-hit }}
|
||||
|
||||
cache-key:
|
||||
description: "The cache key used"
|
||||
value: ${{ steps.generate-cache-key.outputs.cache-key }}
|
||||
|
||||
binary-path:
|
||||
description: "Path to the built/cached benchmark-harness binary"
|
||||
value: ${{ steps.validate-binary.outputs.binary-path }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
# Validate inputs
|
||||
- name: Validate inputs
|
||||
shell: bash
|
||||
env:
|
||||
BUILD_PROFILE: ${{ inputs.build-profile }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
# Validate build profile
|
||||
valid_profiles=("release" "debug")
|
||||
if [[ ! " ${valid_profiles[@]} " =~ " ${BUILD_PROFILE} " ]]; then
|
||||
echo "❌ Error: build-profile must be one of: ${valid_profiles[*]}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✓ Validation passed"
|
||||
echo " Build profile: $BUILD_PROFILE"
|
||||
echo " Cache version: ${{ inputs.cache-version }}"
|
||||
|
||||
# Compute hash for benchmark-harness sources
|
||||
- name: Compute benchmark-harness source hash
|
||||
id: harness-hash
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
echo "=== Computing Benchmark Harness Source Hash ==="
|
||||
|
||||
# Compute hash for harness source files and Cargo.toml
|
||||
HARNESS_HASH=$(scripts/ci/cache/compute-hash.sh \
|
||||
"tools/benchmark-harness/src/**" \
|
||||
"tools/benchmark-harness/Cargo.toml" \
|
||||
2>&1 | grep "^[a-f0-9]*$")
|
||||
|
||||
if [[ -z "$HARNESS_HASH" ]]; then
|
||||
echo "❌ Failed to compute harness source hash"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "harness-hash=$HARNESS_HASH" >> "$GITHUB_OUTPUT"
|
||||
echo "✓ Harness source hash: $HARNESS_HASH"
|
||||
|
||||
# Compute hash for kreuzberg dependency
|
||||
- name: Compute kreuzberg dependency hash
|
||||
id: kreuzberg-hash
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
echo "=== Computing Kreuzberg Dependency Hash ==="
|
||||
|
||||
# Compute hash for kreuzberg crate (dependency)
|
||||
KREUZBERG_HASH=$(scripts/ci/cache/compute-hash.sh --dirs \
|
||||
"crates/kreuzberg" \
|
||||
2>&1 | grep "^[a-f0-9]*$")
|
||||
|
||||
if [[ -z "$KREUZBERG_HASH" ]]; then
|
||||
echo "❌ Failed to compute kreuzberg dependency hash"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "kreuzberg-hash=$KREUZBERG_HASH" >> "$GITHUB_OUTPUT"
|
||||
echo "✓ Kreuzberg dependency hash: $KREUZBERG_HASH"
|
||||
|
||||
# Compute hash for Cargo files
|
||||
- name: Compute Cargo files hash
|
||||
id: cargo-hash
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
echo "=== Computing Cargo Files Hash ==="
|
||||
|
||||
# Compute hash for Cargo.lock
|
||||
CARGO_HASH=$(scripts/ci/cache/compute-hash.sh --files Cargo.lock 2>&1 | grep "^[a-f0-9]*$")
|
||||
|
||||
if [[ -z "$CARGO_HASH" ]]; then
|
||||
echo "❌ Failed to compute Cargo files hash"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "cargo-hash=$CARGO_HASH" >> "$GITHUB_OUTPUT"
|
||||
echo "✓ Cargo files hash: $CARGO_HASH"
|
||||
|
||||
# Generate cache key
|
||||
- name: Generate cache key
|
||||
id: generate-cache-key
|
||||
shell: bash
|
||||
env:
|
||||
BUILD_PROFILE: ${{ inputs.build-profile }}
|
||||
HARNESS_HASH: ${{ steps.harness-hash.outputs.harness-hash }}
|
||||
KREUZBERG_HASH: ${{ steps.kreuzberg-hash.outputs.kreuzberg-hash }}
|
||||
CARGO_HASH: ${{ steps.cargo-hash.outputs.cargo-hash }}
|
||||
CACHE_VERSION: ${{ inputs.cache-version }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
echo "=== Cache Key Generated ==="
|
||||
|
||||
# Build cache key following format:
|
||||
# harness-{profile}-{platform}-src-{harness-hash}-kreuzberg-{kreuzberg-hash}-cargo-{cargo-hash}-v{version}
|
||||
CACHE_KEY="harness-${BUILD_PROFILE}-$(uname -m)-src-${HARNESS_HASH}-kreuzberg-${KREUZBERG_HASH}-cargo-${CARGO_HASH}-${CACHE_VERSION}"
|
||||
|
||||
echo "cache-key=$CACHE_KEY" >> "$GITHUB_OUTPUT"
|
||||
|
||||
echo "Full key: $CACHE_KEY"
|
||||
echo ""
|
||||
echo "Key components:"
|
||||
echo " Profile: $BUILD_PROFILE"
|
||||
echo " Platform: $(uname -m)"
|
||||
echo " Harness hash: $HARNESS_HASH"
|
||||
echo " Kreuzberg hash: $KREUZBERG_HASH"
|
||||
echo " Cargo hash: $CARGO_HASH"
|
||||
echo " Cache version: $CACHE_VERSION"
|
||||
|
||||
# Determine target path based on profile
|
||||
- name: Determine target paths
|
||||
id: target-paths
|
||||
shell: bash
|
||||
env:
|
||||
BUILD_PROFILE: ${{ inputs.build-profile }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
echo "=== Determining Target Paths ==="
|
||||
|
||||
case "$BUILD_PROFILE" in
|
||||
release)
|
||||
TARGET_DIR="target/release"
|
||||
;;
|
||||
debug)
|
||||
TARGET_DIR="target/debug"
|
||||
;;
|
||||
*)
|
||||
echo "❌ Invalid build profile: $BUILD_PROFILE"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "target-dir=$TARGET_DIR" >> "$GITHUB_OUTPUT"
|
||||
echo "✓ Target directory: $TARGET_DIR"
|
||||
|
||||
# Detect architecture for cache keys (shell expansion doesn't work in YAML with: context)
|
||||
- name: Detect architecture
|
||||
id: detect-arch
|
||||
shell: bash
|
||||
run: echo "arch=$(uname -m)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Restore from cache
|
||||
- name: Restore benchmark-harness binary from cache
|
||||
id: cache-restore
|
||||
uses: kreuzberg-dev/actions/cache-binding-artifact@v1
|
||||
with:
|
||||
binding-name: benchmark-harness
|
||||
cache-key: ${{ steps.generate-cache-key.outputs.cache-key }}
|
||||
cache-restore-keys: |
|
||||
harness-${{ inputs.build-profile }}-${{ steps.detect-arch.outputs.arch }}-src-
|
||||
harness-${{ inputs.build-profile }}-${{ steps.detect-arch.outputs.arch }}-
|
||||
harness-${{ inputs.build-profile }}-
|
||||
cache-paths: |
|
||||
${{ steps.target-paths.outputs.target-dir }}/benchmark-harness
|
||||
operation: restore
|
||||
|
||||
# Log cache hit status
|
||||
- name: Log cache hit status
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
if [[ "${{ steps.cache-restore.outputs.cache-hit }}" == "true" ]]; then
|
||||
echo "✓ Cache HIT - benchmark-harness binary found in cache"
|
||||
else
|
||||
echo "✗ Cache MISS - Building benchmark-harness from source"
|
||||
fi
|
||||
|
||||
# Build if cache miss
|
||||
- name: Build benchmark-harness
|
||||
id: build
|
||||
if: steps.cache-restore.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
env:
|
||||
BUILD_PROFILE: ${{ inputs.build-profile }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
echo "=== Building Benchmark Harness ==="
|
||||
echo "Profile: $BUILD_PROFILE"
|
||||
|
||||
# Determine cargo build profile argument
|
||||
case "$BUILD_PROFILE" in
|
||||
release)
|
||||
BUILD_ARG="--release"
|
||||
;;
|
||||
debug)
|
||||
# Debug is default, no flag needed
|
||||
BUILD_ARG=""
|
||||
;;
|
||||
*)
|
||||
echo "❌ Invalid build profile: $BUILD_PROFILE"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Build benchmark-harness
|
||||
echo "Running: cargo build --manifest-path tools/benchmark-harness/Cargo.toml $BUILD_ARG"
|
||||
if ! cargo build --manifest-path tools/benchmark-harness/Cargo.toml $BUILD_ARG; then
|
||||
echo "❌ Build failed for benchmark-harness"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✓ Build succeeded"
|
||||
|
||||
# Validate binary exists and is executable
|
||||
- name: Validate benchmark-harness binary
|
||||
id: validate-binary
|
||||
shell: bash
|
||||
env:
|
||||
BUILD_PROFILE: ${{ inputs.build-profile }}
|
||||
TARGET_DIR: ${{ steps.target-paths.outputs.target-dir }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
echo "=== Validating Benchmark Harness Binary ==="
|
||||
|
||||
BINARY_PATH="${TARGET_DIR}/benchmark-harness"
|
||||
|
||||
# Check if binary exists
|
||||
if [[ ! -f "$BINARY_PATH" ]]; then
|
||||
echo "❌ Binary not found at: $BINARY_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if binary is executable
|
||||
if [[ ! -x "$BINARY_PATH" ]]; then
|
||||
echo "❌ Binary is not executable: $BINARY_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get binary size and info
|
||||
BINARY_SIZE=$(ls -lh "$BINARY_PATH" | awk '{print $5}')
|
||||
BINARY_PERMS=$(ls -l "$BINARY_PATH" | awk '{print $1}')
|
||||
|
||||
echo "binary-path=$BINARY_PATH" >> "$GITHUB_OUTPUT"
|
||||
|
||||
echo "✓ Binary validation passed"
|
||||
echo " Path: $BINARY_PATH"
|
||||
echo " Size: $BINARY_SIZE"
|
||||
echo " Permissions: $BINARY_PERMS"
|
||||
|
||||
# Save to cache if build occurred
|
||||
- name: Save benchmark-harness binary to cache
|
||||
if: steps.cache-restore.outputs.cache-hit != 'true'
|
||||
uses: kreuzberg-dev/actions/cache-binding-artifact@v1
|
||||
with:
|
||||
binding-name: benchmark-harness
|
||||
cache-key: ${{ steps.generate-cache-key.outputs.cache-key }}
|
||||
cache-paths: |
|
||||
${{ steps.target-paths.outputs.target-dir }}/benchmark-harness
|
||||
operation: save
|
||||
|
||||
# Summary
|
||||
- name: Summary
|
||||
if: always()
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
echo ""
|
||||
echo "=== Build and Cache Summary ==="
|
||||
echo "Build Profile: ${{ inputs.build-profile }}"
|
||||
echo "Platform: $(uname -m)"
|
||||
echo "Cache Hit: ${{ steps.cache-restore.outputs.cache-hit == 'true' && 'Yes' || 'No' }}"
|
||||
echo "Cache Key: ${{ steps.generate-cache-key.outputs.cache-key }}"
|
||||
echo "Binary Path: ${{ steps.validate-binary.outputs.binary-path }}"
|
||||
echo ""
|
||||
echo "Hashes:"
|
||||
echo " Harness: ${{ steps.harness-hash.outputs.harness-hash }}"
|
||||
echo " Kreuzberg: ${{ steps.kreuzberg-hash.outputs.kreuzberg-hash }}"
|
||||
echo " Cargo: ${{ steps.cargo-hash.outputs.cargo-hash }}"
|
||||
Reference in New Issue
Block a user