- Move coveragegate tool from cue/tools to vociferate/coverage-gate - Create composite action with JSON metrics output for CI - Update tool to export passes/total_coverage/packages_checked/packages_failed - Support per-package threshold policy via JSON configuration - Change module path to git.hrafn.xyz/aether/vociferate/coverage-gate
92 lines
3.3 KiB
YAML
92 lines
3.3 KiB
YAML
name: vociferate/coverage-gate
|
|
description: >
|
|
Enforce per-package code coverage thresholds against Go coverage profiles.
|
|
Supports JSON policy files with per-package overrides and global minimums.
|
|
|
|
inputs:
|
|
profile:
|
|
description: Path to Go coverage profile file (output from `go test -coverprofile=...`).
|
|
required: false
|
|
default: coverage.out
|
|
policy:
|
|
description: Path to JSON file defining coverage thresholds and per-package overrides.
|
|
required: false
|
|
default: docs/coverage-thresholds.json
|
|
src-root:
|
|
description: Source root directory for package discovery (passed to `go list ./...`).
|
|
required: false
|
|
default: .
|
|
summary-file:
|
|
description: Optional file path to append markdown summary of coverage results.
|
|
required: false
|
|
default: ''
|
|
|
|
outputs:
|
|
passed:
|
|
description: 'Boolean: true if all packages meet threshold, false if any failed.'
|
|
value: ${{ steps.gate.outputs.passed }}
|
|
total-coverage:
|
|
description: Repository-wide statement coverage percentage.
|
|
value: ${{ steps.gate.outputs.total_coverage }}
|
|
packages-checked:
|
|
description: Number of packages evaluated against policy.
|
|
value: ${{ steps.gate.outputs.packages_checked }}
|
|
packages-failed:
|
|
description: Number of packages below threshold.
|
|
value: ${{ steps.gate.outputs.packages_failed }}
|
|
|
|
runs:
|
|
using: composite
|
|
steps:
|
|
- id: gate
|
|
shell: bash
|
|
working-directory: ${{ github.action_path }}
|
|
env:
|
|
PROFILE: ${{ inputs.profile }}
|
|
POLICY: ${{ inputs.policy }}
|
|
SRC_ROOT: ${{ inputs.src-root }}
|
|
SUMMARY_FILE: ${{ inputs.summary-file }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
# Run coverage gate and capture output
|
|
EXIT_CODE=0
|
|
OUTPUT=$(go run . \
|
|
--profile "$PROFILE" \
|
|
--policy "$POLICY" \
|
|
--src-root "$SRC_ROOT" \
|
|
) || EXIT_CODE=$?
|
|
|
|
echo "$OUTPUT"
|
|
|
|
# Parse summary from output (tool prints JSON stats on last line)
|
|
SUMMARY_LINE=$(echo "$OUTPUT" | tail -1)
|
|
|
|
# Determine pass/fail
|
|
if [[ $EXIT_CODE -eq 0 ]]; then
|
|
echo "passed=true" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "passed=false" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
# Extract metrics (tool outputs: packages_checked, packages_failed, total_coverage on summary line)
|
|
if echo "$SUMMARY_LINE" | jq . &>/dev/null; then
|
|
echo "total_coverage=$(echo "$SUMMARY_LINE" | jq -r '.total_coverage')" >> "$GITHUB_OUTPUT"
|
|
echo "packages_checked=$(echo "$SUMMARY_LINE" | jq -r '.packages_checked')" >> "$GITHUB_OUTPUT"
|
|
echo "packages_failed=$(echo "$SUMMARY_LINE" | jq -r '.packages_failed')" >> "$GITHUB_OUTPUT"
|
|
|
|
# Append to summary file if provided
|
|
if [[ -n "$SUMMARY_FILE" ]]; then
|
|
{
|
|
echo "## Coverage Gate Results"
|
|
echo
|
|
echo "- **Passed:** $([ "$EXIT_CODE" -eq 0 ] && echo '✓ Yes' || echo '✗ No')"
|
|
echo "- **Total Coverage:** $(echo "$SUMMARY_LINE" | jq -r '.total_coverage')%"
|
|
echo "- **Packages Checked:** $(echo "$SUMMARY_LINE" | jq -r '.packages_checked')"
|
|
echo "- **Packages Failed:** $(echo "$SUMMARY_LINE" | jq -r '.packages_failed')"
|
|
} >> "$SUMMARY_FILE"
|
|
fi
|
|
fi
|
|
|
|
exit $EXIT_CODE
|