-
Notifications
You must be signed in to change notification settings - Fork 2.2k
feat(coprocessor): add local coverage tooling and pre-push hook #2095
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
ed2c0b4
test prepush
PanGan21 f7bf701
Merge branch 'panos/add-coverage-tool' into panos/pre-push-coverage
PanGan21 6c5be9f
Merge branch 'panos/add-coverage-tool' into panos/pre-push-coverage
PanGan21 55492b7
fix(coprocessor): improve summary report, warn user on installation a…
PanGan21 fd6e539
fix(common): allow to install any combination of pre push hooks from …
PanGan21 f3ff10d
fix(common): run first coverage hook
PanGan21 c5aa5a2
fix(common): compare against brnach changes
PanGan21 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,25 +1,86 @@ | ||
| #!/bin/bash | ||
| # | ||
| # Install git hooks from .github/hooks/ into .git/hooks/ via symlinks. | ||
| # | ||
| # Usage: | ||
| # sh .github/hooks/install.sh # Install all hooks | ||
| # sh .github/hooks/install.sh pre-push-coverage # Install only coverage hook | ||
| # sh .github/hooks/install.sh pre-push # Install only quality gates hook | ||
| # sh .github/hooks/install.sh pre-push pre-push-coverage # Install both pre-push hooks | ||
| # | ||
| # Available hooks: | ||
| # commit-msg — Angular conventional commit format check | ||
| # pre-push — Quality gates (cargo fmt, clippy, test) [blocking] | ||
| # pre-push-coverage — Coverage report check [non-blocking] | ||
| # | ||
|
|
||
| # Define the directory containing the custom hook scripts | ||
| HOOKS_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | ||
|
|
||
| # Define the Git hooks directory | ||
| GIT_HOOKS_DIR="$(git rev-parse --git-dir)/hooks" | ||
|
|
||
| # List of hooks to install | ||
| HOOKS=("commit-msg" "pre-push") | ||
|
|
||
| # Create the hooks directory if it doesn't exist | ||
| mkdir -p "$GIT_HOOKS_DIR" | ||
|
|
||
| # Install each hook | ||
| for hook in "${HOOKS[@]}"; do | ||
| if [ -f "$HOOKS_DIR/$hook" ]; then | ||
| ln -sf "$HOOKS_DIR/$hook" "$GIT_HOOKS_DIR/$hook" | ||
| echo "Installed $hook hook" | ||
| else | ||
| echo "Hook $hook not found in $HOOKS_DIR" | ||
| install_symlink() { | ||
| local source="$1" | ||
| local target="$2" | ||
|
|
||
| if [ ! -f "$HOOKS_DIR/$source" ]; then | ||
| echo "Hook '$source' not found in $HOOKS_DIR" | ||
| return 1 | ||
| fi | ||
|
|
||
| ln -sf "$HOOKS_DIR/$source" "$GIT_HOOKS_DIR/$target" | ||
| echo "Installed $source hook" | ||
| } | ||
|
|
||
| # Collect requested hooks | ||
| if [ -n "$1" ]; then | ||
| REQUESTED="$*" | ||
| else | ||
| REQUESTED="commit-msg pre-push" | ||
| fi | ||
|
|
||
| # Check if both pre-push hooks are requested | ||
| HAS_PREPUSH=false | ||
| HAS_COVERAGE=false | ||
| for hook in $REQUESTED; do | ||
| case "$hook" in | ||
| pre-push) HAS_PREPUSH=true ;; | ||
| pre-push-coverage) HAS_COVERAGE=true ;; | ||
| esac | ||
| done | ||
|
|
||
| # Install non-pre-push hooks as symlinks | ||
| for hook in $REQUESTED; do | ||
| case "$hook" in | ||
| pre-push|pre-push-coverage) ;; # handled below | ||
| *) install_symlink "$hook" "$hook" ;; | ||
| esac | ||
| done | ||
|
|
||
| # Install pre-push hook(s) | ||
| if $HAS_PREPUSH && $HAS_COVERAGE; then | ||
| # Both requested — create a wrapper that runs both | ||
| cat > "$GIT_HOOKS_DIR/pre-push" << 'WRAPPER' | ||
| #!/bin/sh | ||
| # Auto-generated wrapper — runs both pre-push hooks. | ||
| # Re-run install.sh to regenerate. | ||
|
|
||
| REPO_ROOT="$(git rev-parse --show-toplevel)" | ||
| HOOKS_SRC="$REPO_ROOT/.github/hooks" | ||
|
|
||
| # Coverage check (non-blocking) | ||
| "$HOOKS_SRC/pre-push-coverage" "$@" | ||
|
|
||
| # Quality gates (blocking) | ||
| "$HOOKS_SRC/pre-push" "$@" || exit $? | ||
| exit 0 | ||
| WRAPPER | ||
| chmod +x "$GIT_HOOKS_DIR/pre-push" | ||
| echo "Installed pre-push + pre-push-coverage hooks (combined)" | ||
| elif $HAS_PREPUSH; then | ||
| install_symlink "pre-push" "pre-push" | ||
| elif $HAS_COVERAGE; then | ||
| install_symlink "pre-push-coverage" "pre-push" | ||
| fi | ||
|
|
||
| echo "Git hooks installation complete." |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| #!/bin/sh | ||
| # | ||
| # Pre-push hook: checks that a fresh coverage report exists | ||
| # when pushing coprocessor changes. Non-blocking (always exits 0). | ||
| # | ||
|
|
||
| # Preserve Git LFS functionality | ||
| command -v git-lfs >/dev/null 2>&1 && git lfs pre-push "$@" | ||
|
|
||
| # Get the repo root | ||
| REPO_ROOT=$(git rev-parse --show-toplevel) | ||
| REPORT_FILE="$REPO_ROOT/coprocessor/fhevm-engine/coverage-report.txt" | ||
| COPROCESSOR_DIR="coprocessor/fhevm-engine/" | ||
|
|
||
| # Fetch latest remote to ensure accurate comparison | ||
| git fetch origin main --quiet 2>/dev/null || true | ||
|
|
||
| # Get changed files on this branch vs origin/main, filtered to actual crate directories only | ||
| # (ignores root-level config: Makefile, scripts/, Cargo.toml, etc.) | ||
| CRATE_CHANGES=$(git diff --name-only "origin/main"...HEAD -- "$COPROCESSOR_DIR" 2>/dev/null | \ | ||
| while read -r f; do | ||
| rel=$(echo "$f" | sed "s|^$COPROCESSOR_DIR||") | ||
| crate_name=$(echo "$rel" | cut -d/ -f1) | ||
| if [ -f "$REPO_ROOT/$COPROCESSOR_DIR$crate_name/Cargo.toml" ]; then | ||
| echo "$crate_name" | ||
| fi | ||
| done | sort -u) | ||
|
|
||
| if [ -z "$CRATE_CHANGES" ]; then | ||
| exit 0 | ||
| fi | ||
|
|
||
| # Check if coverage report exists | ||
| if [ ! -f "$REPORT_FILE" ]; then | ||
| echo "" | ||
| echo "WARNING: No coverage report found for coprocessor." | ||
| echo " Run 'make coverage-changed' in coprocessor/fhevm-engine/ to generate it." | ||
| echo "" | ||
| exit 0 | ||
| fi | ||
|
|
||
| # Check report freshness via embedded commit hash | ||
| REPORT_COMMIT=$(grep "^# commit:" "$REPORT_FILE" 2>/dev/null | awk '{print $3}') | ||
| if [ -z "$REPORT_COMMIT" ]; then | ||
| echo "" | ||
| echo "WARNING: Coverage report has no commit metadata (regenerate with latest tooling)." | ||
| echo " Run 'make coverage-changed' in coprocessor/fhevm-engine/ to regenerate." | ||
| echo "" | ||
| exit 0 | ||
| fi | ||
|
|
||
| # Get the latest crate-related commit on this branch | ||
| LATEST_CRATE_COMMIT="" | ||
| for crate in $CRATE_CHANGES; do | ||
| c=$(git log -1 --format=%H "origin/main"..HEAD -- "$COPROCESSOR_DIR$crate/" 2>/dev/null) | ||
| if [ -n "$c" ]; then | ||
| if [ -z "$LATEST_CRATE_COMMIT" ] || [ "$(git log -1 --format=%ct "$c")" -gt "$(git log -1 --format=%ct "$LATEST_CRATE_COMMIT")" ]; then | ||
| LATEST_CRATE_COMMIT="$c" | ||
| fi | ||
| fi | ||
| done | ||
|
|
||
| if [ -z "$LATEST_CRATE_COMMIT" ]; then | ||
| exit 0 | ||
| fi | ||
|
|
||
| # Check if the report was generated at or after the latest crate commit | ||
| if ! git merge-base --is-ancestor "$LATEST_CRATE_COMMIT" "$REPORT_COMMIT" 2>/dev/null; then | ||
| echo "" | ||
| echo "WARNING: Coverage report is stale (generated before latest coprocessor commit)." | ||
| echo " Run 'make coverage-changed' in coprocessor/fhevm-engine/ to regenerate." | ||
| echo "" | ||
| exit 0 | ||
| fi | ||
|
|
||
| # Report is fresh — print summary | ||
| TOTAL_LINE=$(grep "^TOTAL" "$REPORT_FILE" 2>/dev/null) | ||
| if [ -n "$TOTAL_LINE" ]; then | ||
| REGION_PCT=$(echo "$TOTAL_LINE" | awk '{print $4}') | ||
| FUNC_PCT=$(echo "$TOTAL_LINE" | awk '{print $7}') | ||
| LINE_PCT=$(echo "$TOTAL_LINE" | awk '{print $10}') | ||
| echo "" | ||
| echo "Coverage: Lines: $LINE_PCT | Functions: $FUNC_PCT | Regions: $REGION_PCT" | ||
| echo "" | ||
| fi | ||
|
|
||
| exit 0 | ||
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| .PHONY: coverage coverage-crate coverage-changed | ||
|
|
||
| # Run coverage for the full workspace | ||
| coverage: | ||
| cargo llvm-cov clean --workspace --profile coverage | ||
| DATABASE_URL=postgresql://postgres:postgres@localhost:5432/coprocessor \ | ||
| TEST_GLOBAL_LOCALSTACK=1 \ | ||
| cargo llvm-cov --no-report --workspace --profile coverage -- --test-threads=1 | ||
| cargo llvm-cov report --profile coverage 2>&1 | tee coverage-report.txt | ||
| @echo "# commit: $$(git rev-parse HEAD)" >> coverage-report.txt | ||
| @echo "" | ||
| @echo "Coverage report saved to coverage-report.txt" | ||
| @tail -2 coverage-report.txt | ||
|
|
||
| # Run coverage for a specific crate | ||
| # Usage: make coverage-crate CRATE=host-listener | ||
| coverage-crate: | ||
| @test -n "$(CRATE)" || (echo "Usage: make coverage-crate CRATE=<crate-name>" && exit 1) | ||
| cargo llvm-cov clean --workspace --profile coverage | ||
| DATABASE_URL=postgresql://postgres:postgres@localhost:5432/coprocessor \ | ||
| TEST_GLOBAL_LOCALSTACK=1 \ | ||
| cargo llvm-cov --no-report --package $(CRATE) --profile coverage -- --test-threads=1 | ||
| cargo llvm-cov report --profile coverage 2>&1 | tee coverage-report.txt | ||
| @echo "# commit: $$(git rev-parse HEAD)" >> coverage-report.txt | ||
| @echo "" | ||
| @echo "Coverage report saved to coverage-report.txt" | ||
| @tail -2 coverage-report.txt | ||
|
|
||
| # Auto-detect changed crates vs main and run coverage only for them | ||
| coverage-changed: | ||
| @sh scripts/coverage-changed.sh |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| #!/bin/sh | ||
| # | ||
| # Detect which workspace crates have changed vs main and run coverage | ||
| # only for those crates. If fhevm-engine-common changes, run all. | ||
| # | ||
| set -e | ||
|
|
||
| BASE_BRANCH="${BASE_BRANCH:-main}" | ||
| REPO_ROOT="$(git rev-parse --show-toplevel)" | ||
| ENGINE_DIR="$REPO_ROOT/coprocessor/fhevm-engine" | ||
|
|
||
| cd "$ENGINE_DIR" | ||
|
|
||
| # Fetch latest remote to ensure accurate comparison | ||
| git fetch origin "$BASE_BRANCH" --quiet 2>/dev/null || true | ||
|
|
||
| # Compare only your branch's changes against the remote base branch | ||
| # Uses three-dot diff against origin/ to exclude changes already on main | ||
| CHANGED_FILES=$(git diff --name-only "origin/$BASE_BRANCH"...HEAD -- "$ENGINE_DIR" 2>/dev/null | \ | ||
| sed "s|^coprocessor/fhevm-engine/||" || true) | ||
|
|
||
| if [ -z "$CHANGED_FILES" ]; then | ||
| echo "No changes detected vs $BASE_BRANCH. Nothing to cover." | ||
| exit 0 | ||
| fi | ||
|
|
||
| # Extract unique directory names from changed file paths, filtered to actual crates | ||
| # e.g. "host-listener/src/cmd/mod.rs" → "host-listener" (only if host-listener/Cargo.toml exists) | ||
| # Root-level files (Cargo.toml, Makefile, etc.) are skipped by the sed filter | ||
| ALL_DIRS=$(echo "$CHANGED_FILES" | sed -n 's|^\([^/]*\)/.*|\1|p' | sort -u) | ||
|
|
||
| # Only Cargo.lock affects all crates — other root-level files are ignored | ||
| if echo "$CHANGED_FILES" | grep -q '^Cargo\.lock$'; then | ||
| echo "Cargo.lock changed — running full workspace coverage." | ||
| echo "" | ||
| exec make coverage | ||
| fi | ||
|
|
||
| # Filter to actual crates (directories with Cargo.toml) | ||
| CHANGED_CRATES="" | ||
| for dir in $ALL_DIRS; do | ||
| if [ -f "$dir/Cargo.toml" ]; then | ||
| CHANGED_CRATES="$CHANGED_CRATES $dir" | ||
| fi | ||
| done | ||
| CHANGED_CRATES=$(echo "$CHANGED_CRATES" | xargs) | ||
|
|
||
| if [ -z "$CHANGED_CRATES" ]; then | ||
| echo "No crate-level changes detected. Nothing to cover." | ||
| exit 0 | ||
| fi | ||
|
|
||
| echo "Changed crates:" | ||
| echo "$CHANGED_CRATES" | tr ' ' '\n' | sed 's/^/ - /' | ||
| echo "" | ||
|
|
||
| # If fhevm-engine-common changed, run full workspace (all crates depend on it) | ||
| if echo "$CHANGED_CRATES" | grep -q "fhevm-engine-common"; then | ||
| echo "fhevm-engine-common changed — running full workspace coverage." | ||
| echo "" | ||
| exec make coverage | ||
| fi | ||
|
|
||
| # Build --package flags | ||
| PKG_FLAGS="" | ||
| for crate in $CHANGED_CRATES; do | ||
| PKG_FLAGS="$PKG_FLAGS --package $crate" | ||
| done | ||
|
|
||
| if [ -z "$PKG_FLAGS" ]; then | ||
| echo "No Cargo crates changed. Nothing to cover." | ||
| exit 0 | ||
| fi | ||
|
|
||
| echo "Running coverage for:$PKG_FLAGS" | ||
| echo "" | ||
|
|
||
| cargo llvm-cov clean --workspace --profile coverage | ||
|
|
||
| DATABASE_URL=postgresql://postgres:postgres@localhost:5432/coprocessor \ | ||
| TEST_GLOBAL_LOCALSTACK=1 \ | ||
| cargo llvm-cov --no-report $PKG_FLAGS --profile coverage -- --test-threads=1 | ||
|
|
||
| cargo llvm-cov report --profile coverage 2>&1 | tee coverage-report.txt | ||
| echo "# commit: $(git rev-parse HEAD)" >> coverage-report.txt | ||
|
|
||
| echo "" | ||
| echo "Coverage report saved to coverage-report.txt" | ||
| tail -2 coverage-report.txt |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.