ci: remove superseded traceability workflow
traceability.yml duplicated the coverage check now owned by traceability-check.yml, running the same extraction on every push and PR to master/main/develop. Dead CI: nothing references it, and keeping both doubled runner time for one result.
This commit is contained in:
@@ -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
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user