moai-adk 0.8.0__py3-none-any.whl → 0.15.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of moai-adk might be problematic. Click here for more details.
- moai_adk/cli/commands/init.py +14 -2
- moai_adk/cli/commands/update.py +229 -60
- moai_adk/core/config/migration.py +1 -1
- moai_adk/core/issue_creator.py +313 -0
- moai_adk/core/project/detector.py +201 -12
- moai_adk/core/project/initializer.py +62 -1
- moai_adk/core/project/phase_executor.py +48 -6
- moai_adk/core/tags/__init__.py +86 -0
- moai_adk/core/tags/ci_validator.py +463 -0
- moai_adk/core/tags/cli.py +283 -0
- moai_adk/core/tags/generator.py +109 -0
- moai_adk/core/tags/inserter.py +99 -0
- moai_adk/core/tags/mapper.py +126 -0
- moai_adk/core/tags/parser.py +76 -0
- moai_adk/core/tags/pre_commit_validator.py +393 -0
- moai_adk/core/tags/reporter.py +956 -0
- moai_adk/core/tags/tags.py +149 -0
- moai_adk/core/tags/validator.py +897 -0
- moai_adk/core/template_engine.py +268 -0
- moai_adk/templates/.claude/agents/alfred/backend-expert.md +319 -0
- moai_adk/templates/.claude/agents/alfred/cc-manager.md +25 -2
- moai_adk/templates/.claude/agents/alfred/debug-helper.md +24 -12
- moai_adk/templates/.claude/agents/alfred/devops-expert.md +464 -0
- moai_adk/templates/.claude/agents/alfred/doc-syncer.md +20 -13
- moai_adk/templates/.claude/agents/alfred/frontend-expert.md +357 -0
- moai_adk/templates/.claude/agents/alfred/git-manager.md +47 -16
- moai_adk/templates/.claude/agents/alfred/implementation-planner.md +95 -15
- moai_adk/templates/.claude/agents/alfred/project-manager.md +78 -12
- moai_adk/templates/.claude/agents/alfred/quality-gate.md +28 -5
- moai_adk/templates/.claude/agents/alfred/skill-factory.md +30 -2
- moai_adk/templates/.claude/agents/alfred/spec-builder.md +133 -13
- moai_adk/templates/.claude/agents/alfred/tag-agent.md +104 -8
- moai_adk/templates/.claude/agents/alfred/tdd-implementer.md +133 -16
- moai_adk/templates/.claude/agents/alfred/trust-checker.md +27 -4
- moai_adk/templates/.claude/agents/alfred/ui-ux-expert.md +571 -0
- moai_adk/templates/.claude/commands/alfred/0-project.md +466 -125
- moai_adk/templates/.claude/commands/alfred/1-plan.md +208 -71
- moai_adk/templates/.claude/commands/alfred/2-run.md +276 -55
- moai_adk/templates/.claude/commands/alfred/3-sync.md +439 -53
- moai_adk/templates/.claude/commands/alfred/9-feedback.md +149 -0
- moai_adk/templates/.claude/hooks/alfred/core/project.py +361 -29
- moai_adk/templates/.claude/hooks/alfred/core/timeout.py +136 -0
- moai_adk/templates/.claude/hooks/alfred/core/ttl_cache.py +108 -0
- moai_adk/templates/.claude/hooks/alfred/core/version_cache.py +198 -0
- moai_adk/templates/.claude/hooks/alfred/handlers/__init__.py +14 -6
- moai_adk/templates/.claude/hooks/alfred/post_tool__log_changes.py +94 -0
- moai_adk/templates/.claude/hooks/alfred/pre_tool__auto_checkpoint.py +100 -0
- moai_adk/templates/.claude/hooks/alfred/session_end__cleanup.py +94 -0
- moai_adk/templates/.claude/hooks/alfred/session_start__show_project_info.py +94 -0
- moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/__init__.py +2 -2
- moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/checkpoint.py +3 -3
- moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/context.py +5 -5
- moai_adk/templates/.claude/hooks/alfred/shared/core/project.py +749 -0
- moai_adk/templates/.claude/hooks/alfred/{core → shared/core}/tags.py +55 -23
- moai_adk/templates/.claude/hooks/alfred/shared/core/version_cache.py +198 -0
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/__init__.py +21 -0
- moai_adk/templates/.claude/hooks/alfred/shared/handlers/notification.py +154 -0
- moai_adk/templates/.claude/hooks/alfred/{handlers → shared/handlers}/session.py +28 -15
- moai_adk/templates/.claude/hooks/alfred/{handlers → shared/handlers}/tool.py +3 -6
- moai_adk/templates/.claude/hooks/alfred/{handlers → shared/handlers}/user.py +19 -0
- moai_adk/templates/.claude/hooks/alfred/user_prompt__jit_load_docs.py +112 -0
- moai_adk/templates/.claude/hooks/alfred/utils/__init__.py +1 -0
- moai_adk/templates/.claude/hooks/alfred/utils/timeout.py +161 -0
- moai_adk/templates/.claude/settings.json +5 -5
- moai_adk/templates/.claude/skills/moai-alfred-agent-guide/SKILL.md +70 -0
- moai_adk/templates/.claude/skills/moai-alfred-agent-guide/examples.md +62 -0
- moai_adk/templates/{.moai/memory/CLAUDE-AGENTS-GUIDE.md → .claude/skills/moai-alfred-agent-guide/reference.md} +34 -0
- moai_adk/templates/.claude/skills/moai-alfred-config-schema/SKILL.md +56 -0
- moai_adk/templates/.claude/skills/moai-alfred-config-schema/examples.md +28 -0
- moai_adk/templates/.claude/skills/moai-alfred-context-budget/SKILL.md +62 -0
- moai_adk/templates/.claude/skills/moai-alfred-context-budget/examples.md +28 -0
- moai_adk/templates/.claude/skills/moai-alfred-context-budget/reference.md +405 -0
- moai_adk/templates/.claude/skills/moai-alfred-dev-guide/SKILL.md +51 -0
- moai_adk/templates/.claude/skills/moai-alfred-dev-guide/examples.md +355 -0
- moai_adk/templates/.claude/skills/moai-alfred-dev-guide/reference.md +239 -0
- moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/SKILL.md +323 -0
- moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/examples.md +286 -0
- moai_adk/templates/.claude/skills/moai-alfred-expertise-detection/reference.md +126 -0
- moai_adk/templates/.claude/skills/moai-alfred-gitflow-policy/SKILL.md +74 -0
- moai_adk/templates/.claude/skills/moai-alfred-gitflow-policy/examples.md +4 -0
- moai_adk/templates/.claude/skills/moai-alfred-gitflow-policy/reference.md +269 -0
- moai_adk/templates/.claude/skills/moai-alfred-issue-labels/SKILL.md +19 -0
- moai_adk/templates/.claude/skills/moai-alfred-issue-labels/examples.md +4 -0
- moai_adk/templates/.claude/skills/moai-alfred-issue-labels/reference.md +150 -0
- moai_adk/templates/.claude/skills/moai-alfred-persona-roles/SKILL.md +198 -0
- moai_adk/templates/.claude/skills/moai-alfred-persona-roles/examples.md +431 -0
- moai_adk/templates/.claude/skills/moai-alfred-persona-roles/reference.md +141 -0
- moai_adk/templates/.claude/skills/moai-alfred-practices/SKILL.md +89 -0
- moai_adk/templates/.claude/skills/moai-alfred-practices/examples.md +122 -0
- moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/SKILL.md +508 -0
- moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/examples.md +481 -0
- moai_adk/templates/.claude/skills/moai-alfred-proactive-suggestions/reference.md +100 -0
- moai_adk/templates/.claude/skills/moai-alfred-reporting/SKILL.md +273 -0
- moai_adk/templates/.claude/skills/moai-alfred-rules/SKILL.md +77 -0
- moai_adk/templates/.claude/skills/moai-alfred-rules/examples.md +265 -0
- moai_adk/templates/.claude/skills/moai-alfred-session-state/SKILL.md +19 -0
- moai_adk/templates/.claude/skills/moai-alfred-session-state/examples.md +4 -0
- moai_adk/templates/.claude/skills/moai-alfred-session-state/reference.md +84 -0
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/README.md +137 -0
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/SKILL.md +219 -0
- moai_adk/templates/.claude/skills/{moai-spec-authoring → moai-alfred-spec-authoring}/examples/validate-spec.sh +3 -3
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/examples.md +541 -0
- moai_adk/templates/.claude/skills/moai-alfred-spec-authoring/reference.md +622 -0
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-extended/SKILL.md +115 -0
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-extended/examples.md +4 -0
- moai_adk/templates/.claude/skills/moai-alfred-spec-metadata-extended/reference.md +348 -0
- moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/SKILL.md +19 -0
- moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/examples.md +4 -0
- moai_adk/templates/.claude/skills/moai-alfred-todowrite-pattern/reference.md +211 -0
- moai_adk/templates/.claude/skills/moai-alfred-workflow/SKILL.md +288 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-descriptions/SKILL.md +19 -0
- moai_adk/templates/.claude/skills/moai-cc-skill-descriptions/examples.md +4 -0
- moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/SKILL.md +3 -3
- moai_adk/templates/.claude/skills/moai-design-systems/SKILL.md +802 -0
- moai_adk/templates/.claude/skills/moai-design-systems/examples.md +1238 -0
- moai_adk/templates/.claude/skills/moai-design-systems/reference.md +673 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +17 -13
- moai_adk/templates/.claude/skills/moai-foundation-ears/SKILL.md +9 -6
- moai_adk/templates/.claude/skills/moai-lang-go/SKILL.md +15 -12
- moai_adk/templates/.claude/skills/moai-lang-java/SKILL.md +14 -12
- moai_adk/templates/.claude/skills/moai-lang-php/SKILL.md +14 -11
- moai_adk/templates/.claude/skills/moai-lang-python/SKILL.md +10 -8
- moai_adk/templates/.claude/skills/moai-lang-rust/SKILL.md +15 -12
- moai_adk/templates/.claude/skills/moai-lang-scala/SKILL.md +13 -11
- moai_adk/templates/.claude/skills/moai-lang-typescript/SKILL.md +16 -10
- moai_adk/templates/.claude/skills/moai-project-documentation.md +622 -0
- moai_adk/templates/.git-hooks/pre-push +143 -0
- moai_adk/templates/.github/workflows/c-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/cpp-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/csharp-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/dart-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/go-tag-validation.yml +130 -0
- moai_adk/templates/.github/workflows/java-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/javascript-tag-validation.yml +135 -0
- moai_adk/templates/.github/workflows/kotlin-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/moai-gitflow.yml +166 -3
- moai_adk/templates/.github/workflows/moai-release-create.yml +100 -0
- moai_adk/templates/.github/workflows/moai-release-pipeline.yml +188 -0
- moai_adk/templates/.github/workflows/php-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/python-tag-validation.yml +118 -0
- moai_adk/templates/.github/workflows/release.yml +118 -0
- moai_adk/templates/.github/workflows/ruby-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/rust-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/shell-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/spec-issue-sync.yml +206 -35
- moai_adk/templates/.github/workflows/swift-tag-validation.yml +11 -0
- moai_adk/templates/.github/workflows/tag-report.yml +269 -0
- moai_adk/templates/.github/workflows/tag-validation.yml +186 -0
- moai_adk/templates/.github/workflows/typescript-tag-validation.yml +154 -0
- moai_adk/templates/.moai/config.json +21 -2
- moai_adk/templates/CLAUDE.md +972 -78
- moai_adk/templates/workflows/go-tag-validation.yml +30 -0
- moai_adk/templates/workflows/javascript-tag-validation.yml +41 -0
- moai_adk/templates/workflows/python-tag-validation.yml +42 -0
- moai_adk/templates/workflows/typescript-tag-validation.yml +31 -0
- moai_adk/utils/banner.py +5 -5
- {moai_adk-0.8.0.dist-info → moai_adk-0.15.0.dist-info}/METADATA +1518 -161
- {moai_adk-0.8.0.dist-info → moai_adk-0.15.0.dist-info}/RECORD +183 -100
- moai_adk/templates/.claude/hooks/alfred/HOOK_SCHEMA_VALIDATION.md +0 -313
- moai_adk/templates/.claude/hooks/alfred/README.md +0 -230
- moai_adk/templates/.claude/hooks/alfred/alfred_hooks.py +0 -174
- moai_adk/templates/.claude/hooks/alfred/handlers/notification.py +0 -25
- moai_adk/templates/.claude/hooks/alfred/test_hook_output.py +0 -175
- moai_adk/templates/.claude/output-styles/alfred/agentic-coding.md +0 -640
- moai_adk/templates/.claude/output-styles/alfred/moai-adk-learning.md +0 -696
- moai_adk/templates/.claude/output-styles/alfred/study-with-alfred.md +0 -474
- moai_adk/templates/.claude/skills/moai-spec-authoring/README.md +0 -137
- moai_adk/templates/.claude/skills/moai-spec-authoring/SKILL.md +0 -218
- moai_adk/templates/.claude/skills/moai-spec-authoring/examples.md +0 -541
- moai_adk/templates/.claude/skills/moai-spec-authoring/reference.md +0 -622
- moai_adk/templates/.github/ISSUE_TEMPLATE/spec.yml +0 -176
- moai_adk/templates/.github/PULL_REQUEST_TEMPLATE.md +0 -69
- moai_adk/templates/.moai/memory/DEVELOPMENT-GUIDE.md +0 -344
- moai_adk/templates/.moai/memory/GITFLOW-PROTECTION-POLICY.md +0 -220
- moai_adk/templates/.moai/memory/SPEC-METADATA.md +0 -356
- moai_adk/templates/.moai/memory/config-schema.md +0 -444
- moai_adk/templates/.moai/memory/gitflow-protection-policy.md +0 -220
- moai_adk/templates/.moai/memory/spec-metadata.md +0 -356
- moai_adk/templates/.moai/project/product.md +0 -161
- moai_adk/templates/.moai/project/structure.md +0 -156
- moai_adk/templates/.moai/project/tech.md +0 -227
- moai_adk/templates/__init__.py +0 -2
- /moai_adk/templates/{.moai/memory/CONFIG-SCHEMA.md → .claude/skills/moai-alfred-config-schema/reference.md} +0 -0
- /moai_adk/templates/{.moai/memory/CLAUDE-PRACTICES.md → .claude/skills/moai-alfred-practices/reference.md} +0 -0
- /moai_adk/templates/{.moai/memory/CLAUDE-RULES.md → .claude/skills/moai-alfred-rules/reference.md} +0 -0
- /moai_adk/templates/{.moai/memory/SKILLS-DESCRIPTION-POLICY.md → .claude/skills/moai-cc-skill-descriptions/reference.md} +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/CHECKLIST.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/EXAMPLES.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/INTERACTIVE-DISCOVERY.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/METADATA.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/PARALLEL-ANALYSIS-REPORT.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/PYTHON-VERSION-MATRIX.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/SKILL-FACTORY-WORKFLOW.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/SKILL-UPDATE-ADVISOR.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/STEP-BY-STEP-GUIDE.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/STRUCTURE.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/WEB-RESEARCH.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/reference.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/scripts/generate-structure.sh +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/scripts/validate-skill.sh +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/templates/SKILL_TEMPLATE.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/templates/examples-template.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/templates/reference-template.md +0 -0
- /moai_adk/templates/.claude/skills/{moai-skill-factory → moai-cc-skill-factory}/templates/scripts-template.sh +0 -0
- {moai_adk-0.8.0.dist-info → moai_adk-0.15.0.dist-info}/WHEEL +0 -0
- {moai_adk-0.8.0.dist-info → moai_adk-0.15.0.dist-info}/entry_points.txt +0 -0
- {moai_adk-0.8.0.dist-info → moai_adk-0.15.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -25,33 +25,62 @@ jobs:
|
|
|
25
25
|
|
|
26
26
|
- name: Find and parse SPEC file
|
|
27
27
|
id: spec
|
|
28
|
+
env:
|
|
29
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
28
30
|
run: |
|
|
29
31
|
set -x # Enable debug mode
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
ls -la
|
|
33
|
+
echo "=== STEP 1: Get PR branch name ==="
|
|
34
|
+
branch_name="${{ github.head_ref }}"
|
|
35
|
+
echo "Branch: $branch_name"
|
|
35
36
|
|
|
36
|
-
echo "
|
|
37
|
-
|
|
37
|
+
echo ""
|
|
38
|
+
echo "=== STEP 2: Get changed files from PR ==="
|
|
39
|
+
# Get list of changed files from PR
|
|
40
|
+
changed_files=$(gh pr view ${{ github.event.pull_request.number }} --json files --jq '.files[].path' 2>&1)
|
|
41
|
+
|
|
42
|
+
if [ $? -ne 0 ]; then
|
|
43
|
+
echo "⚠️ Failed to fetch PR files, falling back to git diff"
|
|
44
|
+
changed_files=$(git diff --name-only origin/main HEAD 2>&1)
|
|
45
|
+
fi
|
|
38
46
|
|
|
39
|
-
|
|
40
|
-
echo "
|
|
41
|
-
find . -name "spec.md" -type f 2>&1 || echo "find command failed"
|
|
47
|
+
echo "Changed files:"
|
|
48
|
+
echo "$changed_files"
|
|
42
49
|
|
|
43
|
-
|
|
44
|
-
echo "
|
|
50
|
+
echo ""
|
|
51
|
+
echo "=== STEP 3: Find SPEC files that were actually changed ==="
|
|
52
|
+
# Find spec files that were actually modified in this PR
|
|
53
|
+
spec_files=$(echo "$changed_files" | grep -E '\.moai/specs/SPEC-.*/spec\.md$' || true)
|
|
45
54
|
|
|
46
|
-
if [ -z "$
|
|
47
|
-
echo "⚠️ No SPEC file
|
|
55
|
+
if [ -z "$spec_files" ]; then
|
|
56
|
+
echo "⚠️ No SPEC file changes detected in this PR"
|
|
48
57
|
echo "Exiting gracefully (this is expected if no SPEC files changed)"
|
|
49
58
|
exit 0
|
|
50
59
|
fi
|
|
51
60
|
|
|
52
|
-
echo "
|
|
61
|
+
echo "Found SPEC files:"
|
|
62
|
+
echo "$spec_files"
|
|
63
|
+
|
|
64
|
+
# Count SPEC files
|
|
65
|
+
spec_file_count=$(echo "$spec_files" | wc -l)
|
|
66
|
+
echo "Count: $spec_file_count"
|
|
67
|
+
|
|
68
|
+
if [ "$spec_file_count" -gt 1 ]; then
|
|
69
|
+
echo ""
|
|
70
|
+
echo "⚠️ WARNING: Multiple SPEC files detected in this PR"
|
|
71
|
+
echo " This is unusual. Using first SPEC file."
|
|
72
|
+
echo " Files:"
|
|
73
|
+
echo "$spec_files" | sed 's/^/ /'
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# Select first SPEC file
|
|
77
|
+
spec_file=$(echo "$spec_files" | head -1)
|
|
78
|
+
echo ""
|
|
79
|
+
echo "✅ Selected SPEC file: $spec_file"
|
|
53
80
|
echo "spec_file=$spec_file" >> $GITHUB_OUTPUT
|
|
54
81
|
|
|
82
|
+
echo ""
|
|
83
|
+
echo "=== STEP 4: Extract YAML metadata ==="
|
|
55
84
|
# Extract YAML metadata using grep
|
|
56
85
|
spec_id=$(grep "^id:" "$spec_file" | sed 's/^id: *//' | tr -d ' "')
|
|
57
86
|
spec_version=$(grep "^version:" "$spec_file" | sed 's/^version: *//' | tr -d ' "')
|
|
@@ -68,13 +97,93 @@ jobs:
|
|
|
68
97
|
echo " Status: $spec_status"
|
|
69
98
|
echo " Priority: $spec_priority"
|
|
70
99
|
|
|
100
|
+
echo ""
|
|
101
|
+
echo "=== STEP 5: Validate SPEC status ==="
|
|
102
|
+
# Skip if SPEC is already completed (historical document)
|
|
103
|
+
if [ "$spec_status" = "completed" ]; then
|
|
104
|
+
echo "⚠️ SPEC status is 'completed' (historical document)"
|
|
105
|
+
echo " Skipping issue creation for completed SPEC"
|
|
106
|
+
exit 0
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
echo "✅ SPEC status is valid (not completed)"
|
|
110
|
+
|
|
111
|
+
echo ""
|
|
112
|
+
echo "=== STEP 6: Validate branch name matches SPEC ID ==="
|
|
113
|
+
# Extract SPEC ID from branch name (feature/SPEC-UPDATE-REFACTOR-002 -> UPDATE-REFACTOR-002)
|
|
114
|
+
branch_spec_id=$(echo "$branch_name" | grep -oE 'SPEC-[A-Z0-9_-]+' | sed 's/^SPEC-//' || true)
|
|
115
|
+
|
|
116
|
+
if [ -n "$branch_spec_id" ]; then
|
|
117
|
+
if [ "$branch_spec_id" != "$spec_id" ]; then
|
|
118
|
+
echo "⚠️ WARNING: Branch name mismatch!"
|
|
119
|
+
echo " Branch SPEC ID: $branch_spec_id"
|
|
120
|
+
echo " File SPEC ID: $spec_id"
|
|
121
|
+
echo " Continuing anyway (might be intentional)"
|
|
122
|
+
else
|
|
123
|
+
echo "✅ Branch name matches SPEC ID"
|
|
124
|
+
fi
|
|
125
|
+
else
|
|
126
|
+
echo "⚠️ Could not extract SPEC ID from branch name"
|
|
127
|
+
echo " Branch: $branch_name"
|
|
128
|
+
echo " Continuing anyway"
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
echo ""
|
|
132
|
+
echo "=== STEP 7: Output all variables ==="
|
|
71
133
|
echo "spec_id=$spec_id" >> $GITHUB_OUTPUT
|
|
72
134
|
echo "spec_version=$spec_version" >> $GITHUB_OUTPUT
|
|
73
135
|
echo "spec_status=$spec_status" >> $GITHUB_OUTPUT
|
|
74
136
|
echo "spec_priority=$spec_priority" >> $GITHUB_OUTPUT
|
|
75
137
|
echo "spec_title=$spec_title" >> $GITHUB_OUTPUT
|
|
76
138
|
|
|
77
|
-
- name:
|
|
139
|
+
- name: Check for existing issue
|
|
140
|
+
if: steps.spec.outputs.spec_id
|
|
141
|
+
id: check-issue
|
|
142
|
+
env:
|
|
143
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
144
|
+
run: |
|
|
145
|
+
spec_id="${{ steps.spec.outputs.spec_id }}"
|
|
146
|
+
|
|
147
|
+
echo "=== Checking for existing issue ==="
|
|
148
|
+
echo "Searching for existing GitHub issue with SPEC-$spec_id..."
|
|
149
|
+
|
|
150
|
+
# PRIMARY: Search with label filter (efficient)
|
|
151
|
+
echo " Attempt 1: Searching with 'spec' label filter..."
|
|
152
|
+
existing_issue=$(gh issue list \
|
|
153
|
+
--label "spec" \
|
|
154
|
+
--state all \
|
|
155
|
+
--search "[SPEC-$spec_id]" \
|
|
156
|
+
--json number,title,state \
|
|
157
|
+
--jq '.[] | select(.title | contains("[SPEC-'$spec_id']")) | .number' \
|
|
158
|
+
2>/dev/null | head -1)
|
|
159
|
+
|
|
160
|
+
# FALLBACK: Search without label filter (in case labels missing)
|
|
161
|
+
if [ -z "$existing_issue" ]; then
|
|
162
|
+
echo " Attempt 2: Searching WITHOUT label filter (fallback for missing labels)..."
|
|
163
|
+
existing_issue=$(gh issue list \
|
|
164
|
+
--state all \
|
|
165
|
+
--search "[SPEC-$spec_id]" \
|
|
166
|
+
--json number,title,state,labels \
|
|
167
|
+
--jq '.[] | select(.title | contains("[SPEC-'$spec_id']")) | .number' \
|
|
168
|
+
2>/dev/null | head -1)
|
|
169
|
+
|
|
170
|
+
if [ -n "$existing_issue" ]; then
|
|
171
|
+
echo " ⚠️ Found issue without 'spec' label, adding labels..."
|
|
172
|
+
# Add missing labels to existing issue
|
|
173
|
+
gh issue edit "$existing_issue" --add-label "spec,planning" 2>/dev/null || true
|
|
174
|
+
fi
|
|
175
|
+
fi
|
|
176
|
+
|
|
177
|
+
if [ -n "$existing_issue" ]; then
|
|
178
|
+
echo "✅ Found existing issue: #$existing_issue"
|
|
179
|
+
echo "issue_exists=true" >> $GITHUB_OUTPUT
|
|
180
|
+
echo "issue_number=$existing_issue" >> $GITHUB_OUTPUT
|
|
181
|
+
else
|
|
182
|
+
echo "📋 No existing issue found for SPEC-$spec_id"
|
|
183
|
+
echo "issue_exists=false" >> $GITHUB_OUTPUT
|
|
184
|
+
fi
|
|
185
|
+
|
|
186
|
+
- name: Create or Update GitHub Issue
|
|
78
187
|
if: steps.spec.outputs.spec_id
|
|
79
188
|
id: create-issue
|
|
80
189
|
env:
|
|
@@ -86,6 +195,8 @@ jobs:
|
|
|
86
195
|
spec_status="${{ steps.spec.outputs.spec_status }}"
|
|
87
196
|
spec_priority="${{ steps.spec.outputs.spec_priority }}"
|
|
88
197
|
spec_file="${{ steps.spec.outputs.spec_file }}"
|
|
198
|
+
issue_exists="${{ steps.check-issue.outputs.issue_exists }}"
|
|
199
|
+
existing_issue="${{ steps.check-issue.outputs.issue_number }}"
|
|
89
200
|
|
|
90
201
|
# Read SPEC content (skip YAML frontmatter: 9 lines + 1 blank = 10 lines total)
|
|
91
202
|
# Start reading from line 11
|
|
@@ -114,33 +225,93 @@ jobs:
|
|
|
114
225
|
echo "📝 **Auto-synced**: This issue is automatically synchronized from the SPEC document"
|
|
115
226
|
} > /tmp/issue_body.txt
|
|
116
227
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
228
|
+
if [ "$issue_exists" = "true" ]; then
|
|
229
|
+
echo "📝 Updating existing issue #$existing_issue..."
|
|
230
|
+
echo " Title: [SPEC-$spec_id] $spec_title (v$spec_version)"
|
|
231
|
+
echo " Labels: spec, planning, $spec_priority"
|
|
121
232
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
233
|
+
# Update existing issue with new content and ensure proper labels
|
|
234
|
+
gh issue edit "$existing_issue" \
|
|
235
|
+
--title "[SPEC-$spec_id] $spec_title (v$spec_version)" \
|
|
236
|
+
--body-file /tmp/issue_body.txt \
|
|
237
|
+
--add-label "spec,planning,$spec_priority" \
|
|
238
|
+
--state open
|
|
239
|
+
|
|
240
|
+
issue_num=$existing_issue
|
|
241
|
+
echo "✅ Updated issue #$issue_num with latest SPEC version"
|
|
242
|
+
else
|
|
243
|
+
echo "📋 Creating new GitHub Issue..."
|
|
244
|
+
echo " Title: [SPEC-$spec_id] $spec_title (v$spec_version)"
|
|
245
|
+
echo " Body file: /tmp/issue_body.txt"
|
|
246
|
+
wc -l /tmp/issue_body.txt
|
|
247
|
+
|
|
248
|
+
# Create issue with labels using body-file
|
|
249
|
+
issue_output=$(gh issue create \
|
|
250
|
+
--title "[SPEC-$spec_id] $spec_title (v$spec_version)" \
|
|
251
|
+
--body-file /tmp/issue_body.txt \
|
|
252
|
+
--label "spec" \
|
|
253
|
+
--label "planning" \
|
|
254
|
+
--label "$spec_priority" 2>&1)
|
|
129
255
|
|
|
130
|
-
|
|
256
|
+
echo "$issue_output" | tee /tmp/issue_output.txt
|
|
131
257
|
|
|
132
|
-
|
|
133
|
-
|
|
258
|
+
# Extract issue number from output
|
|
259
|
+
issue_num=$(echo "$issue_output" | grep -oE '/issues/[0-9]+' | grep -oE '[0-9]+' | head -1)
|
|
134
260
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
261
|
+
if [ -z "$issue_num" ]; then
|
|
262
|
+
echo "⚠️ Could not extract issue number from output"
|
|
263
|
+
echo "Full output:"
|
|
264
|
+
cat /tmp/issue_output.txt
|
|
265
|
+
exit 1
|
|
266
|
+
fi
|
|
267
|
+
|
|
268
|
+
echo "✅ Created issue #$issue_num"
|
|
140
269
|
fi
|
|
141
270
|
|
|
142
271
|
echo "issue_number=$issue_num" >> $GITHUB_OUTPUT
|
|
143
|
-
|
|
272
|
+
|
|
273
|
+
- name: Validate SPEC issue labels
|
|
274
|
+
if: steps.create-issue.outputs.issue_number
|
|
275
|
+
id: validate-labels
|
|
276
|
+
env:
|
|
277
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
278
|
+
run: |
|
|
279
|
+
issue_num="${{ steps.create-issue.outputs.issue_number }}"
|
|
280
|
+
spec_priority="${{ steps.spec.outputs.spec_priority }}"
|
|
281
|
+
|
|
282
|
+
echo "🔍 Validating SPEC issue #$issue_num labels..."
|
|
283
|
+
|
|
284
|
+
# Get current labels
|
|
285
|
+
current_labels=$(gh issue view $issue_num --json labels --jq '.labels[].name' | tr '\n' ',' | sed 's/,$//')
|
|
286
|
+
echo "Current labels: $current_labels"
|
|
287
|
+
|
|
288
|
+
# Check for mandatory labels
|
|
289
|
+
needs_update=false
|
|
290
|
+
|
|
291
|
+
if [[ ! "$current_labels" =~ "spec" ]]; then
|
|
292
|
+
echo "⚠️ Missing 'spec' label, adding..."
|
|
293
|
+
gh issue edit $issue_num --add-label "spec"
|
|
294
|
+
needs_update=true
|
|
295
|
+
fi
|
|
296
|
+
|
|
297
|
+
if [[ ! "$current_labels" =~ "planning" ]]; then
|
|
298
|
+
echo "⚠️ Missing 'planning' label, adding..."
|
|
299
|
+
gh issue edit $issue_num --add-label "planning"
|
|
300
|
+
needs_update=true
|
|
301
|
+
fi
|
|
302
|
+
|
|
303
|
+
# Check for priority label
|
|
304
|
+
if [[ ! "$current_labels" =~ (critical|high|medium|low) ]]; then
|
|
305
|
+
echo "⚠️ No priority label found, adding '$spec_priority' as default"
|
|
306
|
+
gh issue edit $issue_num --add-label "$spec_priority"
|
|
307
|
+
needs_update=true
|
|
308
|
+
fi
|
|
309
|
+
|
|
310
|
+
if [ "$needs_update" = true ]; then
|
|
311
|
+
echo "✅ SPEC labels validated and corrected"
|
|
312
|
+
else
|
|
313
|
+
echo "✅ SPEC labels already valid"
|
|
314
|
+
fi
|
|
144
315
|
|
|
145
316
|
- name: Add PR comment
|
|
146
317
|
if: steps.create-issue.outputs.issue_number
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# @CODE:DOC-TAG-004 | Component 4: Automated TAG reporting workflow
|
|
2
|
+
name: TAG Report Generation
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
# Scheduled: Daily at 09:00 UTC
|
|
6
|
+
schedule:
|
|
7
|
+
- cron: '0 9 * * *'
|
|
8
|
+
|
|
9
|
+
# Event: Push to main/develop
|
|
10
|
+
push:
|
|
11
|
+
branches:
|
|
12
|
+
- main
|
|
13
|
+
- develop
|
|
14
|
+
|
|
15
|
+
# Manual: Workflow dispatch
|
|
16
|
+
workflow_dispatch:
|
|
17
|
+
inputs:
|
|
18
|
+
output_format:
|
|
19
|
+
description: 'Report format (all|inventory|matrix|statistics)'
|
|
20
|
+
required: false
|
|
21
|
+
default: 'all'
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
generate-tag-reports:
|
|
25
|
+
name: Generate TAG Reports
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
|
|
28
|
+
permissions:
|
|
29
|
+
contents: write # Required to commit reports back to repo
|
|
30
|
+
pull-requests: write # Required to comment on PRs
|
|
31
|
+
|
|
32
|
+
strategy:
|
|
33
|
+
matrix:
|
|
34
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
35
|
+
|
|
36
|
+
steps:
|
|
37
|
+
- name: Checkout repository
|
|
38
|
+
uses: actions/checkout@v4
|
|
39
|
+
with:
|
|
40
|
+
fetch-depth: 0 # Full history for accurate file modification times
|
|
41
|
+
|
|
42
|
+
- name: Setup Python
|
|
43
|
+
uses: actions/setup-python@v5
|
|
44
|
+
with:
|
|
45
|
+
python-version: ${{ matrix.python-version }}
|
|
46
|
+
|
|
47
|
+
- name: Install uv
|
|
48
|
+
uses: astral-sh/setup-uv@v5
|
|
49
|
+
with:
|
|
50
|
+
version: "latest"
|
|
51
|
+
|
|
52
|
+
- name: Install MoAI-ADK
|
|
53
|
+
run: |
|
|
54
|
+
uv pip install --system -e .
|
|
55
|
+
uv pip install --system requests
|
|
56
|
+
|
|
57
|
+
- name: Create reports directory
|
|
58
|
+
run: |
|
|
59
|
+
mkdir -p docs/reports
|
|
60
|
+
echo "Reports will be generated in docs/reports/"
|
|
61
|
+
|
|
62
|
+
- name: Generate TAG Inventory
|
|
63
|
+
run: |
|
|
64
|
+
python -c "
|
|
65
|
+
from moai_adk.core.tags.reporter import ReportGenerator
|
|
66
|
+
|
|
67
|
+
generator = ReportGenerator()
|
|
68
|
+
inventory = generator.generate_inventory_report('.')
|
|
69
|
+
|
|
70
|
+
with open('docs/reports/tag-inventory.md', 'w') as f:
|
|
71
|
+
f.write(inventory)
|
|
72
|
+
|
|
73
|
+
print('✅ Generated tag-inventory.md')
|
|
74
|
+
"
|
|
75
|
+
|
|
76
|
+
- name: Generate TAG Coverage Matrix
|
|
77
|
+
run: |
|
|
78
|
+
python -c "
|
|
79
|
+
from moai_adk.core.tags.reporter import ReportGenerator
|
|
80
|
+
|
|
81
|
+
generator = ReportGenerator()
|
|
82
|
+
matrix = generator.generate_matrix_report('.')
|
|
83
|
+
|
|
84
|
+
with open('docs/reports/tag-matrix.md', 'w') as f:
|
|
85
|
+
f.write(matrix)
|
|
86
|
+
|
|
87
|
+
print('✅ Generated tag-matrix.md')
|
|
88
|
+
"
|
|
89
|
+
|
|
90
|
+
- name: Generate TAG Statistics
|
|
91
|
+
run: |
|
|
92
|
+
python -c "
|
|
93
|
+
from moai_adk.core.tags.reporter import ReportGenerator
|
|
94
|
+
|
|
95
|
+
generator = ReportGenerator()
|
|
96
|
+
stats = generator.generate_statistics_report('.')
|
|
97
|
+
|
|
98
|
+
with open('docs/reports/tag-statistics.json', 'w') as f:
|
|
99
|
+
f.write(stats)
|
|
100
|
+
|
|
101
|
+
print('✅ Generated tag-statistics.json')
|
|
102
|
+
"
|
|
103
|
+
|
|
104
|
+
- name: Generate combined report
|
|
105
|
+
run: |
|
|
106
|
+
python -c "
|
|
107
|
+
from moai_adk.core.tags.reporter import ReportGenerator
|
|
108
|
+
from pathlib import Path
|
|
109
|
+
import json
|
|
110
|
+
|
|
111
|
+
generator = ReportGenerator()
|
|
112
|
+
result = generator.generate_all_reports('.', 'docs/reports')
|
|
113
|
+
|
|
114
|
+
if result.success:
|
|
115
|
+
print(f'✅ All reports generated successfully')
|
|
116
|
+
print(f' - Inventory: {result.inventory_path}')
|
|
117
|
+
print(f' - Matrix: {result.matrix_path}')
|
|
118
|
+
print(f' - Statistics: {result.statistics_path}')
|
|
119
|
+
|
|
120
|
+
# Read statistics for summary
|
|
121
|
+
stats = json.loads(result.statistics_path.read_text())
|
|
122
|
+
print(f'')
|
|
123
|
+
print(f'📊 Summary:')
|
|
124
|
+
print(f' - Total TAGs: {stats[\"total_tags\"]}')
|
|
125
|
+
print(f' - By Type: SPEC={stats[\"by_type\"].get(\"SPEC\", 0)}, CODE={stats[\"by_type\"].get(\"CODE\", 0)}, TEST={stats[\"by_type\"].get(\"TEST\", 0)}, DOC={stats[\"by_type\"].get(\"DOC\", 0)}')
|
|
126
|
+
print(f' - Coverage: {stats[\"coverage\"].get(\"overall_percentage\", 0)}%')
|
|
127
|
+
else:
|
|
128
|
+
print(f'❌ Report generation failed: {result.error_message}')
|
|
129
|
+
exit(1)
|
|
130
|
+
"
|
|
131
|
+
|
|
132
|
+
- name: Check for changes
|
|
133
|
+
id: git_status
|
|
134
|
+
run: |
|
|
135
|
+
if [ -n "$(git status --porcelain docs/reports/)" ]; then
|
|
136
|
+
echo "changes=true" >> $GITHUB_OUTPUT
|
|
137
|
+
echo "📝 TAG reports have changed"
|
|
138
|
+
else
|
|
139
|
+
echo "changes=false" >> $GITHUB_OUTPUT
|
|
140
|
+
echo "✅ TAG reports unchanged (no commit needed)"
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
- name: Commit reports
|
|
144
|
+
if: steps.git_status.outputs.changes == 'true'
|
|
145
|
+
run: |
|
|
146
|
+
git config --global user.name 'github-actions[bot]'
|
|
147
|
+
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
|
|
148
|
+
git add docs/reports/
|
|
149
|
+
git commit -m "docs(tags): Update TAG reports [automated]
|
|
150
|
+
|
|
151
|
+
- Updated tag-inventory.md
|
|
152
|
+
- Updated tag-matrix.md
|
|
153
|
+
- Updated tag-statistics.json
|
|
154
|
+
|
|
155
|
+
Generated by: GitHub Actions workflow (tag-report.yml)
|
|
156
|
+
Triggered: ${{ github.event_name }}
|
|
157
|
+
Commit: ${{ github.sha }}
|
|
158
|
+
|
|
159
|
+
🤖 Generated with MoAI-ADK TAG Reporting System
|
|
160
|
+
"
|
|
161
|
+
git push
|
|
162
|
+
|
|
163
|
+
- name: Create GitHub Release Notes
|
|
164
|
+
if: github.ref == 'refs/heads/main' && steps.git_status.outputs.changes == 'true'
|
|
165
|
+
run: |
|
|
166
|
+
echo "📊 TAG System Health Report" > report_summary.md
|
|
167
|
+
echo "" >> report_summary.md
|
|
168
|
+
echo "Generated: $(date -u +'%Y-%m-%d %H:%M:%S UTC')" >> report_summary.md
|
|
169
|
+
echo "" >> report_summary.md
|
|
170
|
+
|
|
171
|
+
# Extract key metrics from statistics
|
|
172
|
+
python -c "
|
|
173
|
+
import json
|
|
174
|
+
from pathlib import Path
|
|
175
|
+
|
|
176
|
+
stats = json.loads(Path('docs/reports/tag-statistics.json').read_text())
|
|
177
|
+
|
|
178
|
+
print(f'## Summary')
|
|
179
|
+
print(f'')
|
|
180
|
+
print(f'- **Total TAGs**: {stats[\"total_tags\"]}')
|
|
181
|
+
print(f'- **By Type**:')
|
|
182
|
+
print(f' - SPEC: {stats[\"by_type\"].get(\"SPEC\", 0)}')
|
|
183
|
+
print(f' - CODE: {stats[\"by_type\"].get(\"CODE\", 0)}')
|
|
184
|
+
print(f' - TEST: {stats[\"by_type\"].get(\"TEST\", 0)}')
|
|
185
|
+
print(f' - DOC: {stats[\"by_type\"].get(\"DOC\", 0)}')
|
|
186
|
+
print(f'')
|
|
187
|
+
print(f'## Coverage')
|
|
188
|
+
print(f'')
|
|
189
|
+
print(f'- **Overall**: {stats[\"coverage\"].get(\"overall_percentage\", 0)}%')
|
|
190
|
+
print(f'- **SPEC → CODE**: {stats[\"coverage\"].get(\"spec_to_code\", 0)}%')
|
|
191
|
+
print(f'- **CODE → TEST**: {stats[\"coverage\"].get(\"code_to_test\", 0)}%')
|
|
192
|
+
print(f'')
|
|
193
|
+
print(f'## Issues')
|
|
194
|
+
print(f'')
|
|
195
|
+
print(f'- **Orphan TAGs**: {stats[\"issues\"].get(\"orphan_count\", 0)}')
|
|
196
|
+
print(f'- **Incomplete Chains**: {stats[\"issues\"].get(\"incomplete_chains\", 0)}')
|
|
197
|
+
print(f'')
|
|
198
|
+
print(f'## Reports')
|
|
199
|
+
print(f'')
|
|
200
|
+
print(f'- [TAG Inventory](./docs/reports/tag-inventory.md)')
|
|
201
|
+
print(f'- [Coverage Matrix](./docs/reports/tag-matrix.md)')
|
|
202
|
+
print(f'- [Statistics (JSON)](./docs/reports/tag-statistics.json)')
|
|
203
|
+
" >> report_summary.md
|
|
204
|
+
|
|
205
|
+
cat report_summary.md
|
|
206
|
+
|
|
207
|
+
- name: Upload reports as artifacts
|
|
208
|
+
uses: actions/upload-artifact@v4
|
|
209
|
+
with:
|
|
210
|
+
name: tag-reports-${{ github.sha }}
|
|
211
|
+
path: docs/reports/
|
|
212
|
+
retention-days: 90
|
|
213
|
+
|
|
214
|
+
- name: Post summary to GitHub Actions UI
|
|
215
|
+
run: |
|
|
216
|
+
echo "## 📊 TAG Report Generation Complete" >> $GITHUB_STEP_SUMMARY
|
|
217
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
|
218
|
+
|
|
219
|
+
python -c "
|
|
220
|
+
import json
|
|
221
|
+
from pathlib import Path
|
|
222
|
+
|
|
223
|
+
stats = json.loads(Path('docs/reports/tag-statistics.json').read_text())
|
|
224
|
+
|
|
225
|
+
print(f'### Summary')
|
|
226
|
+
print(f'')
|
|
227
|
+
print(f'| Metric | Value |')
|
|
228
|
+
print(f'|--------|-------|')
|
|
229
|
+
print(f'| Total TAGs | {stats[\"total_tags\"]} |')
|
|
230
|
+
print(f'| SPEC | {stats[\"by_type\"].get(\"SPEC\", 0)} |')
|
|
231
|
+
print(f'| CODE | {stats[\"by_type\"].get(\"CODE\", 0)} |')
|
|
232
|
+
print(f'| TEST | {stats[\"by_type\"].get(\"TEST\", 0)} |')
|
|
233
|
+
print(f'| DOC | {stats[\"by_type\"].get(\"DOC\", 0)} |')
|
|
234
|
+
print(f'| Overall Coverage | {stats[\"coverage\"].get(\"overall_percentage\", 0)}% |')
|
|
235
|
+
print(f'| Orphan TAGs | {stats[\"issues\"].get(\"orphan_count\", 0)} |')
|
|
236
|
+
print(f'| Incomplete Chains | {stats[\"issues\"].get(\"incomplete_chains\", 0)} |')
|
|
237
|
+
print(f'')
|
|
238
|
+
print(f'### Generated Files')
|
|
239
|
+
print(f'')
|
|
240
|
+
print(f'- ✅ tag-inventory.md')
|
|
241
|
+
print(f'- ✅ tag-matrix.md')
|
|
242
|
+
print(f'- ✅ tag-statistics.json')
|
|
243
|
+
" >> $GITHUB_STEP_SUMMARY
|
|
244
|
+
|
|
245
|
+
- name: Fail workflow if issues detected (optional)
|
|
246
|
+
if: always()
|
|
247
|
+
run: |
|
|
248
|
+
python -c "
|
|
249
|
+
import json
|
|
250
|
+
from pathlib import Path
|
|
251
|
+
import sys
|
|
252
|
+
|
|
253
|
+
stats = json.loads(Path('docs/reports/tag-statistics.json').read_text())
|
|
254
|
+
|
|
255
|
+
orphan_count = stats['issues'].get('orphan_count', 0)
|
|
256
|
+
incomplete_count = stats['issues'].get('incomplete_chains', 0)
|
|
257
|
+
|
|
258
|
+
# Optional: Fail workflow if too many issues
|
|
259
|
+
# Uncomment to enable strict validation
|
|
260
|
+
# if orphan_count > 10 or incomplete_count > 10:
|
|
261
|
+
# print(f'❌ Too many TAG issues detected!')
|
|
262
|
+
# print(f' Orphans: {orphan_count}')
|
|
263
|
+
# print(f' Incomplete: {incomplete_count}')
|
|
264
|
+
# sys.exit(1)
|
|
265
|
+
|
|
266
|
+
print(f'✅ TAG system health check passed')
|
|
267
|
+
print(f' Orphans: {orphan_count}')
|
|
268
|
+
print(f' Incomplete: {incomplete_count}')
|
|
269
|
+
"
|