name: Traceability Validation on: push: branches: - master - main - develop pull_request: branches: - master - main - develop jobs: validate-traces: runs-on: ubuntu-latest name: Check Requirement Traces steps: - name: Checkout repository uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup Bun uses: oven-sh/setup-bun@v1 - name: Install dependencies run: bun install - name: Extract traces run: | echo "🔍 Extracting requirement traces..." bun run traces:json > traces-report.json - name: Validate traces run: | set -e echo "📊 Validating requirement traceability..." echo "" # Parse JSON TOTAL_TRACES=$(jq '.totalTraces' traces-report.json) UR=$(jq '.byType.UR | length' traces-report.json) IR=$(jq '.byType.IR | length' traces-report.json) DR=$(jq '.byType.DR | length' traces-report.json) JA=$(jq '.byType.JA | length' traces-report.json) # Print coverage report echo "✅ TRACES Found: $TOTAL_TRACES" echo "" echo "📋 Coverage Summary:" echo " User Requirements (UR): $UR / 39 ($(( UR * 100 / 39 ))%)" echo " Integration Requirements (IR): $IR / 24 ($(( IR * 100 / 24 ))%)" echo " Development Requirements (DR): $DR / 48 ($(( DR * 100 / 48 ))%)" echo " Jellyfin API Requirements (JA): $JA / 3 ($(( JA * 100 / 3 ))%)" echo "" COVERED=$((UR + IR + DR + JA)) TOTAL_REQS=114 COVERAGE=$((COVERED * 100 / TOTAL_REQS)) echo "📈 Overall Coverage: $COVERED / $TOTAL_REQS ($COVERAGE%)" echo "" # Check minimum threshold MIN_THRESHOLD=50 if [ "$COVERAGE" -lt "$MIN_THRESHOLD" ]; then echo "❌ ERROR: Coverage ($COVERAGE%) is below minimum threshold ($MIN_THRESHOLD%)" exit 1 fi echo "✅ Coverage is acceptable ($COVERAGE% >= $MIN_THRESHOLD%)" - name: Check modified files if: github.event_name == 'pull_request' run: | echo "🔍 Checking modified files for traces..." echo "" # Get changed files CHANGED=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E '\.(ts|tsx|svelte|rs)$' || echo "") if [ -z "$CHANGED" ]; then echo "✅ No TypeScript/Rust files changed" exit 0 fi echo "📝 Changed files:" echo "$CHANGED" | sed 's/^/ /' echo "" # Check each file MISSING_TRACES=0 while IFS= read -r file; do # Skip test files if [[ "$file" == *".test."* ]]; then continue fi if [ -f "$file" ]; then if ! grep -q "TRACES:" "$file"; then echo "⚠️ Missing TRACES: $file" MISSING_TRACES=$((MISSING_TRACES + 1)) fi fi done <<< "$CHANGED" if [ "$MISSING_TRACES" -gt 0 ]; then echo "" echo "📝 Recommendation: Add TRACES comments to new/modified code" echo " Format: // TRACES: UR-001, UR-002 | DR-003" echo "" echo "💡 For more info, see: scripts/README.md" fi - name: Generate full report if: always() run: | echo "📄 Generating full traceability report..." bun run traces:markdown - name: Display report summary if: always() run: | echo "" echo "📊 Full Report Generated" echo "📁 Location: docs/TRACEABILITY.md" echo "" head -50 docs/TRACEABILITY.md || true - name: Save artifacts if: always() uses: actions/upload-artifact@v3 with: name: traceability-reports path: | traces-report.json docs/TRACEABILITY.md retention-days: 30