Files
vociferate/coverage-gate/action.yml
Micheal Wilkinson 532f6a98d8
Some checks failed
Push Validation / coverage-badge (push) Failing after 44s
Push Validation / recommend-release (push) Has been skipped
feat: extract coverage-gate action from Cue for reuse across projects
- 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
2026-03-21 22:34:01 +00:00

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