diff --git a/.gitea/workflows/traceability.yml b/.gitea/workflows/traceability.yml deleted file mode 100644 index 0eb6f28f..00000000 --- a/.gitea/workflows/traceability.yml +++ /dev/null @@ -1,172 +0,0 @@ -name: Requirement Traceability Check - -on: - push: - branches: - - master - - main - - develop - pull_request: - branches: - - master - - main - - develop - -jobs: - traceability: - name: Validate Requirement Traces - runs-on: linux/amd64 - container: - image: gitea.tourolle.paris/dtourolle/jellytau-builder:latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - # bun is baked into jellytau-builder (see Dockerfile.builder); no setup-bun - # action needed — fetching it stalls on this Gitea runner. - - name: Install dependencies - run: bun install - - - name: Extract requirement traces - run: bun run traces:json > traces.json - - - name: Validate trace format - run: | - if ! jq empty traces.json 2>/dev/null; then - echo "❌ Invalid traces.json format" - exit 1 - fi - echo "✅ Traces JSON is valid" - - - name: Check requirement coverage - run: | - set -e - - # Extract coverage stats - TOTAL_TRACES=$(jq '.totalTraces' traces.json) - UR_COUNT=$(jq '.byType.UR | length' traces.json) - IR_COUNT=$(jq '.byType.IR | length' traces.json) - DR_COUNT=$(jq '.byType.DR | length' traces.json) - JA_COUNT=$(jq '.byType.JA | length' traces.json) - - echo "## 📊 Requirement Traceability Report" - echo "" - echo "**Total TRACES Found:** $TOTAL_TRACES" - echo "" - echo "### Requirements Covered:" - echo "- User Requirements (UR): $UR_COUNT / 39 ($(( UR_COUNT * 100 / 39 ))%)" - echo "- Integration Requirements (IR): $IR_COUNT / 24 ($(( IR_COUNT * 100 / 24 ))%)" - echo "- Development Requirements (DR): $DR_COUNT / 48 ($(( DR_COUNT * 100 / 48 ))%)" - echo "- Jellyfin API Requirements (JA): $JA_COUNT / 3 ($(( JA_COUNT * 100 / 3 ))%)" - echo "" - - # Set minimum coverage threshold (50%) - TOTAL_REQS=114 - MIN_COVERAGE=$((TOTAL_REQS / 2)) - COVERED=$((UR_COUNT + IR_COUNT + DR_COUNT + JA_COUNT)) - COVERAGE_PERCENT=$((COVERED * 100 / TOTAL_REQS)) - - echo "**Overall Coverage:** $COVERED / $TOTAL_REQS ($COVERAGE_PERCENT%)" - echo "" - - if [ "$COVERED" -lt "$MIN_COVERAGE" ]; then - echo "❌ Coverage below minimum threshold ($COVERAGE_PERCENT% < 50%)" - exit 1 - else - echo "✅ Coverage meets minimum threshold ($COVERAGE_PERCENT% >= 50%)" - fi - - - name: Check for new untraced code - run: | - set -e - - # Find files modified in this PR/push - if [ "${{ github.event_name }}" = "pull_request" ]; then - CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E '\.(ts|tsx|svelte|rs)$' || true) - else - CHANGED_FILES=$(git diff --name-only HEAD~1 | grep -E '\.(ts|tsx|svelte|rs)$' || true) - fi - - if [ -z "$CHANGED_FILES" ]; then - echo "✅ No source files changed" - exit 0 - fi - - echo "### Files Changed:" - echo "$CHANGED_FILES" | sed 's/^/- /' - echo "" - - # Check if changed files have TRACES - UNTRACED_FILES="" - while IFS= read -r file; do - if [ -f "$file" ]; then - # Skip test files and generated code - if [[ "$file" == *".test."* ]] || [[ "$file" == *"node_modules"* ]]; then - continue - fi - - # Check if file has TRACES comments - if ! grep -q "TRACES:" "$file" 2>/dev/null; then - UNTRACED_FILES+="$file"$'\n' - fi - fi - done <<< "$CHANGED_FILES" - - if [ -n "$UNTRACED_FILES" ]; then - echo "⚠️ New files without TRACES:" - echo "$UNTRACED_FILES" | sed 's/^/ - /' - echo "" - echo "💡 Add TRACES comments to link code to requirements:" - echo " // TRACES: UR-001, UR-002 | DR-003" - else - echo "✅ All changed files have TRACES comments" - fi - - - name: Generate traceability report - if: always() - run: bun run traces:markdown - - - name: Upload traceability report - if: always() - uses: actions/upload-artifact@v3 - with: - name: traceability-report - path: docs/traceability.md - retention-days: 30 - - - name: Comment PR with coverage report - if: github.event_name == 'pull_request' - uses: actions/github-script@v7 - with: - script: | - const fs = require('fs'); - const traces = JSON.parse(fs.readFileSync('traces.json', 'utf8')); - - const urCount = traces.byType.UR.length; - const irCount = traces.byType.IR.length; - const drCount = traces.byType.DR.length; - const jaCount = traces.byType.JA.length; - const total = urCount + irCount + drCount + jaCount; - const coverage = Math.round((total / 114) * 100); - - const comment = `## 📊 Requirement Traceability Report - -**Coverage:** ${coverage}% (${total}/114 requirements traced) - -### By Type: -- **User Requirements (UR):** ${urCount}/39 (${Math.round(urCount/39*100)}%) -- **Integration Requirements (IR):** ${irCount}/24 (${Math.round(irCount/24*100)}%) -- **Development Requirements (DR):** ${drCount}/48 (${Math.round(drCount/48*100)}%) -- **Jellyfin API (JA):** ${jaCount}/3 (${Math.round(jaCount/3*100)}%) - -**Total Traces:** ${traces.totalTraces} - -[View full report](artifacts) | [Format Guide](https://github.com/yourusername/jellytau/blob/master/scripts/README.md#extract-tracests)`; - - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: comment - });