@mokoconsulting/mcp-mokosuite 1.0.0

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.
Files changed (73) hide show
  1. package/.editorconfig +19 -0
  2. package/.gitattributes +94 -0
  3. package/.gitmessage +9 -0
  4. package/.mokogit/ISSUE_TEMPLATE/adr.md +110 -0
  5. package/.mokogit/ISSUE_TEMPLATE/bug_report.md +48 -0
  6. package/.mokogit/ISSUE_TEMPLATE/config.yml +18 -0
  7. package/.mokogit/ISSUE_TEMPLATE/documentation.md +52 -0
  8. package/.mokogit/ISSUE_TEMPLATE/feature_request.md +51 -0
  9. package/.mokogit/ISSUE_TEMPLATE/mcp_api_integration.md +48 -0
  10. package/.mokogit/ISSUE_TEMPLATE/mcp_connection_issue.md +69 -0
  11. package/.mokogit/ISSUE_TEMPLATE/mcp_tool_request.md +50 -0
  12. package/.mokogit/ISSUE_TEMPLATE/question.md +82 -0
  13. package/.mokogit/ISSUE_TEMPLATE/rfc.md +126 -0
  14. package/.mokogit/ISSUE_TEMPLATE/security.md +51 -0
  15. package/.mokogit/ISSUE_TEMPLATE/version.md +24 -0
  16. package/.mokogit/actions/resolve-source-dir/action.yml +108 -0
  17. package/.mokogit/workflows/auto-assign.yml +76 -0
  18. package/.mokogit/workflows/auto-bump.yml +78 -0
  19. package/.mokogit/workflows/auto-dev-issue.yml +207 -0
  20. package/.mokogit/workflows/auto-release.yml +596 -0
  21. package/.mokogit/workflows/branch-cleanup.yml +60 -0
  22. package/.mokogit/workflows/cascade-dev.yml +198 -0
  23. package/.mokogit/workflows/changelog-validation.yml +101 -0
  24. package/.mokogit/workflows/ci-generic.yml +203 -0
  25. package/.mokogit/workflows/ci-issue-reporter.yml +75 -0
  26. package/.mokogit/workflows/cleanup.yml +87 -0
  27. package/.mokogit/workflows/gitleaks.yml +94 -0
  28. package/.mokogit/workflows/issue-branch.yml +81 -0
  29. package/.mokogit/workflows/notify.yml +73 -0
  30. package/.mokogit/workflows/npm-build-test.yml +83 -0
  31. package/.mokogit/workflows/npm-publish.yml +126 -0
  32. package/.mokogit/workflows/npm-sdk-check.yml +110 -0
  33. package/.mokogit/workflows/npm-tool-inventory.yml +80 -0
  34. package/.mokogit/workflows/pr-branch-check.yml +90 -0
  35. package/.mokogit/workflows/pr-check.yml +565 -0
  36. package/.mokogit/workflows/pre-release.yml +413 -0
  37. package/.mokogit/workflows/push-notify.yml +43 -0
  38. package/.mokogit/workflows/rc-revert.yml +72 -0
  39. package/.mokogit/workflows/repo-health.yml +700 -0
  40. package/.mokogit/workflows/repository-cleanup.yml +525 -0
  41. package/.mokogit/workflows/standards-compliance.yml +2507 -0
  42. package/.mokogit/workflows/sync-version-on-merge.yml +130 -0
  43. package/.mokogit/workflows/version-set.yml +131 -0
  44. package/CHANGELOG.md +18 -0
  45. package/CLAUDE.md +52 -0
  46. package/CODE_OF_CONDUCT.md +70 -0
  47. package/CONTRIBUTING.md +161 -0
  48. package/LICENSE +696 -0
  49. package/Makefile +70 -0
  50. package/README.md +83 -0
  51. package/SECURITY.md +34 -0
  52. package/config.example.json +21 -0
  53. package/dist/client.d.ts +22 -0
  54. package/dist/client.js +124 -0
  55. package/dist/config.d.ts +4 -0
  56. package/dist/config.js +53 -0
  57. package/dist/index.d.ts +3 -0
  58. package/dist/index.js +181 -0
  59. package/dist/signing.d.ts +14 -0
  60. package/dist/signing.js +62 -0
  61. package/dist/types.d.ts +44 -0
  62. package/dist/types.js +16 -0
  63. package/docs/API.md +63 -0
  64. package/docs/ARCHITECTURE.md +73 -0
  65. package/docs/INSTALLATION.md +102 -0
  66. package/docs/index.md +12 -0
  67. package/package.json +35 -0
  68. package/src/client.ts +142 -0
  69. package/src/config.ts +63 -0
  70. package/src/index.ts +336 -0
  71. package/src/signing.ts +67 -0
  72. package/src/types.ts +63 -0
  73. package/tsconfig.json +19 -0
@@ -0,0 +1,2507 @@
1
+ # Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
2
+ # SPDX-License-Identifier: GPL-3.0-or-later
3
+ # FILE INFORMATION
4
+ # DEFGROUP: GitHub.Workflow
5
+ # INGROUP: MokoCLI.Compliance
6
+ # REPO: https://github.com/mokoconsulting-tech/mokocli
7
+ # PATH: /.mokogit/workflows/standards-compliance.yml
8
+ # VERSION: 04.06.00
9
+ # BRIEF: MokoCLI compliance validation workflow
10
+ # NOTE: Validates repository structure, documentation, and coding standards
11
+
12
+ name: "Generic: Standards Compliance"
13
+
14
+ # ╔════════════════════════════════════════════════════════════════════════╗
15
+ # ║ MOKOSTANDARDS COMPLIANCE WORKFLOW ║
16
+ # ╠════════════════════════════════════════════════════════════════════════╣
17
+ # ║ ║
18
+ # ║ 28 checks across 4 priority tiers: ║
19
+ # ║ ║
20
+ # ║ TIER 1 — CRITICAL (must pass) ║
21
+ # ║ license-compliance, repository-structure, ║
22
+ # ║ coding-standards, version-consistency ║
23
+ # ║ ║
24
+ # ║ TIER 2 — IMPORTANT (should pass) ║
25
+ # ║ workflow-validation, documentation-quality, readme-completeness, ║
26
+ # ║ git-hygiene, script-integrity ║
27
+ # ║ ║
28
+ # ║ TIER 3 — QUALITY (code metrics) ║
29
+ # ║ line-length, file-naming, insecure-patterns, complexity, ║
30
+ # ║ duplication, dead-code ║
31
+ # ║ ║
32
+ # ║ TIER 4 — SUPPLEMENTARY (informational) ║
33
+ # ║ file-size, binary, todo, deps, links, api-docs, accessibility, ║
34
+ # ║ performance, enterprise, health, terraform ║
35
+ # ║ ║
36
+ # ║ File size: warning >15MB, critical >20MB ║
37
+ # ║ Exempt: .mmdb, .woff2, .woff, .ttf, .otf ║
38
+ # ║ ║
39
+ # ╚════════════════════════════════════════════════════════════════════════╝
40
+
41
+ env:
42
+ WORKFLOW_VERSION: "04.04.01"
43
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
44
+
45
+ # MokoCLI Policy Compliance:
46
+ # - File formatting: Enforces organizational coding standards
47
+ # - Reference: docs/policy/file-formatting.md
48
+
49
+ # ┌─────────────────────────────────────────────────────────────────────────┐
50
+ # │ WORKFLOW FLOW DIAGRAM │
51
+ # └─────────────────────────────────────────────────────────────────────────┘
52
+ #
53
+ # TRIGGER: Push/PR to main/dev/rc branches
54
+ # │
55
+ # ▼
56
+ # ┌──────────────────────────────────────────────────────────────┐
57
+ # │ PARALLEL VALIDATION CHECKS │
58
+ # └──────────────────────────────────────────────────────────────┘
59
+ # │
60
+ # ├─────────────┬──────────────┬──────────────┬────────────┐
61
+ # ▼ ▼ ▼ ▼ ▼
62
+ # ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ ┌──────────┐
63
+ # │Repository │File Header │Code Style│ │ Docs │ │ License │
64
+ # │Structure│ │ Validation│ │ Check │ │ Check │ │ Check │
65
+ # └─────────┘ └──────────┘ └──────────┘ └─────────┘ └──────────┘
66
+ # │ │ │ │ │
67
+ # ▼ ▼ ▼ ▼ ▼
68
+ # ┌─────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ ┌──────────┐
69
+ # │ Check │ │ Verify │ │ Run │ │ Check │ │ Verify │
70
+ # │Required │ │Copyright │ │ Linters │ │README │ │SPDX-ID │
71
+ # │ Dirs │ │ Header │ │(Python, │ │ Exists │ │ Present │
72
+ # │ │ │ Format │ │PHP,YAML) │ │ │ │ │
73
+ # └─────────┘ └──────────┘ └──────────┘ └─────────┘ └──────────┘
74
+ # │ │ │ │ │
75
+ # └─────────────┴──────────────┴──────────────┴────────────┘
76
+ # │
77
+ # ▼
78
+ # ┌──────────────────┐
79
+ # │ All Checks Pass?│
80
+ # └──────────────────┘
81
+ # │ │
82
+ # YES │ │ NO
83
+ # ▼ ▼
84
+ # ┌──────────┐ ┌──────────────┐
85
+ # │ SUCCESS │ │ CREATE ISSUE │
86
+ # │ Summary │ │ with Failure │
87
+ # └──────────┘ │ Details │
88
+ # └──────────────┘
89
+
90
+ on:
91
+ push:
92
+ branches: [main, dev/**, rc/**, version/**]
93
+ pull_request:
94
+ branches: [main, dev/**, rc/**]
95
+ workflow_dispatch:
96
+
97
+ permissions:
98
+ contents: read
99
+ pull-requests: write
100
+ issues: write
101
+
102
+ jobs:
103
+ # ════════════════════════════════════════════════════════════════════════
104
+ # TIER 1 — CRITICAL (must pass, blocks merge)
105
+ # ════════════════════════════════════════════════════════════════════════
106
+ license-compliance:
107
+ name: License Header Validation
108
+ runs-on: ubuntu-latest
109
+
110
+ steps:
111
+ - name: Checkout Repository
112
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
113
+
114
+ - name: Check SPDX Headers
115
+ run: |
116
+ set -x
117
+ echo "### SPDX License Header Check" >> $GITHUB_STEP_SUMMARY
118
+
119
+ # Count source files with and without SPDX headers
120
+ TOTAL_PHP=0
121
+ WITH_SPDX_PHP=0
122
+
123
+ if find . -name "*.php" -type f ! -path "./vendor/*" | head -1 | grep -q .; then
124
+ TOTAL_PHP=$(find . -name "*.php" -type f ! -path "./vendor/*" | wc -l)
125
+ WITH_SPDX_PHP=$(find . -name "*.php" -type f ! -path "./vendor/*" -exec grep -l "SPDX-License-Identifier" {} \; | wc -l)
126
+ fi
127
+
128
+ if [ "$TOTAL_PHP" -gt 0 ]; then
129
+ PERCENT=$((WITH_SPDX_PHP * 100 / TOTAL_PHP))
130
+ echo "- PHP files: $WITH_SPDX_PHP/$TOTAL_PHP ($PERCENT%) with SPDX headers" >> $GITHUB_STEP_SUMMARY
131
+
132
+ if [ "$PERCENT" -lt 80 ]; then
133
+ echo "⚠️ Less than 80% of PHP files have SPDX headers" >> $GITHUB_STEP_SUMMARY
134
+ else
135
+ echo "✅ Good SPDX header coverage" >> $GITHUB_STEP_SUMMARY
136
+ fi
137
+ fi
138
+
139
+ - name: Validate License File
140
+ run: |
141
+ set -x
142
+ echo "" >> $GITHUB_STEP_SUMMARY
143
+ echo "### License File Validation" >> $GITHUB_STEP_SUMMARY
144
+
145
+ if [ ! -f "LICENSE" ]; then
146
+ echo "❌ LICENSE file not found" >> $GITHUB_STEP_SUMMARY
147
+ echo "" >> $GITHUB_STEP_SUMMARY
148
+ echo "### ❌ Validation Failed: LICENSE File Missing" >> $GITHUB_STEP_SUMMARY
149
+ echo "" >> $GITHUB_STEP_SUMMARY
150
+ echo "**Error:** LICENSE file is required for all MokoCLI-compliant repositories" >> $GITHUB_STEP_SUMMARY
151
+ echo "**Action Required:** Add LICENSE file with appropriate open-source license (GPL-3.0-or-later recommended)" >> $GITHUB_STEP_SUMMARY
152
+ echo ""
153
+ echo "❌ ERROR: LICENSE file not found - This is a critical requirement"
154
+ exit 1
155
+ fi
156
+
157
+ # Check license type
158
+ if grep -qi "GNU GENERAL PUBLIC LICENSE" LICENSE; then
159
+ VERSION=$(grep -i "Version 3" LICENSE || echo "")
160
+ if [ -n "$VERSION" ]; then
161
+ echo "✅ GPL-3.0-or-later license detected" >> $GITHUB_STEP_SUMMARY
162
+ else
163
+ echo "⚠️ GPL license detected but version unclear" >> $GITHUB_STEP_SUMMARY
164
+ fi
165
+ elif grep -qi "MIT License" LICENSE; then
166
+ echo "✅ MIT license detected" >> $GITHUB_STEP_SUMMARY
167
+ elif grep -qi "Apache License" LICENSE; then
168
+ echo "✅ Apache license detected" >> $GITHUB_STEP_SUMMARY
169
+ else
170
+ echo "ℹ️ License type could not be automatically detected" >> $GITHUB_STEP_SUMMARY
171
+ fi
172
+
173
+ repository-structure:
174
+ name: Repository Structure Validation
175
+ runs-on: ubuntu-latest
176
+
177
+ steps:
178
+ - name: Checkout Repository
179
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
180
+
181
+ - name: Check Required Directories
182
+ run: |
183
+ set -x
184
+ echo "## 📁 Repository Structure Validation" >> $GITHUB_STEP_SUMMARY
185
+ echo "" >> $GITHUB_STEP_SUMMARY
186
+
187
+ MISSING=0
188
+ PRESENT=0
189
+ TOTAL=1
190
+
191
+ echo "### Required Directories" >> $GITHUB_STEP_SUMMARY
192
+ echo "" >> $GITHUB_STEP_SUMMARY
193
+ echo "| Directory | Status | Files | Size | Notes |" >> $GITHUB_STEP_SUMMARY
194
+ echo "|-----------|--------|-------|------|-------|" >> $GITHUB_STEP_SUMMARY
195
+
196
+ # Check required directories
197
+ for dir in .mokogit; do
198
+ if [ -d "$dir" ]; then
199
+ FILE_COUNT=$(find "$dir" -type f 2>/dev/null | wc -l)
200
+ DIR_SIZE=$(du -sh "$dir" 2>/dev/null | cut -f1)
201
+ echo "| $dir/ | ✅ Pass | $FILE_COUNT files | $DIR_SIZE | Complete |" >> $GITHUB_STEP_SUMMARY
202
+ PRESENT=$((PRESENT + 1))
203
+ else
204
+ echo "| $dir/ | ❌ **Missing** | - | - | **Action Required** |" >> $GITHUB_STEP_SUMMARY
205
+ MISSING=$((MISSING + 1))
206
+ fi
207
+ done
208
+
209
+ echo "" >> $GITHUB_STEP_SUMMARY
210
+ PERCENT=$((PRESENT * 100 / TOTAL))
211
+ echo "**Compliance Score:** $PERCENT% ($PRESENT/$TOTAL directories present)" >> $GITHUB_STEP_SUMMARY
212
+
213
+ if [ "$MISSING" -gt 0 ]; then
214
+ echo "" >> $GITHUB_STEP_SUMMARY
215
+ echo "### 🔴 Critical Issues: $MISSING" >> $GITHUB_STEP_SUMMARY
216
+ echo "" >> $GITHUB_STEP_SUMMARY
217
+ echo "**Remediation Steps:**" >> $GITHUB_STEP_SUMMARY
218
+ [ ! -d ".mokogit" ] && echo "- Create .mokogit directory: \`mkdir -p .mokogit/workflows\`" >> $GITHUB_STEP_SUMMARY
219
+ echo "" >> $GITHUB_STEP_SUMMARY
220
+ echo "📚 Reference: [MokoCLI Repository Structure](https://github.com/mokoconsulting-tech/mokocli/tree/main/docs/policy/core-structure.md)" >> $GITHUB_STEP_SUMMARY
221
+ echo "" >> $GITHUB_STEP_SUMMARY
222
+ echo "### ❌ Validation Failed: Required Directories Missing" >> $GITHUB_STEP_SUMMARY
223
+ echo "" >> $GITHUB_STEP_SUMMARY
224
+ echo "**Status:** Repository structure does not meet MokoCLI requirements" >> $GITHUB_STEP_SUMMARY
225
+ echo "**Missing:** $MISSING required director(y|ies)" >> $GITHUB_STEP_SUMMARY
226
+ echo "**Compliance:** $PERCENT% ($PRESENT/$TOTAL directories present)" >> $GITHUB_STEP_SUMMARY
227
+ echo ""
228
+ echo "❌ ERROR: Required directories missing - See job summary for remediation steps"
229
+ exit 1
230
+ fi
231
+
232
+ - name: Check Required Files
233
+ run: |
234
+ set -x
235
+ echo "" >> $GITHUB_STEP_SUMMARY
236
+ echo "### Required Files" >> $GITHUB_STEP_SUMMARY
237
+ echo "" >> $GITHUB_STEP_SUMMARY
238
+
239
+ MISSING=0
240
+ PRESENT=0
241
+ TOTAL=5
242
+
243
+ echo "| File | Status | Size | Last Modified | Notes |" >> $GITHUB_STEP_SUMMARY
244
+ echo "|------|--------|------|---------------|-------|" >> $GITHUB_STEP_SUMMARY
245
+
246
+ # Check required files (CHANGELOG handled separately via find -iname to support src/ChangeLog.md)
247
+ for file in README.md LICENSE CONTRIBUTING.md SECURITY.md .editorconfig; do
248
+ if [ -f "$file" ]; then
249
+ FILE_SIZE=$(wc -c < "$file" 2>/dev/null | awk '{printf "%.1f KB", $1/1024}')
250
+ LAST_MOD=$(stat -c %y "$file" 2>/dev/null | cut -d' ' -f1 || echo "Unknown")
251
+ CONTENT_CHECK=""
252
+
253
+ # Basic content validation
254
+ case "$file" in
255
+ "README.md")
256
+ LINES=$(wc -l < "$file")
257
+ [ "$LINES" -lt 10 ] && CONTENT_CHECK="⚠️ Too short"
258
+ ;;
259
+ "LICENSE")
260
+ [ $(wc -c < "$file") -lt 100 ] && CONTENT_CHECK="⚠️ Incomplete?"
261
+ ;;
262
+ esac
263
+
264
+ echo "| $file | ✅ Pass | $FILE_SIZE | $LAST_MOD | Complete $CONTENT_CHECK |" >> $GITHUB_STEP_SUMMARY
265
+ PRESENT=$((PRESENT + 1))
266
+ else
267
+ echo "| $file | ❌ **Missing** | - | - | **Required** |" >> $GITHUB_STEP_SUMMARY
268
+ MISSING=$((MISSING + 1))
269
+ fi
270
+ done
271
+
272
+ echo "" >> $GITHUB_STEP_SUMMARY
273
+ PERCENT=$((PRESENT * 100 / TOTAL))
274
+ echo "**Compliance Score:** $PERCENT% ($PRESENT/$TOTAL files present)" >> $GITHUB_STEP_SUMMARY
275
+
276
+ if [ "$MISSING" -gt 0 ]; then
277
+ echo "" >> $GITHUB_STEP_SUMMARY
278
+ echo "### 🔴 Critical Issues: $MISSING" >> $GITHUB_STEP_SUMMARY
279
+ echo "" >> $GITHUB_STEP_SUMMARY
280
+ echo "**Remediation Steps:**" >> $GITHUB_STEP_SUMMARY
281
+ [ ! -f "README.md" ] && echo "- Create README.md: Use [template](https://github.com/mokoconsulting-tech/mokocli/tree/main/templates/docs/required/README.md)" >> $GITHUB_STEP_SUMMARY
282
+ [ ! -f "LICENSE" ] && echo "- Add LICENSE file: Choose from [OSI-approved licenses](https://opensource.org/licenses)" >> $GITHUB_STEP_SUMMARY
283
+ [ ! -f "CONTRIBUTING.md" ] && echo "- Create CONTRIBUTING.md: Use [template](https://github.com/mokoconsulting-tech/mokocli/tree/main/templates/docs/required/CONTRIBUTING.md)" >> $GITHUB_STEP_SUMMARY
284
+ [ ! -f "SECURITY.md" ] && echo "- Create SECURITY.md: Use [template](https://github.com/mokoconsulting-tech/mokocli/tree/main/templates/docs/required/SECURITY.md)" >> $GITHUB_STEP_SUMMARY
285
+ [ ! -f ".editorconfig" ] && echo "- Add .editorconfig: Use [template](https://github.com/mokoconsulting-tech/mokocli/tree/main/templates/.editorconfig)" >> $GITHUB_STEP_SUMMARY
286
+ echo "" >> $GITHUB_STEP_SUMMARY
287
+ echo "📚 Reference: [MokoCLI File Requirements](https://github.com/mokoconsulting-tech/mokocli/tree/main/docs/policy/file-header-standards.md)" >> $GITHUB_STEP_SUMMARY
288
+ echo "" >> $GITHUB_STEP_SUMMARY
289
+ echo "### ❌ Validation Failed: Required Files Missing" >> $GITHUB_STEP_SUMMARY
290
+ echo "" >> $GITHUB_STEP_SUMMARY
291
+ echo "**Status:** Repository files do not meet MokoCLI requirements" >> $GITHUB_STEP_SUMMARY
292
+ echo "**Missing:** $MISSING required file(s)" >> $GITHUB_STEP_SUMMARY
293
+ echo "**Compliance:** $PERCENT% ($PRESENT/$TOTAL files present)" >> $GITHUB_STEP_SUMMARY
294
+ echo ""
295
+ echo "❌ ERROR: Required files missing - See job summary for remediation steps"
296
+ exit 1
297
+ fi
298
+
299
+ coding-standards:
300
+ name: Coding Standards Check
301
+ runs-on: ubuntu-latest
302
+
303
+ steps:
304
+ - name: Checkout Repository
305
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
306
+
307
+ - name: Check for Tab Characters
308
+ run: |
309
+ set -x
310
+ echo "### Tab Character Detection" >> $GITHUB_STEP_SUMMARY
311
+
312
+ # Policy: Tabs are DEFAULT. Only check for tabs in files that REQUIRE spaces.
313
+ # Languages requiring spaces: YAML, Python, Haskell, F#, CoffeeScript, Nim, JSON, RST
314
+ TABS_IN_SPACES_FILES=$(find . -type f \
315
+ \( -name "*.yml" -o -name "*.yaml" \
316
+ -o -name "*.py" \
317
+ -o -name "*.hs" -o -name "*.lhs" \
318
+ -o -name "*.fs" -o -name "*.fsx" -o -name "*.fsi" \
319
+ -o -name "*.coffee" -o -name "*.litcoffee" \
320
+ -o -name "*.nim" -o -name "*.nims" -o -name "*.nimble" \
321
+ -o -name "*.json" \
322
+ -o -name "*.rst" \) \
323
+ ! -path "./vendor/*" \
324
+ ! -path "./node_modules/*" \
325
+ ! -path "./.git/*" \
326
+ -exec grep -l $'\t' {} \; 2>/dev/null | head -10)
327
+
328
+ if [ -n "$TABS_IN_SPACES_FILES" ]; then
329
+ echo "⚠️ Tab characters found in files that require spaces:" >> $GITHUB_STEP_SUMMARY
330
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
331
+ echo "$TABS_IN_SPACES_FILES" >> $GITHUB_STEP_SUMMARY
332
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
333
+ echo "These languages require spaces (tabs will break): YAML, Python, Haskell, F#, CoffeeScript, Nim, JSON, RST" >> $GITHUB_STEP_SUMMARY
334
+ echo "All other files (including .md, .ps1, LICENSE, etc.) may use tabs per MokoCLI policy" >> $GITHUB_STEP_SUMMARY
335
+ else
336
+ echo "✅ No tabs found in files requiring spaces" >> $GITHUB_STEP_SUMMARY
337
+ echo "Note: Tabs are allowed in most files (policy default). Only checked files requiring spaces." >> $GITHUB_STEP_SUMMARY
338
+ fi
339
+
340
+ - name: Check File Encoding
341
+ run: |
342
+ set -x
343
+ echo "" >> $GITHUB_STEP_SUMMARY
344
+ echo "### File Encoding Check" >> $GITHUB_STEP_SUMMARY
345
+
346
+ # Check for UTF-8 encoding (ASCII is a subset of UTF-8 and is acceptable)
347
+ NON_UTF8=$(find . -type f \( -name "*.php" -o -name "*.js" -o -name "*.md" \) \
348
+ ! -path "./vendor/*" \
349
+ ! -path "./node_modules/*" \
350
+ ! -path "./.git/*" \
351
+ -exec file {} \; | grep -v "UTF-8" | grep -v "ASCII" | head -5 || true)
352
+
353
+ if [ -n "$NON_UTF8" ]; then
354
+ echo "⚠️ Non-UTF-8 files detected:" >> $GITHUB_STEP_SUMMARY
355
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
356
+ echo "$NON_UTF8" >> $GITHUB_STEP_SUMMARY
357
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
358
+ else
359
+ echo "✅ All source files appear to be UTF-8 encoded" >> $GITHUB_STEP_SUMMARY
360
+ fi
361
+
362
+ - name: Check Line Endings
363
+ run: |
364
+ set -x
365
+ echo "" >> $GITHUB_STEP_SUMMARY
366
+ echo "### Line Ending Check" >> $GITHUB_STEP_SUMMARY
367
+
368
+ # Check for CRLF line endings
369
+ CRLF_FILES=$(find . -type f \( -name "*.php" -o -name "*.js" -o -name "*.md" \) \
370
+ ! -path "./vendor/*" \
371
+ ! -path "./node_modules/*" \
372
+ ! -path "./.git/*" \
373
+ -exec file {} \; | grep "CRLF" | head -5 || true)
374
+
375
+ if [ -n "$CRLF_FILES" ]; then
376
+ echo "⚠️ Files with CRLF line endings found:" >> $GITHUB_STEP_SUMMARY
377
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
378
+ echo "$CRLF_FILES" >> $GITHUB_STEP_SUMMARY
379
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
380
+ echo "MokoCLI requires LF line endings" >> $GITHUB_STEP_SUMMARY
381
+ else
382
+ echo "✅ Line endings are consistent (LF)" >> $GITHUB_STEP_SUMMARY
383
+ fi
384
+
385
+ version-consistency:
386
+ name: Version Consistency Check
387
+ runs-on: ubuntu-latest
388
+
389
+ steps:
390
+ - name: Checkout Repository
391
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
392
+
393
+ - name: Set up PHP
394
+ uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.31.0
395
+ with:
396
+ php-version: '8.1'
397
+ extensions: json
398
+ tools: composer
399
+ coverage: none
400
+
401
+ - name: Setup MokoCLI tools
402
+ env:
403
+ GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
404
+ COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN || github.token }}"}}'
405
+ run: |
406
+ git clone --depth 1 --branch version/04 --quiet \
407
+ "https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/mokocli.git" \
408
+ /tmp/mokostandards 2>/dev/null || true
409
+ if [ -d "/tmp/mokostandards" ] && [ -f "/tmp/mokostandards/composer.json" ]; then
410
+ cd /tmp/mokostandards
411
+ composer install --no-dev --no-interaction --quiet 2>/dev/null || true
412
+ fi
413
+
414
+ - name: Run Version Consistency Check
415
+ id: version_check
416
+ run: |
417
+ set -x
418
+ echo "## 🔢 Version Consistency Validation" >> $GITHUB_STEP_SUMMARY
419
+ echo "" >> $GITHUB_STEP_SUMMARY
420
+
421
+ # Use MokoCLI tools (no Composer needed on the governed repo)
422
+ if [ -f "/tmp/mokostandards/api/validate/check_version_consistency.php" ]; then
423
+ php /tmp/mokostandards/api/validate/check_version_consistency.php --path . --verbose 2>&1 | tee /tmp/version-check.log
424
+ EXIT_CODE=${PIPESTATUS[0]}
425
+ elif [ -f "api/validate/check_version_consistency.php" ]; then
426
+ php api/validate/check_version_consistency.php --path . --verbose 2>&1 | tee /tmp/version-check.log
427
+ EXIT_CODE=${PIPESTATUS[0]}
428
+ else
429
+ echo "⏭️ MokoCLI tools not available — skipping version check" >> $GITHUB_STEP_SUMMARY
430
+ exit 0
431
+ fi
432
+
433
+ echo '```' >> $GITHUB_STEP_SUMMARY
434
+ cat /tmp/version-check.log >> $GITHUB_STEP_SUMMARY
435
+ echo '```' >> $GITHUB_STEP_SUMMARY
436
+
437
+ if [ "$EXIT_CODE" -eq 0 ]; then
438
+ echo "✅ All version numbers are consistent" >> $GITHUB_STEP_SUMMARY
439
+ else
440
+ echo "❌ Version drift detected" >> $GITHUB_STEP_SUMMARY
441
+ exit 1
442
+ fi
443
+
444
+
445
+ # ════════════════════════════════════════════════════════════════════════
446
+ # TIER 2 — IMPORTANT (should pass)
447
+ # ════════════════════════════════════════════════════════════════════════
448
+ workflow-validation:
449
+ name: Workflow Configuration Check
450
+ runs-on: ubuntu-latest
451
+
452
+ steps:
453
+ - name: Checkout Repository
454
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
455
+
456
+ - name: Check Required Workflows
457
+ run: |
458
+ set -x
459
+ echo "### GitHub Actions Workflows" >> $GITHUB_STEP_SUMMARY
460
+
461
+ WORKFLOWS_DIR=".mokogit/workflows"
462
+
463
+ if [ ! -d "$WORKFLOWS_DIR" ]; then
464
+ echo "❌ No workflows directory found" >> $GITHUB_STEP_SUMMARY
465
+ echo "" >> $GITHUB_STEP_SUMMARY
466
+ echo "### ❌ Validation Failed: Workflows Directory Missing" >> $GITHUB_STEP_SUMMARY
467
+ echo "" >> $GITHUB_STEP_SUMMARY
468
+ echo "**Error:** .mokogit/workflows directory is required for CI/CD automation" >> $GITHUB_STEP_SUMMARY
469
+ echo "**Action Required:** Create .mokogit/workflows directory and add GitHub Actions workflows" >> $GITHUB_STEP_SUMMARY
470
+ echo ""
471
+ echo "❌ ERROR: .mokogit/workflows directory not found"
472
+ exit 1
473
+ fi
474
+
475
+ # Check for recommended workflows
476
+ CI_FOUND=false
477
+ for wf in ci.yml build.yml ci-joomla.yml; do
478
+ if [ -f "$WORKFLOWS_DIR/$wf" ]; then
479
+ echo "✅ CI workflow present ($wf)" >> $GITHUB_STEP_SUMMARY
480
+ CI_FOUND=true
481
+ break
482
+ fi
483
+ done
484
+ if [ "$CI_FOUND" = "false" ]; then
485
+ echo "⚠️ No CI workflow found (ci.yml, build.yml, or ci-joomla.yml)" >> $GITHUB_STEP_SUMMARY
486
+ fi
487
+
488
+ if [ -f "$WORKFLOWS_DIR/codeql-analysis.yml" ]; then
489
+ echo "✅ CodeQL security scanning present" >> $GITHUB_STEP_SUMMARY
490
+ else
491
+ echo "⚠️ CodeQL workflow not found" >> $GITHUB_STEP_SUMMARY
492
+ fi
493
+
494
+ # Check for MokoCLI-synced workflows
495
+ for wf in deploy-dev.yml deploy-demo.yml deploy-rs.yml sync-version-on-merge.yml auto-release.yml standards-compliance.yml enterprise-firewall-setup.yml; do
496
+ if [ -f "$WORKFLOWS_DIR/$wf" ]; then
497
+ echo "✅ ${wf}" >> $GITHUB_STEP_SUMMARY
498
+ else
499
+ echo "⚠️ ${wf} not found (synced from MokoCLI)" >> $GITHUB_STEP_SUMMARY
500
+ fi
501
+ done
502
+
503
+ - name: Validate Workflow Syntax
504
+ run: |
505
+ set -x
506
+ echo "" >> $GITHUB_STEP_SUMMARY
507
+ echo "### Workflow YAML Syntax" >> $GITHUB_STEP_SUMMARY
508
+
509
+ INVALID=0
510
+ for workflow in $(find .mokogit/workflows -maxdepth 1 -type f \( -name "*.yml" -o -name "*.yaml" \) 2>/dev/null); do
511
+ if [ -f "$workflow" ]; then
512
+ if python3 -c "import yaml, sys; yaml.safe_load(open(sys.argv[1]))" "$workflow" 2>/dev/null; then
513
+ echo "✅ $(basename $workflow)" >> $GITHUB_STEP_SUMMARY
514
+ else
515
+ echo "❌ $(basename $workflow) - invalid YAML" >> $GITHUB_STEP_SUMMARY
516
+ INVALID=$((INVALID + 1))
517
+ fi
518
+ fi
519
+ done
520
+
521
+ if [ "$INVALID" -gt 0 ]; then
522
+ echo "" >> $GITHUB_STEP_SUMMARY
523
+ echo "### ❌ Validation Failed: Invalid Workflow YAML Syntax" >> $GITHUB_STEP_SUMMARY
524
+ echo "" >> $GITHUB_STEP_SUMMARY
525
+ echo "**Error:** $INVALID workflow file(s) have invalid YAML syntax" >> $GITHUB_STEP_SUMMARY
526
+ echo "**Action Required:** Fix YAML syntax errors in the marked workflow files" >> $GITHUB_STEP_SUMMARY
527
+ echo "**Tool:** Run \`python3 -c \"import yaml; yaml.safe_load(open('.mokogit/workflows/FILE.yml'))\"\` locally" >> $GITHUB_STEP_SUMMARY
528
+ echo ""
529
+ echo "❌ ERROR: $INVALID workflow file(s) with invalid YAML syntax"
530
+ exit 1
531
+ fi
532
+
533
+ echo "" >> $GITHUB_STEP_SUMMARY
534
+ echo "### ✅ All Workflow Files Have Valid YAML Syntax" >> $GITHUB_STEP_SUMMARY
535
+ echo ""
536
+ echo "✅ SUCCESS: All workflow files passed YAML validation"
537
+
538
+ - name: Validate CodeQL Configuration
539
+ if: hashFiles('.mokogit/workflows/codeql-analysis.yml') != ''
540
+ run: |
541
+ set -e
542
+ echo "" >> $GITHUB_STEP_SUMMARY
543
+ echo "### CodeQL Language Configuration" >> $GITHUB_STEP_SUMMARY
544
+ echo "" >> $GITHUB_STEP_SUMMARY
545
+
546
+ # Inline validation (rewritten from Python to bash for PHP-only architecture)
547
+ CODEQL_FILE=".mokogit/workflows/codeql-analysis.yml"
548
+
549
+ if [ ! -f "$CODEQL_FILE" ]; then
550
+ echo "⚠️ CodeQL workflow file not found" >> $GITHUB_STEP_SUMMARY
551
+ echo "" >> $GITHUB_STEP_SUMMARY
552
+ echo "### ⚠️ CodeQL Workflow Not Found" >> $GITHUB_STEP_SUMMARY
553
+ echo "" >> $GITHUB_STEP_SUMMARY
554
+ echo "**Status:** CodeQL workflow file not present - skipping language validation" >> $GITHUB_STEP_SUMMARY
555
+ echo ""
556
+ echo "⚠️ INFO: CodeQL workflow not found - Skipping validation"
557
+ exit 0
558
+ fi
559
+
560
+ echo "**CodeQL Configuration Analysis**" >> $GITHUB_STEP_SUMMARY
561
+ echo "" >> $GITHUB_STEP_SUMMARY
562
+
563
+ # Extract configured languages from workflow
564
+ LANGUAGES=$(grep -A5 "language:" "$CODEQL_FILE" | grep -oP "(?<=')[^']+(?=')" | tr '\n' ' ' || echo "")
565
+
566
+ # Check if this is a configuration-only scan (no languages specified)
567
+ if grep -q "category.*language:config" "$CODEQL_FILE"; then
568
+ echo "**Scan Type:** Configuration-only (no language matrix)" >> $GITHUB_STEP_SUMMARY
569
+ echo "**Status:** ✅ Valid configuration for PHP-only repository" >> $GITHUB_STEP_SUMMARY
570
+ echo "" >> $GITHUB_STEP_SUMMARY
571
+ echo "This CodeQL workflow scans YAML, JSON, shell scripts for security issues." >> $GITHUB_STEP_SUMMARY
572
+ echo "PHP security is handled by SecurityValidator enterprise library." >> $GITHUB_STEP_SUMMARY
573
+ echo "" >> $GITHUB_STEP_SUMMARY
574
+ echo "✅ SUCCESS: CodeQL configuration-only scan properly configured"
575
+ exit 0
576
+ fi
577
+
578
+ if [ -z "$LANGUAGES" ]; then
579
+ echo "❌ No languages configured in CodeQL workflow" >> $GITHUB_STEP_SUMMARY
580
+ echo "" >> $GITHUB_STEP_SUMMARY
581
+ echo "### ❌ Validation Failed: CodeQL Languages Not Configured" >> $GITHUB_STEP_SUMMARY
582
+ echo "" >> $GITHUB_STEP_SUMMARY
583
+ echo "**Error:** CodeQL workflow exists but has no languages configured" >> $GITHUB_STEP_SUMMARY
584
+ echo "**Action Required:** Configure appropriate languages in codeql-analysis.yml" >> $GITHUB_STEP_SUMMARY
585
+ echo ""
586
+ echo "❌ ERROR: No languages configured in CodeQL workflow"
587
+ exit 1
588
+ fi
589
+
590
+ echo "**Configured Languages:** $LANGUAGES" >> $GITHUB_STEP_SUMMARY
591
+ echo "" >> $GITHUB_STEP_SUMMARY
592
+
593
+ # Validate language presence in repository
594
+ INVALID_LANGS=""
595
+ VALID_LANGS=""
596
+
597
+ for LANG in $LANGUAGES; do
598
+ case "$LANG" in
599
+ python)
600
+ # Check for Python files (should be none in v04.00.04)
601
+ if find . -name "*.py" -type f ! -path "./.git/*" | grep -q .; then
602
+ VALID_LANGS="$VALID_LANGS python"
603
+ echo "✅ Python: Found Python files" >> $GITHUB_STEP_SUMMARY
604
+ else
605
+ INVALID_LANGS="$INVALID_LANGS python"
606
+ echo "❌ Python: No Python files found (PHP-only repository)" >> $GITHUB_STEP_SUMMARY
607
+ fi
608
+ ;;
609
+ javascript|typescript)
610
+ # Check for JS/TS files
611
+ if find . \( -name "*.js" -o -name "*.ts" -o -name "*.json" \) -type f ! -path "./.git/*" ! -path "./node_modules/*" | grep -q .; then
612
+ VALID_LANGS="$VALID_LANGS $LANG"
613
+ echo "✅ $LANG: Found JavaScript/TypeScript/JSON files" >> $GITHUB_STEP_SUMMARY
614
+ else
615
+ INVALID_LANGS="$INVALID_LANGS $LANG"
616
+ echo "⚠️ $LANG: No JavaScript/TypeScript files found" >> $GITHUB_STEP_SUMMARY
617
+ fi
618
+ ;;
619
+ java)
620
+ if find . -name "*.java" -type f ! -path "./.git/*" | grep -q .; then
621
+ VALID_LANGS="$VALID_LANGS java"
622
+ echo "✅ Java: Found Java files" >> $GITHUB_STEP_SUMMARY
623
+ else
624
+ INVALID_LANGS="$INVALID_LANGS java"
625
+ echo "⚠️ Java: No Java files found" >> $GITHUB_STEP_SUMMARY
626
+ fi
627
+ ;;
628
+ go)
629
+ if find . -name "*.go" -type f ! -path "./.git/*" | grep -q .; then
630
+ VALID_LANGS="$VALID_LANGS go"
631
+ echo "✅ Go: Found Go files" >> $GITHUB_STEP_SUMMARY
632
+ else
633
+ INVALID_LANGS="$INVALID_LANGS go"
634
+ echo "⚠️ Go: No Go files found" >> $GITHUB_STEP_SUMMARY
635
+ fi
636
+ ;;
637
+ cpp|c)
638
+ if find . \( -name "*.cpp" -o -name "*.c" -o -name "*.h" \) -type f ! -path "./.git/*" | grep -q .; then
639
+ VALID_LANGS="$VALID_LANGS $LANG"
640
+ echo "✅ $LANG: Found C/C++ files" >> $GITHUB_STEP_SUMMARY
641
+ else
642
+ INVALID_LANGS="$INVALID_LANGS $LANG"
643
+ echo "⚠️ $LANG: No C/C++ files found" >> $GITHUB_STEP_SUMMARY
644
+ fi
645
+ ;;
646
+ ruby)
647
+ if find . -name "*.rb" -type f ! -path "./.git/*" | grep -q .; then
648
+ VALID_LANGS="$VALID_LANGS ruby"
649
+ echo "✅ Ruby: Found Ruby files" >> $GITHUB_STEP_SUMMARY
650
+ else
651
+ INVALID_LANGS="$INVALID_LANGS ruby"
652
+ echo "⚠️ Ruby: No Ruby files found" >> $GITHUB_STEP_SUMMARY
653
+ fi
654
+ ;;
655
+ *)
656
+ echo "⚠️ $LANG: Unknown language, skipping validation" >> $GITHUB_STEP_SUMMARY
657
+ ;;
658
+ esac
659
+ done
660
+
661
+ echo "" >> $GITHUB_STEP_SUMMARY
662
+
663
+ # Report results
664
+ if [ -n "$INVALID_LANGS" ]; then
665
+ echo "**⚠️ Warning:** Some configured languages may not have corresponding files:" >> $GITHUB_STEP_SUMMARY
666
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
667
+ echo "Invalid languages: $INVALID_LANGS" >> $GITHUB_STEP_SUMMARY
668
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
669
+ echo "" >> $GITHUB_STEP_SUMMARY
670
+ echo "**Note:** This is informational. CodeQL will skip languages without source files." >> $GITHUB_STEP_SUMMARY
671
+ echo "For PHP repository (v04.00.04), JavaScript language covers JSON/YAML/shell scripts." >> $GITHUB_STEP_SUMMARY
672
+ else
673
+ echo "✅ **All configured CodeQL languages have corresponding source files**" >> $GITHUB_STEP_SUMMARY
674
+ fi
675
+
676
+ # Always succeed - this is informational only
677
+ echo "" >> $GITHUB_STEP_SUMMARY
678
+ echo "### ✅ CodeQL Configuration Validation Complete" >> $GITHUB_STEP_SUMMARY
679
+ echo "" >> $GITHUB_STEP_SUMMARY
680
+ echo "**Status:** CodeQL language configuration reviewed successfully" >> $GITHUB_STEP_SUMMARY
681
+ echo ""
682
+ echo "✅ SUCCESS: CodeQL validation complete"
683
+ exit 0
684
+
685
+ documentation-quality:
686
+ name: Documentation Quality Check
687
+ runs-on: ubuntu-latest
688
+
689
+ steps:
690
+ - name: Checkout Repository
691
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
692
+
693
+ - name: Validate README.md
694
+ run: |
695
+ set -x
696
+ echo "## 📚 Documentation Quality Check" >> $GITHUB_STEP_SUMMARY
697
+ echo "" >> $GITHUB_STEP_SUMMARY
698
+ echo "### README.md Analysis" >> $GITHUB_STEP_SUMMARY
699
+ echo "" >> $GITHUB_STEP_SUMMARY
700
+
701
+ if [ ! -f "README.md" ]; then
702
+ echo "❌ **Critical:** README.md not found" >> $GITHUB_STEP_SUMMARY
703
+ echo "" >> $GITHUB_STEP_SUMMARY
704
+ echo "### ❌ Validation Failed: README.md Missing" >> $GITHUB_STEP_SUMMARY
705
+ echo "" >> $GITHUB_STEP_SUMMARY
706
+ echo "**Error:** README.md is required for all MokoCLI-compliant repositories" >> $GITHUB_STEP_SUMMARY
707
+ echo "**Action Required:** Create README.md with project description, setup instructions, and usage examples" >> $GITHUB_STEP_SUMMARY
708
+ echo ""
709
+ echo "❌ ERROR: README.md not found - This is a critical requirement"
710
+ exit 1
711
+ fi
712
+
713
+ # Detailed content analysis
714
+ SIZE=$(wc -c < README.md)
715
+ LINES=$(wc -l < README.md)
716
+ WORDS=$(wc -w < README.md)
717
+ HEADINGS=$(grep -c "^#" README.md || echo 0)
718
+ LINKS=$(grep -c "\[.*\](.*)" README.md || echo 0)
719
+ CODE_BLOCKS=$(grep -c '```' README.md || echo 0)
720
+
721
+ echo "| Metric | Value | Status | Recommendation |" >> $GITHUB_STEP_SUMMARY
722
+ echo "|--------|-------|--------|----------------|" >> $GITHUB_STEP_SUMMARY
723
+
724
+ # Size check
725
+ SIZE_STATUS="✅ Good"
726
+ SIZE_REC="Adequate length"
727
+ if [ "$SIZE" -lt 500 ]; then
728
+ SIZE_STATUS="⚠️ Warning"
729
+ SIZE_REC="Add more content (min 500 bytes)"
730
+ elif [ "$SIZE" -gt 50000 ]; then
731
+ SIZE_STATUS="⚠️ Warning"
732
+ SIZE_REC="Consider splitting into multiple docs"
733
+ fi
734
+ echo "| Size | $SIZE bytes | $SIZE_STATUS | $SIZE_REC |" >> $GITHUB_STEP_SUMMARY
735
+
736
+ # Line count
737
+ LINES_STATUS="✅ Good"
738
+ LINES_REC="Good size"
739
+ if [ "$LINES" -lt 20 ]; then
740
+ LINES_STATUS="⚠️ Warning"
741
+ LINES_REC="Add more sections (min 20 lines)"
742
+ fi
743
+ echo "| Lines | $LINES | $LINES_STATUS | $LINES_REC |" >> $GITHUB_STEP_SUMMARY
744
+
745
+ # Word count
746
+ WORDS_STATUS="✅ Good"
747
+ WORDS_REC="Good detail"
748
+ if [ "$WORDS" -lt 100 ]; then
749
+ WORDS_STATUS="⚠️ Warning"
750
+ WORDS_REC="Add more description (min 100 words)"
751
+ fi
752
+ echo "| Words | $WORDS | $WORDS_STATUS | $WORDS_REC |" >> $GITHUB_STEP_SUMMARY
753
+
754
+ # Headings
755
+ HEADINGS_STATUS="✅ Good"
756
+ HEADINGS_REC="Well structured"
757
+ if [ "$HEADINGS" -lt 3 ]; then
758
+ HEADINGS_STATUS="⚠️ Warning"
759
+ HEADINGS_REC="Add more sections (min 3 headings)"
760
+ fi
761
+ echo "| Headings | $HEADINGS | $HEADINGS_STATUS | $HEADINGS_REC |" >> $GITHUB_STEP_SUMMARY
762
+
763
+ # Links
764
+ LINKS_STATUS="✅ Good"
765
+ LINKS_REC="Includes references"
766
+ if [ "$LINKS" -lt 1 ]; then
767
+ LINKS_STATUS="ℹ️ Info"
768
+ LINKS_REC="Consider adding useful links"
769
+ fi
770
+ echo "| Links | $LINKS | $LINKS_STATUS | $LINKS_REC |" >> $GITHUB_STEP_SUMMARY
771
+
772
+ # Code blocks
773
+ CODE_STATUS="✅ Good"
774
+ CODE_REC="Includes examples"
775
+ if [ "$CODE_BLOCKS" -eq 0 ]; then
776
+ CODE_STATUS="ℹ️ Info"
777
+ CODE_REC="Consider adding code examples"
778
+ fi
779
+ echo "| Code blocks | $CODE_BLOCKS | $CODE_STATUS | $CODE_REC |" >> $GITHUB_STEP_SUMMARY
780
+
781
+ echo "" >> $GITHUB_STEP_SUMMARY
782
+
783
+ # Check for key sections
784
+ echo "**Section Coverage:**" >> $GITHUB_STEP_SUMMARY
785
+ MISSING_COUNT=0
786
+ grep -qi "install\|setup\|getting started" README.md && echo "- ✅ Installation/Setup instructions" >> $GITHUB_STEP_SUMMARY || { echo "- ⚠️ Missing: Installation/Setup" >> $GITHUB_STEP_SUMMARY; MISSING_COUNT=$((MISSING_COUNT + 1)); }
787
+ grep -qi "usage\|example\|how to" README.md && echo "- ✅ Usage examples" >> $GITHUB_STEP_SUMMARY || { echo "- ⚠️ Missing: Usage examples" >> $GITHUB_STEP_SUMMARY; MISSING_COUNT=$((MISSING_COUNT + 1)); }
788
+ grep -qi "license" README.md && echo "- ✅ License information" >> $GITHUB_STEP_SUMMARY || { echo "- ⚠️ Missing: License information" >> $GITHUB_STEP_SUMMARY; MISSING_COUNT=$((MISSING_COUNT + 1)); }
789
+ grep -qi "contribut" README.md && echo "- ✅ Contributing guidelines" >> $GITHUB_STEP_SUMMARY || echo "- ℹ️ Optional: Contributing section" >> $GITHUB_STEP_SUMMARY
790
+
791
+ if [ "$MISSING_COUNT" -gt 0 ]; then
792
+ echo "" >> $GITHUB_STEP_SUMMARY
793
+ echo "**⚠️ $MISSING_COUNT important sections missing**" >> $GITHUB_STEP_SUMMARY
794
+ fi
795
+
796
+ - name: Validate CHANGELOG.md
797
+ run: |
798
+ set -x
799
+ echo "" >> $GITHUB_STEP_SUMMARY
800
+ echo "### CHANGELOG.md Analysis" >> $GITHUB_STEP_SUMMARY
801
+ echo "" >> $GITHUB_STEP_SUMMARY
802
+
803
+ # Locate changelog case-insensitively; accepted at root, src/, or docs/
804
+ CHANGELOG_PATH=$(find . -maxdepth 3 \( -path ./.git -o -path ./node_modules \) -prune \
805
+ -o -iname "changelog.md" -print | head -1 | sed 's|^\./||')
806
+
807
+ if [ -z "$CHANGELOG_PATH" ]; then
808
+ echo "❌ **Critical:** CHANGELOG.md not found (checked root, src/, docs/)" >> $GITHUB_STEP_SUMMARY
809
+ echo "" >> $GITHUB_STEP_SUMMARY
810
+ echo "### ❌ Validation Failed: CHANGELOG.md Missing" >> $GITHUB_STEP_SUMMARY
811
+ echo "" >> $GITHUB_STEP_SUMMARY
812
+ echo "**Error:** CHANGELOG.md is required for all MokoCLI-compliant repositories" >> $GITHUB_STEP_SUMMARY
813
+ echo "**Action Required:** Create CHANGELOG.md following [Keep a Changelog](https://keepachangelog.com/) format" >> $GITHUB_STEP_SUMMARY
814
+ echo ""
815
+ echo "❌ ERROR: CHANGELOG.md not found - This is a critical requirement"
816
+ exit 1
817
+ fi
818
+
819
+ echo "📄 Found: $CHANGELOG_PATH" >> $GITHUB_STEP_SUMMARY
820
+ echo "" >> $GITHUB_STEP_SUMMARY
821
+
822
+ # Analyze changelog structure
823
+ VERSIONS=$(grep -c "## \[" "$CHANGELOG_PATH" || echo 0)
824
+ UNRELEASED=$(grep -c "## \[Unreleased\]" "$CHANGELOG_PATH" || echo 0)
825
+ DATES=$(grep -c "[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}" "$CHANGELOG_PATH" || echo 0)
826
+ SIZE=$(wc -c < "$CHANGELOG_PATH")
827
+
828
+ echo "| Metric | Value | Status | Notes |" >> $GITHUB_STEP_SUMMARY
829
+ echo "|--------|-------|--------|-------|" >> $GITHUB_STEP_SUMMARY
830
+
831
+ # Check format
832
+ if grep -qi "## \[.*\]" "$CHANGELOG_PATH"; then
833
+ echo "| Format | Keep a Changelog | ✅ Pass | Standard format |" >> $GITHUB_STEP_SUMMARY
834
+ else
835
+ echo "| Format | Custom | ⚠️ Warning | Consider [Keep a Changelog](https://keepachangelog.com/) |" >> $GITHUB_STEP_SUMMARY
836
+ fi
837
+
838
+ # Version count
839
+ VERSIONS_STATUS="✅ Good"
840
+ VERSIONS_NOTE="Well maintained"
841
+ if [ "$VERSIONS" -lt 1 ]; then
842
+ VERSIONS_STATUS="⚠️ Warning"
843
+ VERSIONS_NOTE="Add version entries"
844
+ fi
845
+ echo "| Versions | $VERSIONS | $VERSIONS_STATUS | $VERSIONS_NOTE |" >> $GITHUB_STEP_SUMMARY
846
+
847
+ # Unreleased section
848
+ if [ "$UNRELEASED" -gt 0 ]; then
849
+ echo "| Unreleased | Yes | ✅ Good | Active development tracked |" >> $GITHUB_STEP_SUMMARY
850
+ else
851
+ echo "| Unreleased | No | ℹ️ Info | Consider adding [Unreleased] section |" >> $GITHUB_STEP_SUMMARY
852
+ fi
853
+
854
+ # Dates
855
+ DATES_STATUS="✅ Good"
856
+ if [ "$DATES" -lt 1 ]; then
857
+ DATES_STATUS="⚠️ Warning"
858
+ DATES_NOTE="Add release dates"
859
+ else
860
+ DATES_NOTE="Dates present"
861
+ fi
862
+ echo "| Release dates | $DATES | $DATES_STATUS | $DATES_NOTE |" >> $GITHUB_STEP_SUMMARY
863
+
864
+ # Check for standard sections
865
+ echo "" >> $GITHUB_STEP_SUMMARY
866
+ echo "**Changelog Sections:**" >> $GITHUB_STEP_SUMMARY
867
+ grep -qi "### Added" "$CHANGELOG_PATH" && echo "- ✅ Added section" >> $GITHUB_STEP_SUMMARY || echo "- ℹ️ Added section (optional)" >> $GITHUB_STEP_SUMMARY
868
+ grep -qi "### Changed" "$CHANGELOG_PATH" && echo "- ✅ Changed section" >> $GITHUB_STEP_SUMMARY || echo "- ℹ️ Changed section (optional)" >> $GITHUB_STEP_SUMMARY
869
+ grep -qi "### Fixed" "$CHANGELOG_PATH" && echo "- ✅ Fixed section" >> $GITHUB_STEP_SUMMARY || echo "- ℹ️ Fixed section (optional)" >> $GITHUB_STEP_SUMMARY
870
+
871
+ echo "" >> $GITHUB_STEP_SUMMARY
872
+ echo "📚 Reference: [Keep a Changelog](https://keepachangelog.com/)" >> $GITHUB_STEP_SUMMARY
873
+
874
+ - name: Check Documentation Index
875
+ run: |
876
+ set -x
877
+ echo "" >> $GITHUB_STEP_SUMMARY
878
+ echo "### Documentation Index" >> $GITHUB_STEP_SUMMARY
879
+
880
+ if [ -f "docs/index.md" ] || [ -f "docs/README.md" ]; then
881
+ echo "✅ Documentation index found" >> $GITHUB_STEP_SUMMARY
882
+ else
883
+ echo "⚠️ No documentation index (docs/index.md or docs/README.md)" >> $GITHUB_STEP_SUMMARY
884
+ fi
885
+
886
+ readme-completeness:
887
+ name: README Completeness Check
888
+ runs-on: ubuntu-latest
889
+
890
+ steps:
891
+ - name: Checkout Repository
892
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
893
+
894
+ - name: Check README Sections
895
+ run: |
896
+ set -x
897
+ echo "## 📄 README Completeness Check" >> $GITHUB_STEP_SUMMARY
898
+ echo "" >> $GITHUB_STEP_SUMMARY
899
+
900
+ if [ ! -f "README.md" ]; then
901
+ echo "❌ README.md not found" >> $GITHUB_STEP_SUMMARY
902
+ exit 1
903
+ fi
904
+
905
+ # Required sections
906
+ REQUIRED_SECTIONS=("Installation" "Usage" "Contributing" "License")
907
+ MISSING=0
908
+ PRESENT=0
909
+
910
+ echo "### Required Sections" >> $GITHUB_STEP_SUMMARY
911
+ echo "" >> $GITHUB_STEP_SUMMARY
912
+
913
+ for section in "${REQUIRED_SECTIONS[@]}"; do
914
+ if grep -qi "##.*$section" README.md; then
915
+ echo "✅ $section" >> $GITHUB_STEP_SUMMARY
916
+ PRESENT=$((PRESENT + 1))
917
+ else
918
+ echo "❌ $section" >> $GITHUB_STEP_SUMMARY
919
+ MISSING=$((MISSING + 1))
920
+ fi
921
+ done
922
+
923
+ echo "" >> $GITHUB_STEP_SUMMARY
924
+ echo "**Completeness**: $PRESENT/${#REQUIRED_SECTIONS[@]} required sections present" >> $GITHUB_STEP_SUMMARY
925
+
926
+ if [ "$MISSING" -gt 0 ]; then
927
+ echo "" >> $GITHUB_STEP_SUMMARY
928
+ echo "**Action Required**: Add missing sections to README.md" >> $GITHUB_STEP_SUMMARY
929
+ exit 1
930
+ fi
931
+
932
+ # ============================================================================
933
+ # PHASE 3: Future Enhancements
934
+ # ============================================================================
935
+
936
+ git-hygiene:
937
+ name: Git Repository Hygiene
938
+ runs-on: ubuntu-latest
939
+
940
+ steps:
941
+ - name: Checkout Repository
942
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
943
+ with:
944
+ fetch-depth: 0
945
+
946
+ - name: Check .gitignore
947
+ run: |
948
+ set -x
949
+ echo "### .gitignore Validation" >> $GITHUB_STEP_SUMMARY
950
+
951
+ if [ ! -f ".gitignore" ]; then
952
+ echo "⚠️ .gitignore file not found" >> $GITHUB_STEP_SUMMARY
953
+ echo "" >> $GITHUB_STEP_SUMMARY
954
+ echo "### ⚠️ Warning: .gitignore Not Found" >> $GITHUB_STEP_SUMMARY
955
+ echo "" >> $GITHUB_STEP_SUMMARY
956
+ echo "**Status:** .gitignore file is recommended but not required" >> $GITHUB_STEP_SUMMARY
957
+ echo "**Recommendation:** Add .gitignore to exclude build artifacts, dependencies, and temporary files" >> $GITHUB_STEP_SUMMARY
958
+ echo ""
959
+ echo "⚠️ WARNING: .gitignore file not found - Continuing validation"
960
+ exit 0
961
+ fi
962
+
963
+ # Check for common exclusions
964
+ MISSING=""
965
+ grep -q "vendor/" .gitignore || MISSING="${MISSING}vendor/ "
966
+ grep -q "node_modules/" .gitignore || MISSING="${MISSING}node_modules/ "
967
+
968
+ if [ -n "$MISSING" ]; then
969
+ echo "⚠️ .gitignore may be missing common exclusions: $MISSING" >> $GITHUB_STEP_SUMMARY
970
+ else
971
+ echo "✅ .gitignore appears complete" >> $GITHUB_STEP_SUMMARY
972
+ fi
973
+
974
+ - name: Check for Large Files
975
+ run: |
976
+ set -x
977
+ echo "" >> $GITHUB_STEP_SUMMARY
978
+ echo "### Large File Detection" >> $GITHUB_STEP_SUMMARY
979
+
980
+ # Find files larger than 1MB
981
+ LARGE_FILES=$(find . -type f -size +1M ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" | head -5)
982
+
983
+ if [ -n "$LARGE_FILES" ]; then
984
+ echo "⚠️ Large files detected (>1MB):" >> $GITHUB_STEP_SUMMARY
985
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
986
+ echo "$LARGE_FILES" >> $GITHUB_STEP_SUMMARY
987
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
988
+ echo "Consider using Git LFS for large binary files" >> $GITHUB_STEP_SUMMARY
989
+ else
990
+ echo "✅ No unusually large files detected" >> $GITHUB_STEP_SUMMARY
991
+ fi
992
+
993
+ script-integrity:
994
+ name: Script Integrity Validation
995
+ runs-on: ubuntu-latest
996
+
997
+ steps:
998
+ - name: Checkout Repository
999
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1000
+
1001
+ - name: Set up Python
1002
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
1003
+ with:
1004
+ python-version: '3.x'
1005
+
1006
+ - name: Validate Script Integrity
1007
+ id: script_check
1008
+ run: |
1009
+ set -x
1010
+ echo "## 🔐 Script Integrity Validation" >> $GITHUB_STEP_SUMMARY
1011
+ echo "" >> $GITHUB_STEP_SUMMARY
1012
+
1013
+ if [ -f "api/.script-registry.json" ]; then
1014
+ echo "### Critical Scripts" >> $GITHUB_STEP_SUMMARY
1015
+ php api/maintenance/update_sha_hashes.php \
1016
+ --dry-run --verbose | tee /tmp/script-validation.log
1017
+
1018
+ EXIT_CODE=$?
1019
+
1020
+ echo "" >> $GITHUB_STEP_SUMMARY
1021
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1022
+ cat /tmp/script-validation.log >> $GITHUB_STEP_SUMMARY
1023
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1024
+
1025
+ if [ "$EXIT_CODE" -eq 0 ]; then
1026
+ echo "" >> $GITHUB_STEP_SUMMARY
1027
+ echo "✅ All critical scripts validated successfully!" >> $GITHUB_STEP_SUMMARY
1028
+ exit 0
1029
+ else
1030
+ echo "" >> $GITHUB_STEP_SUMMARY
1031
+ echo "❌ Script integrity violations detected" >> $GITHUB_STEP_SUMMARY
1032
+ echo "**Action Required:** Review validation report and update registry" >> $GITHUB_STEP_SUMMARY
1033
+ exit 1
1034
+ fi
1035
+ else
1036
+ echo "ℹ️ Script registry not found - skipping integrity check" >> $GITHUB_STEP_SUMMARY
1037
+ exit 0
1038
+ fi
1039
+
1040
+
1041
+ # ════════════════════════════════════════════════════════════════════════
1042
+ # TIER 3 — QUALITY (code quality metrics)
1043
+ # ════════════════════════════════════════════════════════════════════════
1044
+ line-length-validation:
1045
+ name: Line Length Check
1046
+ runs-on: ubuntu-latest
1047
+
1048
+ steps:
1049
+ - name: Checkout Repository
1050
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1051
+
1052
+ - name: Check Line Lengths
1053
+ run: |
1054
+ set -x
1055
+ echo "## 📏 Line Length Validation" >> $GITHUB_STEP_SUMMARY
1056
+ echo "" >> $GITHUB_STEP_SUMMARY
1057
+
1058
+ # Line length standards:
1059
+ # - General source code: 120 characters (hard limit)
1060
+ # - YAML workflows: 180 characters (exception for GitHub Actions)
1061
+ # - Markdown files: No limit (content-focused)
1062
+
1063
+ echo "### Line Length Standards" >> $GITHUB_STEP_SUMMARY
1064
+ echo "" >> $GITHUB_STEP_SUMMARY
1065
+ echo "| File Type | Soft Limit | Hard Limit |" >> $GITHUB_STEP_SUMMARY
1066
+ echo "|-----------|------------|------------|" >> $GITHUB_STEP_SUMMARY
1067
+ echo "| General source code | 80 chars | 120 chars |" >> $GITHUB_STEP_SUMMARY
1068
+ echo "| YAML workflows | 80 chars | 180 chars |" >> $GITHUB_STEP_SUMMARY
1069
+ echo "| Markdown files | N/A | No limit |" >> $GITHUB_STEP_SUMMARY
1070
+ echo "" >> $GITHUB_STEP_SUMMARY
1071
+
1072
+ # Check YAML files (using yamllint which is already configured)
1073
+ echo "### YAML Files (180 char limit)" >> $GITHUB_STEP_SUMMARY
1074
+
1075
+ YAML_VIOLATIONS=0
1076
+ if command -v yamllint >/dev/null 2>&1; then
1077
+ # Install yamllint if not present
1078
+ :
1079
+ else
1080
+ pip install yamllint >/dev/null 2>&1 || true
1081
+ fi
1082
+
1083
+ # Run yamllint and count line-length warnings
1084
+ YAML_OUTPUT=$(yamllint .mokogit/workflows/*.yml 2>&1 | grep "line too long" || true)
1085
+ if [ -n "$YAML_OUTPUT" ]; then
1086
+ YAML_VIOLATIONS=$(echo "$YAML_OUTPUT" | wc -l)
1087
+ echo "⚠️ Found $YAML_VIOLATIONS lines exceeding 180 characters in YAML files" >> $GITHUB_STEP_SUMMARY
1088
+ echo "<details><summary>View warnings (informational only)</summary>" >> $GITHUB_STEP_SUMMARY
1089
+ echo "" >> $GITHUB_STEP_SUMMARY
1090
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1091
+ echo "$YAML_OUTPUT" | head -20 >> $GITHUB_STEP_SUMMARY
1092
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1093
+ echo "</details>" >> $GITHUB_STEP_SUMMARY
1094
+ else
1095
+ echo "✅ All YAML files comply with 180 character limit" >> $GITHUB_STEP_SUMMARY
1096
+ fi
1097
+ echo "" >> $GITHUB_STEP_SUMMARY
1098
+
1099
+ # Check source code files (PHP, Python, JavaScript, etc.) for 120 char limit
1100
+ echo "### Source Code Files (120 char limit)" >> $GITHUB_STEP_SUMMARY
1101
+
1102
+ LONG_LINES=$(find . -type f \
1103
+ \( -name "*.php" -o -name "*.py" -o -name "*.js" -o -name "*.ts" \
1104
+ -o -name "*.go" -o -name "*.rs" -o -name "*.java" -o -name "*.c" \
1105
+ -o -name "*.cpp" -o -name "*.h" -o -name "*.sh" \) \
1106
+ ! -path "./vendor/*" \
1107
+ ! -path "./node_modules/*" \
1108
+ ! -path "./.git/*" \
1109
+ ! -path "./build/*" \
1110
+ ! -path "./dist/*" \
1111
+ -exec awk 'length > 120 { print FILENAME ":" NR ": " length " chars" }' {} \; 2>/dev/null | head -20 || true)
1112
+
1113
+ if [ -n "$LONG_LINES" ]; then
1114
+ LINE_COUNT=$(echo "$LONG_LINES" | wc -l)
1115
+ echo "⚠️ Found $LINE_COUNT source code lines exceeding 120 characters" >> $GITHUB_STEP_SUMMARY
1116
+ echo "<details><summary>View violations (informational)</summary>" >> $GITHUB_STEP_SUMMARY
1117
+ echo "" >> $GITHUB_STEP_SUMMARY
1118
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1119
+ echo "$LONG_LINES" >> $GITHUB_STEP_SUMMARY
1120
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1121
+ echo "</details>" >> $GITHUB_STEP_SUMMARY
1122
+ else
1123
+ echo "✅ All source code files comply with 120 character limit" >> $GITHUB_STEP_SUMMARY
1124
+ fi
1125
+ echo "" >> $GITHUB_STEP_SUMMARY
1126
+
1127
+ # Confirm Markdown files are not checked
1128
+ echo "### Markdown Files" >> $GITHUB_STEP_SUMMARY
1129
+ echo "✅ Markdown files have no line length limit per coding standards" >> $GITHUB_STEP_SUMMARY
1130
+ echo "Rationale: Content-focused format, URLs, tables, and natural prose flow" >> $GITHUB_STEP_SUMMARY
1131
+ echo "" >> $GITHUB_STEP_SUMMARY
1132
+
1133
+ # Summary
1134
+ echo "### Summary" >> $GITHUB_STEP_SUMMARY
1135
+ echo "This check is **informational only** and does not block merges." >> $GITHUB_STEP_SUMMARY
1136
+ echo "Line length standards help maintain code readability." >> $GITHUB_STEP_SUMMARY
1137
+ echo "Exceptions documented in: \`docs/policy/coding-style-guide.md\`" >> $GITHUB_STEP_SUMMARY
1138
+
1139
+ file-naming-standards:
1140
+ name: File Naming Standards
1141
+ runs-on: ubuntu-latest
1142
+
1143
+ steps:
1144
+ - name: Checkout Repository
1145
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1146
+
1147
+ - name: Check File Naming
1148
+ run: |
1149
+ set -x
1150
+ echo "## 📝 File Naming Standards" >> $GITHUB_STEP_SUMMARY
1151
+ echo "" >> $GITHUB_STEP_SUMMARY
1152
+
1153
+ VIOLATIONS=0
1154
+
1155
+ # Check PHP files (should be PascalCase for classes)
1156
+ INVALID_PHP=$(find . -name "*.php" ! -path "./vendor/*" ! -path "./.git/*" ! -regex ".*/[A-Z][a-zA-Z0-9]*\.php" ! -name "index.php" ! -name "functions.php" | wc -l || echo 0)
1157
+
1158
+ # Check config files (should be kebab-case)
1159
+ INVALID_CONFIG=$(find . -name "*.yml" -o -name "*.yaml" -o -name "*.json" ! -path "./vendor/*" ! -path "./.git/*" ! -path "./node_modules/*" | grep -E "[A-Z_]" | wc -l || echo 0)
1160
+
1161
+ echo "### Naming Violations" >> $GITHUB_STEP_SUMMARY
1162
+ echo "- **PHP files not PascalCase**: $INVALID_PHP" >> $GITHUB_STEP_SUMMARY
1163
+ echo "- **Config files not kebab-case**: $INVALID_CONFIG" >> $GITHUB_STEP_SUMMARY
1164
+ echo "" >> $GITHUB_STEP_SUMMARY
1165
+
1166
+ VIOLATIONS=$((INVALID_PHP + INVALID_CONFIG))
1167
+
1168
+ if [ "$VIOLATIONS" -gt 0 ]; then
1169
+ echo "⚠️ Found $VIOLATIONS naming convention violation(s)" >> $GITHUB_STEP_SUMMARY
1170
+ echo "**Recommendation**: Follow naming conventions for consistency" >> $GITHUB_STEP_SUMMARY
1171
+ else
1172
+ echo "✅ File naming conventions followed" >> $GITHUB_STEP_SUMMARY
1173
+ fi
1174
+
1175
+ insecure-patterns:
1176
+ name: Insecure Code Pattern Detection
1177
+ runs-on: ubuntu-latest
1178
+
1179
+ steps:
1180
+ - name: Checkout Repository
1181
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1182
+
1183
+ - name: Scan for Insecure Patterns
1184
+ run: |
1185
+ set -x
1186
+ echo "## 🔒 Insecure Code Pattern Detection" >> $GITHUB_STEP_SUMMARY
1187
+ echo "" >> $GITHUB_STEP_SUMMARY
1188
+
1189
+ VIOLATIONS=0
1190
+
1191
+ # PHP: SQL injection patterns
1192
+ if grep -r -n "\\$_\(GET\|POST\|REQUEST\).*mysql_query\|mysqli_query" . --include="*.php" ! -path "./vendor/*" 2>/dev/null > /tmp/sql_inject.txt; then
1193
+ COUNT=$(wc -l < /tmp/sql_inject.txt)
1194
+ echo "⚠️ Found $COUNT potential SQL injection pattern(s)" >> $GITHUB_STEP_SUMMARY
1195
+ VIOLATIONS=$((VIOLATIONS + COUNT))
1196
+ fi
1197
+
1198
+ # PHP: eval/exec usage
1199
+ if grep -r -n "eval\|exec\|system\|passthru\|shell_exec" . --include="*.php" ! -path "./vendor/*" 2>/dev/null > /tmp/exec.txt; then
1200
+ COUNT=$(wc -l < /tmp/exec.txt)
1201
+ echo "⚠️ Found $COUNT dangerous function call(s)" >> $GITHUB_STEP_SUMMARY
1202
+ VIOLATIONS=$((VIOLATIONS + COUNT))
1203
+ fi
1204
+
1205
+ # Python: eval usage
1206
+ if grep -r -n "eval(" . --include="*.py" 2>/dev/null > /tmp/py_eval.txt; then
1207
+ COUNT=$(wc -l < /tmp/py_eval.txt)
1208
+ echo "⚠️ Found $COUNT Python eval() usage(s)" >> $GITHUB_STEP_SUMMARY
1209
+ VIOLATIONS=$((VIOLATIONS + COUNT))
1210
+ fi
1211
+
1212
+ echo "" >> $GITHUB_STEP_SUMMARY
1213
+
1214
+ if [ "$VIOLATIONS" -gt 0 ]; then
1215
+ echo "**Total Violations**: $VIOLATIONS" >> $GITHUB_STEP_SUMMARY
1216
+ echo "**Recommendation**: Review and secure flagged patterns" >> $GITHUB_STEP_SUMMARY
1217
+ else
1218
+ echo "✅ No insecure patterns detected" >> $GITHUB_STEP_SUMMARY
1219
+ fi
1220
+
1221
+ code-complexity:
1222
+ name: Code Complexity Analysis
1223
+ runs-on: ubuntu-latest
1224
+
1225
+ steps:
1226
+ - name: Checkout Repository
1227
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1228
+
1229
+ - name: Setup PHP
1230
+ uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.31.0
1231
+ with:
1232
+ php-version: '8.1'
1233
+
1234
+ - name: Analyze Complexity
1235
+ run: |
1236
+ set -x
1237
+ echo "## 📊 Code Complexity Analysis" >> $GITHUB_STEP_SUMMARY
1238
+ echo "" >> $GITHUB_STEP_SUMMARY
1239
+
1240
+ PHP_COUNT=$(find . -name "*.php" ! -path "./vendor/*" ! -path "./.git/*" | wc -l)
1241
+
1242
+ if [ "$PHP_COUNT" -gt 0 ]; then
1243
+ # Install phploc
1244
+ wget https://phar.phpunit.de/phploc.phar 2>/dev/null
1245
+ chmod +x phploc.phar
1246
+
1247
+ echo "### PHP Code Metrics" >> $GITHUB_STEP_SUMMARY
1248
+ if ./phploc.phar --exclude vendor --exclude .git . 2>&1 | tee /tmp/phploc.txt; then
1249
+ COMPLEXITY=$(grep "Cyclomatic Complexity" /tmp/phploc.txt | grep "Average" | awk '{print $NF}' || echo "N/A")
1250
+ echo "**Average Cyclomatic Complexity**: $COMPLEXITY" >> $GITHUB_STEP_SUMMARY
1251
+ echo "" >> $GITHUB_STEP_SUMMARY
1252
+
1253
+ if [ "$COMPLEXITY" != "N/A" ] && [ $(echo "$COMPLEXITY > 10" | bc -l) -eq 1 ]; then
1254
+ echo "⚠️ Average complexity exceeds recommended threshold (10)" >> $GITHUB_STEP_SUMMARY
1255
+ echo "**Recommendation**: Refactor complex functions" >> $GITHUB_STEP_SUMMARY
1256
+ else
1257
+ echo "✅ Code complexity within acceptable limits" >> $GITHUB_STEP_SUMMARY
1258
+ fi
1259
+ fi
1260
+ else
1261
+ echo "ℹ️ No PHP files found for complexity analysis" >> $GITHUB_STEP_SUMMARY
1262
+ fi
1263
+
1264
+ code-duplication:
1265
+ name: Code Duplication Detection
1266
+ runs-on: ubuntu-latest
1267
+
1268
+ steps:
1269
+ - name: Checkout Repository
1270
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1271
+
1272
+ - name: Setup PHP
1273
+ uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.31.0
1274
+ with:
1275
+ php-version: '8.1'
1276
+
1277
+ - name: Detect Duplicates
1278
+ run: |
1279
+ set -x
1280
+ echo "## 🔁 Code Duplication Detection" >> $GITHUB_STEP_SUMMARY
1281
+ echo "" >> $GITHUB_STEP_SUMMARY
1282
+
1283
+ # Check if PHP files exist
1284
+ PHP_COUNT=$(find . -name "*.php" ! -path "./vendor/*" ! -path "./.git/*" | wc -l)
1285
+
1286
+ if [ "$PHP_COUNT" -gt 0 ]; then
1287
+ echo "### PHP Code Duplication" >> $GITHUB_STEP_SUMMARY
1288
+
1289
+ # Install phpcpd
1290
+ wget https://phar.phpunit.de/phpcpd.phar 2>/dev/null
1291
+ chmod +x phpcpd.phar
1292
+
1293
+ # Run duplication detection
1294
+ if ./phpcpd.phar --exclude vendor --exclude .git . 2>&1 | tee /tmp/phpcpd.txt; then
1295
+ DUPLICATION=$(grep "Found" /tmp/phpcpd.txt | grep -oE "[0-9]+\.[0-9]+%" | head -1 || echo "0.00%")
1296
+ echo "📊 **Duplication Rate**: $DUPLICATION" >> $GITHUB_STEP_SUMMARY
1297
+ echo "" >> $GITHUB_STEP_SUMMARY
1298
+
1299
+ DUPLICATION_NUM=$(echo "$DUPLICATION" | sed 's/%//')
1300
+ if [ $(echo "$DUPLICATION_NUM > 5.0" | bc -l) -eq 1 ]; then
1301
+ echo "⚠️ Code duplication exceeds 5% threshold" >> $GITHUB_STEP_SUMMARY
1302
+ echo "" >> $GITHUB_STEP_SUMMARY
1303
+ echo "<details>" >> $GITHUB_STEP_SUMMARY
1304
+ echo "<summary>View duplication details</summary>" >> $GITHUB_STEP_SUMMARY
1305
+ echo "" >> $GITHUB_STEP_SUMMARY
1306
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1307
+ cat /tmp/phpcpd.txt >> $GITHUB_STEP_SUMMARY
1308
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1309
+ echo "</details>" >> $GITHUB_STEP_SUMMARY
1310
+ else
1311
+ echo "✅ Code duplication within acceptable limits (<5%)" >> $GITHUB_STEP_SUMMARY
1312
+ fi
1313
+ else
1314
+ echo "✅ No significant code duplication detected" >> $GITHUB_STEP_SUMMARY
1315
+ fi
1316
+ else
1317
+ echo "ℹ️ No PHP files found for duplication analysis" >> $GITHUB_STEP_SUMMARY
1318
+ fi
1319
+
1320
+ echo "" >> $GITHUB_STEP_SUMMARY
1321
+ echo "**Note**: This is an informational check to encourage DRY principles." >> $GITHUB_STEP_SUMMARY
1322
+
1323
+ dead-code-detection:
1324
+ name: Dead Code Detection
1325
+ runs-on: ubuntu-latest
1326
+
1327
+ steps:
1328
+ - name: Checkout Repository
1329
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1330
+
1331
+ - name: Setup Python
1332
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
1333
+ with:
1334
+ python-version: '3.x'
1335
+
1336
+ - name: Detect Dead Code
1337
+ run: |
1338
+ set -x
1339
+ echo "## 🗑️ Dead Code Detection" >> $GITHUB_STEP_SUMMARY
1340
+ echo "" >> $GITHUB_STEP_SUMMARY
1341
+
1342
+ PY_COUNT=$(find . -name "*.py" ! -path "./vendor/*" ! -path "./.git/*" ! -path "./venv/*" | wc -l)
1343
+
1344
+ if [ "$PY_COUNT" -gt 0 ]; then
1345
+ pip install vulture 2>/dev/null
1346
+ echo "### Python Dead Code" >> $GITHUB_STEP_SUMMARY
1347
+
1348
+ if vulture . --exclude vendor,venv,.git 2>&1 | tee /tmp/vulture.txt; then
1349
+ DEAD_COUNT=$(wc -l < /tmp/vulture.txt || echo 0)
1350
+ if [ "$DEAD_COUNT" -gt 0 ]; then
1351
+ echo "⚠️ Found $DEAD_COUNT potential dead code item(s)" >> $GITHUB_STEP_SUMMARY
1352
+ echo "" >> $GITHUB_STEP_SUMMARY
1353
+ echo "<details>" >> $GITHUB_STEP_SUMMARY
1354
+ echo "<summary>View dead code</summary>" >> $GITHUB_STEP_SUMMARY
1355
+ echo "" >> $GITHUB_STEP_SUMMARY
1356
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1357
+ head -50 /tmp/vulture.txt >> $GITHUB_STEP_SUMMARY
1358
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1359
+ echo "</details>" >> $GITHUB_STEP_SUMMARY
1360
+ else
1361
+ echo "✅ No dead code detected" >> $GITHUB_STEP_SUMMARY
1362
+ fi
1363
+ fi
1364
+ else
1365
+ echo "ℹ️ No Python files found for dead code analysis" >> $GITHUB_STEP_SUMMARY
1366
+ fi
1367
+
1368
+
1369
+ # ════════════════════════════════════════════════════════════════════════
1370
+ # TIER 4 — SUPPLEMENTARY (informational)
1371
+ # ════════════════════════════════════════════════════════════════════════
1372
+ file-size-limits:
1373
+ name: File Size Limits
1374
+ runs-on: ubuntu-latest
1375
+
1376
+ steps:
1377
+ - name: Checkout Repository
1378
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1379
+
1380
+ - name: Check File Sizes
1381
+ run: |
1382
+ set -x
1383
+ echo "## 📦 File Size Validation" >> $GITHUB_STEP_SUMMARY
1384
+ echo "" >> $GITHUB_STEP_SUMMARY
1385
+
1386
+ # Exempt file types (allowed to be large)
1387
+ EXEMPT="! -name *.mmdb ! -name *.woff2 ! -name *.woff ! -name *.ttf ! -name *.otf"
1388
+
1389
+ # Find large files (>15MB warning, >20MB critical)
1390
+ LARGE_FILES=$(find . -type f -size +15M $EXEMPT ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" 2>/dev/null | wc -l)
1391
+ HUGE_FILES=$(find . -type f -size +20M $EXEMPT ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" 2>/dev/null | wc -l)
1392
+
1393
+ echo "### Size Thresholds" >> $GITHUB_STEP_SUMMARY
1394
+ echo "- **Warning**: Files >15MB" >> $GITHUB_STEP_SUMMARY
1395
+ echo "- **Critical**: Files >20MB" >> $GITHUB_STEP_SUMMARY
1396
+ echo "- **Exempt**: .mmdb, .woff2, .woff, .ttf, .otf" >> $GITHUB_STEP_SUMMARY
1397
+ echo "" >> $GITHUB_STEP_SUMMARY
1398
+
1399
+ if [ "$HUGE_FILES" -gt 0 ]; then
1400
+ echo "❌ **Critical**: Found $HUGE_FILES file(s) exceeding 20MB" >> $GITHUB_STEP_SUMMARY
1401
+ echo "" >> $GITHUB_STEP_SUMMARY
1402
+ echo "<details>" >> $GITHUB_STEP_SUMMARY
1403
+ echo "<summary>View files >20MB</summary>" >> $GITHUB_STEP_SUMMARY
1404
+ echo "" >> $GITHUB_STEP_SUMMARY
1405
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1406
+ find . -type f -size +20M $EXEMPT ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" -exec ls -lh {} + 2>/dev/null | awk '{print $5, $9}' >> $GITHUB_STEP_SUMMARY
1407
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1408
+ echo "</details>" >> $GITHUB_STEP_SUMMARY
1409
+ echo "" >> $GITHUB_STEP_SUMMARY
1410
+ echo "**Action Required**: Remove or optimize files >20MB" >> $GITHUB_STEP_SUMMARY
1411
+ exit 1
1412
+ elif [ "$LARGE_FILES" -gt 0 ]; then
1413
+ echo "⚠️ **Warning**: Found $LARGE_FILES file(s) between 15MB and 20MB" >> $GITHUB_STEP_SUMMARY
1414
+ echo "" >> $GITHUB_STEP_SUMMARY
1415
+ echo "<details>" >> $GITHUB_STEP_SUMMARY
1416
+ echo "<summary>View files >15MB</summary>" >> $GITHUB_STEP_SUMMARY
1417
+ echo "" >> $GITHUB_STEP_SUMMARY
1418
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1419
+ find . -type f -size +15M $EXEMPT ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" -exec ls -lh {} + 2>/dev/null | awk '{print $5, $9}' >> $GITHUB_STEP_SUMMARY
1420
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1421
+ echo "</details>" >> $GITHUB_STEP_SUMMARY
1422
+ echo "" >> $GITHUB_STEP_SUMMARY
1423
+ echo "**Recommendation**: Consider optimizing large files" >> $GITHUB_STEP_SUMMARY
1424
+ else
1425
+ echo "✅ All files within acceptable size limits" >> $GITHUB_STEP_SUMMARY
1426
+ fi
1427
+
1428
+ binary-file-detection:
1429
+ name: Binary File Detection
1430
+ runs-on: ubuntu-latest
1431
+
1432
+ steps:
1433
+ - name: Checkout Repository
1434
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1435
+
1436
+ - name: Detect Binary Files
1437
+ run: |
1438
+ set -x
1439
+ echo "## 🔍 Binary File Detection" >> $GITHUB_STEP_SUMMARY
1440
+ echo "" >> $GITHUB_STEP_SUMMARY
1441
+
1442
+ # Find binary files excluding allowed types
1443
+ BINARIES=$(find . -type f ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" \
1444
+ ! -name "*.png" ! -name "*.jpg" ! -name "*.jpeg" ! -name "*.gif" ! -name "*.svg" ! -name "*.ico" \
1445
+ ! -name "*.woff" ! -name "*.woff2" ! -name "*.ttf" ! -name "*.eot" \
1446
+ -exec file {} \; | grep -v "text" | grep -v "empty" | wc -l || echo 0)
1447
+
1448
+ if [ "$BINARIES" -gt 0 ]; then
1449
+ echo "⚠️ Found $BINARIES non-image binary file(s)" >> $GITHUB_STEP_SUMMARY
1450
+ echo "" >> $GITHUB_STEP_SUMMARY
1451
+ echo "<details>" >> $GITHUB_STEP_SUMMARY
1452
+ echo "<summary>View binary files</summary>" >> $GITHUB_STEP_SUMMARY
1453
+ echo "" >> $GITHUB_STEP_SUMMARY
1454
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1455
+ find . -type f ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" \
1456
+ ! -name "*.png" ! -name "*.jpg" ! -name "*.jpeg" ! -name "*.gif" ! -name "*.svg" ! -name "*.ico" \
1457
+ ! -name "*.woff" ! -name "*.woff2" ! -name "*.ttf" ! -name "*.eot" \
1458
+ -exec file {} \; | grep -v "text" | grep -v "empty" | cut -d: -f1 >> $GITHUB_STEP_SUMMARY
1459
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1460
+ echo "</details>" >> $GITHUB_STEP_SUMMARY
1461
+ echo "" >> $GITHUB_STEP_SUMMARY
1462
+ echo "**Recommendation**: Source control should primarily contain text files" >> $GITHUB_STEP_SUMMARY
1463
+ else
1464
+ echo "✅ No unexpected binary files detected" >> $GITHUB_STEP_SUMMARY
1465
+ fi
1466
+
1467
+ # ============================================================================
1468
+ # PHASE 4: Nice to Have Checks
1469
+ # ============================================================================
1470
+
1471
+ todo-fixme-tracking:
1472
+ name: TODO/FIXME Tracking
1473
+ runs-on: ubuntu-latest
1474
+
1475
+ steps:
1476
+ - name: Checkout Repository
1477
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1478
+
1479
+ - name: Track Technical Debt
1480
+ run: |
1481
+ set -x
1482
+ echo "## 📝 TODO/FIXME Tracking" >> $GITHUB_STEP_SUMMARY
1483
+ echo "" >> $GITHUB_STEP_SUMMARY
1484
+ echo "Tracking technical debt markers in source code." >> $GITHUB_STEP_SUMMARY
1485
+ echo "" >> $GITHUB_STEP_SUMMARY
1486
+
1487
+ # Search for technical debt markers
1488
+ PATTERNS="TODO|FIXME|HACK|XXX"
1489
+ EXTENSIONS="*.php *.py *.js *.ts *.go *.rs *.java *.c *.cpp *.h *.hpp *.sh"
1490
+
1491
+ echo "### Technical Debt Summary" >> $GITHUB_STEP_SUMMARY
1492
+ echo "" >> $GITHUB_STEP_SUMMARY
1493
+
1494
+ TOTAL_COUNT=0
1495
+ for ext in $EXTENSIONS; do
1496
+ COUNT=$(find . -type f -name "$ext" ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" -exec grep -n -E "($PATTERNS)" {} + 2>/dev/null | wc -l || echo 0)
1497
+ TOTAL_COUNT=$((TOTAL_COUNT + COUNT))
1498
+ done
1499
+
1500
+ if [ "$TOTAL_COUNT" -gt 0 ]; then
1501
+ echo "⚠️ Found **$TOTAL_COUNT** technical debt item(s)" >> $GITHUB_STEP_SUMMARY
1502
+ echo "" >> $GITHUB_STEP_SUMMARY
1503
+ echo "<details>" >> $GITHUB_STEP_SUMMARY
1504
+ echo "<summary>View technical debt items</summary>" >> $GITHUB_STEP_SUMMARY
1505
+ echo "" >> $GITHUB_STEP_SUMMARY
1506
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1507
+ for ext in $EXTENSIONS; do
1508
+ find . -type f -name "$ext" ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" -exec grep -n -H -E "($PATTERNS)" {} + 2>/dev/null | head -100 || true
1509
+ done >> $GITHUB_STEP_SUMMARY
1510
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1511
+ echo "" >> $GITHUB_STEP_SUMMARY
1512
+ echo "</details>" >> $GITHUB_STEP_SUMMARY
1513
+ else
1514
+ echo "✅ No technical debt markers found" >> $GITHUB_STEP_SUMMARY
1515
+ fi
1516
+
1517
+ echo "" >> $GITHUB_STEP_SUMMARY
1518
+ echo "**Note**: This is an informational check. Technical debt items don't block compliance." >> $GITHUB_STEP_SUMMARY
1519
+
1520
+ dependency-vulnerabilities:
1521
+ name: Dependency Vulnerability Scanning
1522
+ runs-on: ubuntu-latest
1523
+
1524
+ steps:
1525
+ - name: Checkout Repository
1526
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1527
+
1528
+ - name: Setup PHP
1529
+ uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.31.0
1530
+ with:
1531
+ php-version: '8.1'
1532
+
1533
+ - name: Setup Python
1534
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
1535
+ with:
1536
+ python-version: '3.x'
1537
+
1538
+ - name: Scan Dependencies
1539
+ run: |
1540
+ set -x
1541
+ echo "## 🛡️ Dependency Vulnerability Scanning" >> $GITHUB_STEP_SUMMARY
1542
+ echo "" >> $GITHUB_STEP_SUMMARY
1543
+
1544
+ VULNERABILITIES=0
1545
+
1546
+ # PHP Dependencies
1547
+ if [ -f "composer.json" ]; then
1548
+ echo "### PHP Dependencies (composer)" >> $GITHUB_STEP_SUMMARY
1549
+ if composer audit --no-dev 2>&1 | tee /tmp/php_audit.txt; then
1550
+ echo "✅ No PHP vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
1551
+ else
1552
+ VULN_COUNT=$(grep -c "vulnerability" /tmp/php_audit.txt || echo 0)
1553
+ echo "⚠️ Found $VULN_COUNT PHP vulnerability/vulnerabilities" >> $GITHUB_STEP_SUMMARY
1554
+ VULNERABILITIES=$((VULNERABILITIES + VULN_COUNT))
1555
+ fi
1556
+ echo "" >> $GITHUB_STEP_SUMMARY
1557
+ fi
1558
+
1559
+ # Python Dependencies
1560
+ if [ -f "requirements.txt" ]; then
1561
+ echo "### Python Dependencies" >> $GITHUB_STEP_SUMMARY
1562
+ pip install pip-audit 2>&1 > /dev/null
1563
+ if pip-audit -r requirements.txt 2>&1 | tee /tmp/py_audit.txt; then
1564
+ echo "✅ No Python vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
1565
+ else
1566
+ VULN_COUNT=$(grep -c "vulnerability" /tmp/py_audit.txt || echo 0)
1567
+ echo "⚠️ Found $VULN_COUNT Python vulnerability/vulnerabilities" >> $GITHUB_STEP_SUMMARY
1568
+ VULNERABILITIES=$((VULNERABILITIES + VULN_COUNT))
1569
+ fi
1570
+ echo "" >> $GITHUB_STEP_SUMMARY
1571
+ fi
1572
+
1573
+ # NPM Dependencies
1574
+ if [ -f "package.json" ]; then
1575
+ echo "### NPM Dependencies" >> $GITHUB_STEP_SUMMARY
1576
+ if npm audit --production 2>&1 | tee /tmp/npm_audit.txt; then
1577
+ echo "✅ No NPM vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
1578
+ else
1579
+ VULN_COUNT=$(grep -c "vulnerability" /tmp/npm_audit.txt || echo 0)
1580
+ echo "⚠️ Found $VULN_COUNT NPM vulnerability/vulnerabilities" >> $GITHUB_STEP_SUMMARY
1581
+ VULNERABILITIES=$((VULNERABILITIES + VULN_COUNT))
1582
+ fi
1583
+ echo "" >> $GITHUB_STEP_SUMMARY
1584
+ fi
1585
+
1586
+ if [ "$VULNERABILITIES" -gt 0 ]; then
1587
+ echo "**Total Vulnerabilities**: $VULNERABILITIES" >> $GITHUB_STEP_SUMMARY
1588
+ echo "" >> $GITHUB_STEP_SUMMARY
1589
+ echo "**Action Required**: Update vulnerable dependencies" >> $GITHUB_STEP_SUMMARY
1590
+ exit 1
1591
+ else
1592
+ echo "✅ No dependency vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
1593
+ fi
1594
+
1595
+ unused-dependencies:
1596
+ name: Unused Dependencies Check
1597
+ runs-on: ubuntu-latest
1598
+
1599
+ steps:
1600
+ - name: Checkout Repository
1601
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1602
+
1603
+ - name: Setup PHP
1604
+ uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.31.0
1605
+ with:
1606
+ php-version: '8.1'
1607
+
1608
+ - name: Check Unused Dependencies
1609
+ run: |
1610
+ set -x
1611
+ echo "## 📦 Unused Dependencies Check" >> $GITHUB_STEP_SUMMARY
1612
+ echo "" >> $GITHUB_STEP_SUMMARY
1613
+
1614
+ if [ -f "composer.json" ]; then
1615
+ echo "### PHP Dependencies" >> $GITHUB_STEP_SUMMARY
1616
+
1617
+ # Install composer-unused
1618
+ composer global require icanhazstring/composer-unused 2>/dev/null || true
1619
+
1620
+ if composer global exec composer-unused 2>&1 | tee /tmp/unused.txt; then
1621
+ UNUSED_COUNT=$(grep "unused" /tmp/unused.txt | wc -l || echo 0)
1622
+ if [ "$UNUSED_COUNT" -gt 0 ]; then
1623
+ echo "⚠️ Found $UNUSED_COUNT unused dependency/dependencies" >> $GITHUB_STEP_SUMMARY
1624
+ echo "" >> $GITHUB_STEP_SUMMARY
1625
+ echo "<details>" >> $GITHUB_STEP_SUMMARY
1626
+ echo "<summary>View unused dependencies</summary>" >> $GITHUB_STEP_SUMMARY
1627
+ echo "" >> $GITHUB_STEP_SUMMARY
1628
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1629
+ cat /tmp/unused.txt >> $GITHUB_STEP_SUMMARY
1630
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1631
+ echo "</details>" >> $GITHUB_STEP_SUMMARY
1632
+ else
1633
+ echo "✅ No unused dependencies detected" >> $GITHUB_STEP_SUMMARY
1634
+ fi
1635
+ else
1636
+ echo "✅ All dependencies appear to be in use" >> $GITHUB_STEP_SUMMARY
1637
+ fi
1638
+ else
1639
+ echo "ℹ️ No composer.json found" >> $GITHUB_STEP_SUMMARY
1640
+ fi
1641
+
1642
+ echo "" >> $GITHUB_STEP_SUMMARY
1643
+ echo "**Recommendation**: Remove unused dependencies to reduce attack surface" >> $GITHUB_STEP_SUMMARY
1644
+
1645
+ broken-link-detection:
1646
+ name: Broken Link Detection
1647
+ runs-on: ubuntu-latest
1648
+
1649
+ steps:
1650
+ - name: Checkout Repository
1651
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1652
+
1653
+ - name: Check Internal Links
1654
+ run: |
1655
+ set -x
1656
+ echo "## 🔗 Broken Link Detection" >> $GITHUB_STEP_SUMMARY
1657
+ echo "" >> $GITHUB_STEP_SUMMARY
1658
+ echo "Checking internal links in markdown files." >> $GITHUB_STEP_SUMMARY
1659
+ echo "" >> $GITHUB_STEP_SUMMARY
1660
+
1661
+ BROKEN_LINKS=0
1662
+ CHECKED_LINKS=0
1663
+
1664
+ # Find all markdown files
1665
+ MD_FILES=$(find . -name "*.md" ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*")
1666
+
1667
+ for file in $MD_FILES; do
1668
+ # Extract markdown links [text](path)
1669
+ while IFS= read -r line; do
1670
+ # Extract path from [text](path)
1671
+ link=$(echo "$line" | sed -n 's/.*\](\([^)]*\)).*/\1/p')
1672
+
1673
+ # Skip external links (http/https)
1674
+ if echo "$link" | grep -qE "^https?://"; then
1675
+ continue
1676
+ fi
1677
+
1678
+ # Skip anchors only
1679
+ if echo "$link" | grep -qE "^#"; then
1680
+ continue
1681
+ fi
1682
+
1683
+ CHECKED_LINKS=$((CHECKED_LINKS + 1))
1684
+
1685
+ # Get directory of the markdown file
1686
+ basedir=$(dirname "$file")
1687
+
1688
+ # Resolve relative path
1689
+ if [ -n "$link" ]; then
1690
+ # Remove anchor if present
1691
+ clean_link=$(echo "$link" | sed 's/#.*//')
1692
+
1693
+ # Check if file exists
1694
+ if [ ! -e "$basedir/$clean_link" ] && [ ! -e "$clean_link" ]; then
1695
+ echo "Broken link in $file: $link" >> /tmp/broken_links.txt
1696
+ BROKEN_LINKS=$((BROKEN_LINKS + 1))
1697
+ fi
1698
+ fi
1699
+ done < <(grep -o '\[.*\](.*)' "$file" 2>/dev/null || true)
1700
+ done
1701
+
1702
+ echo "### Link Validation Results" >> $GITHUB_STEP_SUMMARY
1703
+ echo "- **Links Checked**: $CHECKED_LINKS" >> $GITHUB_STEP_SUMMARY
1704
+ echo "- **Broken Links**: $BROKEN_LINKS" >> $GITHUB_STEP_SUMMARY
1705
+ echo "" >> $GITHUB_STEP_SUMMARY
1706
+
1707
+ if [ "$BROKEN_LINKS" -gt 0 ]; then
1708
+ echo "⚠️ Found $BROKEN_LINKS broken internal link(s)" >> $GITHUB_STEP_SUMMARY
1709
+ echo "" >> $GITHUB_STEP_SUMMARY
1710
+ echo "<details>" >> $GITHUB_STEP_SUMMARY
1711
+ echo "<summary>View broken links</summary>" >> $GITHUB_STEP_SUMMARY
1712
+ echo "" >> $GITHUB_STEP_SUMMARY
1713
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1714
+ cat /tmp/broken_links.txt 2>/dev/null >> $GITHUB_STEP_SUMMARY
1715
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1716
+ echo "</details>" >> $GITHUB_STEP_SUMMARY
1717
+ echo "" >> $GITHUB_STEP_SUMMARY
1718
+ echo "**Recommendation**: Fix or remove broken links to maintain documentation quality" >> $GITHUB_STEP_SUMMARY
1719
+ else
1720
+ if [ "$CHECKED_LINKS" -gt 0 ]; then
1721
+ echo "✅ All internal links are valid" >> $GITHUB_STEP_SUMMARY
1722
+ else
1723
+ echo "ℹ️ No internal links found to check" >> $GITHUB_STEP_SUMMARY
1724
+ fi
1725
+ fi
1726
+
1727
+ echo "" >> $GITHUB_STEP_SUMMARY
1728
+ echo "**Note**: This check validates internal file references only. External URLs are not validated." >> $GITHUB_STEP_SUMMARY
1729
+
1730
+ # ============================================================================
1731
+ # PHASE 2: Medium Priority Checks
1732
+ # ============================================================================
1733
+
1734
+ api-documentation:
1735
+ name: API Documentation Coverage
1736
+ runs-on: ubuntu-latest
1737
+
1738
+ steps:
1739
+ - name: Checkout Repository
1740
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1741
+
1742
+ - name: Check Documentation
1743
+ run: |
1744
+ set -x
1745
+ echo "## 📚 API Documentation Coverage" >> $GITHUB_STEP_SUMMARY
1746
+ echo "" >> $GITHUB_STEP_SUMMARY
1747
+
1748
+ # Count public functions/classes
1749
+ PUBLIC_METHODS=$(grep -r "public function" . --include="*.php" ! -path "./vendor/*" | wc -l || echo 0)
1750
+ DOCUMENTED=$(grep -B5 -r "public function" . --include="*.php" ! -path "./vendor/*" | grep -c "/\*\*" || echo 0)
1751
+
1752
+ if [ "$PUBLIC_METHODS" -gt 0 ]; then
1753
+ COVERAGE=$((DOCUMENTED * 100 / PUBLIC_METHODS))
1754
+ echo "**Documentation Coverage**: $COVERAGE% ($DOCUMENTED/$PUBLIC_METHODS)" >> $GITHUB_STEP_SUMMARY
1755
+ echo "" >> $GITHUB_STEP_SUMMARY
1756
+
1757
+ if [ "$COVERAGE" -lt 80 ]; then
1758
+ echo "⚠️ Documentation coverage below 80% threshold" >> $GITHUB_STEP_SUMMARY
1759
+ echo "**Recommendation**: Add PHPDoc blocks to public methods" >> $GITHUB_STEP_SUMMARY
1760
+ else
1761
+ echo "✅ Good documentation coverage" >> $GITHUB_STEP_SUMMARY
1762
+ fi
1763
+ else
1764
+ echo "ℹ️ No public methods found for documentation check" >> $GITHUB_STEP_SUMMARY
1765
+ fi
1766
+
1767
+ accessibility-check:
1768
+ name: Accessibility Check
1769
+ runs-on: ubuntu-latest
1770
+
1771
+ steps:
1772
+ - name: Checkout Repository
1773
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1774
+
1775
+ - name: Check Accessibility
1776
+ run: |
1777
+ set -x
1778
+ echo "## ♿ Accessibility Check" >> $GITHUB_STEP_SUMMARY
1779
+ echo "" >> $GITHUB_STEP_SUMMARY
1780
+
1781
+ HTML_COUNT=$(find . -name "*.html" ! -path "./vendor/*" ! -path "./.git/*" ! -path "./node_modules/*" | wc -l || echo 0)
1782
+ MD_IMG_COUNT=$(find . -name "*.md" ! -path "./vendor/*" ! -path "./.git/*" -exec grep -l "!\[" {} + 2>/dev/null | wc -l || echo 0)
1783
+
1784
+ if [ "$HTML_COUNT" -gt 0 ] || [ "$MD_IMG_COUNT" -gt 0 ]; then
1785
+ # Check for images without alt text
1786
+ MISSING_ALT=0
1787
+
1788
+ if [ "$HTML_COUNT" -gt 0 ]; then
1789
+ MISSING_ALT=$(grep -r "<img" . --include="*.html" | grep -v "alt=" | wc -l || echo 0)
1790
+ fi
1791
+
1792
+ echo "**Images without alt text**: $MISSING_ALT" >> $GITHUB_STEP_SUMMARY
1793
+ echo "" >> $GITHUB_STEP_SUMMARY
1794
+
1795
+ if [ "$MISSING_ALT" -gt 0 ]; then
1796
+ echo "⚠️ Found images without alt text" >> $GITHUB_STEP_SUMMARY
1797
+ echo "**Recommendation**: Add descriptive alt text for accessibility" >> $GITHUB_STEP_SUMMARY
1798
+ else
1799
+ echo "✅ All images have alt text" >> $GITHUB_STEP_SUMMARY
1800
+ fi
1801
+ else
1802
+ echo "ℹ️ No HTML files found for accessibility check" >> $GITHUB_STEP_SUMMARY
1803
+ fi
1804
+
1805
+ performance-metrics:
1806
+ name: Performance Metrics
1807
+ runs-on: ubuntu-latest
1808
+
1809
+ steps:
1810
+ - name: Checkout Repository
1811
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1812
+
1813
+ - name: Check Performance Metrics
1814
+ run: |
1815
+ set -x
1816
+ echo "## ⚡ Performance Metrics" >> $GITHUB_STEP_SUMMARY
1817
+ echo "" >> $GITHUB_STEP_SUMMARY
1818
+
1819
+ # Check if JavaScript bundles exist
1820
+ if [ -f "package.json" ]; then
1821
+ echo "### Bundle Analysis" >> $GITHUB_STEP_SUMMARY
1822
+
1823
+ # Check for common bundle files
1824
+ BUNDLE_SIZE=0
1825
+ if [ -d "dist" ]; then
1826
+ BUNDLE_SIZE=$(du -sb dist/ 2>/dev/null | cut -f1 || echo 0)
1827
+ elif [ -d "build" ]; then
1828
+ BUNDLE_SIZE=$(du -sb build/ 2>/dev/null | cut -f1 || echo 0)
1829
+ fi
1830
+
1831
+ if [ "$BUNDLE_SIZE" -gt 0 ]; then
1832
+ BUNDLE_MB=$((BUNDLE_SIZE / 1024 / 1024))
1833
+ echo "**Bundle Size**: ${BUNDLE_MB}MB" >> $GITHUB_STEP_SUMMARY
1834
+ echo "" >> $GITHUB_STEP_SUMMARY
1835
+
1836
+ if [ "$BUNDLE_MB" -gt 5 ]; then
1837
+ echo "⚠️ Bundle size exceeds 5MB threshold" >> $GITHUB_STEP_SUMMARY
1838
+ echo "**Recommendation**: Optimize bundle size" >> $GITHUB_STEP_SUMMARY
1839
+ else
1840
+ echo "✅ Bundle size within acceptable limits" >> $GITHUB_STEP_SUMMARY
1841
+ fi
1842
+ else
1843
+ echo "ℹ️ No build artifacts found" >> $GITHUB_STEP_SUMMARY
1844
+ fi
1845
+ else
1846
+ echo "ℹ️ Not a JavaScript project" >> $GITHUB_STEP_SUMMARY
1847
+ fi
1848
+
1849
+ enterprise-readiness:
1850
+ name: Enterprise Readiness Check
1851
+ runs-on: ubuntu-latest
1852
+
1853
+ steps:
1854
+ - name: Checkout Repository
1855
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1856
+
1857
+ - name: Set up PHP
1858
+ uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.31.0
1859
+ with:
1860
+ php-version: '8.1'
1861
+ extensions: json, mbstring
1862
+ tools: composer
1863
+ coverage: none
1864
+
1865
+ - name: Install API Package
1866
+ env:
1867
+ GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
1868
+ COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN || github.token }}"}}'
1869
+ run: |
1870
+ if [ -f "composer.json" ]; then
1871
+ composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
1872
+ else
1873
+ echo "No composer.json — pulling MokoCLI tools"
1874
+ if [ ! -d "/tmp/mokostandards" ]; then
1875
+ git clone --depth 1 --branch version/04 --quiet \
1876
+ "https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/mokocli.git" \
1877
+ /tmp/mokostandards 2>/dev/null || true
1878
+ if [ -f "/tmp/mokostandards/composer.json" ]; then
1879
+ cd /tmp/mokostandards && composer install --no-dev --no-interaction --quiet 2>/dev/null || true
1880
+ cd -
1881
+ fi
1882
+ fi
1883
+ fi
1884
+
1885
+ - name: Check Enterprise Readiness
1886
+ id: enterprise_check
1887
+ run: |
1888
+ echo "" >> $GITHUB_STEP_SUMMARY
1889
+
1890
+ SCRIPT=""
1891
+ if [ -f "api/validate/check_enterprise_readiness.php" ]; then
1892
+ SCRIPT="api/validate/check_enterprise_readiness.php"
1893
+ elif [ -f "/tmp/mokostandards/api/validate/check_enterprise_readiness.php" ]; then
1894
+ SCRIPT="/tmp/mokostandards/api/validate/check_enterprise_readiness.php"
1895
+ fi
1896
+
1897
+ if [ -n "$SCRIPT" ]; then
1898
+ php "$SCRIPT" --verbose | tee /tmp/enterprise-check.log
1899
+ EXIT_CODE=$?
1900
+
1901
+ echo "" >> $GITHUB_STEP_SUMMARY
1902
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1903
+ cat /tmp/enterprise-check.log >> $GITHUB_STEP_SUMMARY
1904
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1905
+
1906
+ if [ "$EXIT_CODE" -eq 0 ]; then
1907
+ echo "" >> $GITHUB_STEP_SUMMARY
1908
+ echo "✅ Repository meets enterprise readiness criteria!" >> $GITHUB_STEP_SUMMARY
1909
+ exit 0
1910
+ else
1911
+ echo "" >> $GITHUB_STEP_SUMMARY
1912
+ echo "⚠️ Enterprise readiness issues detected" >> $GITHUB_STEP_SUMMARY
1913
+ echo "**Note:** This is informational - review recommendations to improve" >> $GITHUB_STEP_SUMMARY
1914
+ exit 0 # Non-blocking
1915
+ fi
1916
+ else
1917
+ echo "ℹ️ Enterprise readiness check script not found - skipping" >> $GITHUB_STEP_SUMMARY
1918
+ exit 0
1919
+ fi
1920
+
1921
+ repository-health:
1922
+ name: Repository Health Check
1923
+ runs-on: ubuntu-latest
1924
+
1925
+ steps:
1926
+ - name: Checkout Repository
1927
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
1928
+
1929
+ - name: Set up PHP
1930
+ uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.31.0
1931
+ with:
1932
+ php-version: '8.1'
1933
+ extensions: json, mbstring
1934
+ tools: composer
1935
+ coverage: none
1936
+
1937
+ - name: Install API Package
1938
+ env:
1939
+ GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
1940
+ COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN || github.token }}"}}'
1941
+ run: |
1942
+ if [ -f "composer.json" ]; then
1943
+ composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
1944
+ else
1945
+ echo "No composer.json — pulling MokoCLI tools"
1946
+ if [ ! -d "/tmp/mokostandards" ]; then
1947
+ git clone --depth 1 --branch version/04 --quiet \
1948
+ "https://x-access-token:${GH_TOKEN}@github.com/mokoconsulting-tech/mokocli.git" \
1949
+ /tmp/mokostandards 2>/dev/null || true
1950
+ if [ -f "/tmp/mokostandards/composer.json" ]; then
1951
+ cd /tmp/mokostandards && composer install --no-dev --no-interaction --quiet 2>/dev/null || true
1952
+ cd -
1953
+ fi
1954
+ fi
1955
+ fi
1956
+
1957
+ - name: Check Repository Health
1958
+ id: health_check
1959
+ run: |
1960
+ echo "" >> $GITHUB_STEP_SUMMARY
1961
+
1962
+ SCRIPT=""
1963
+ if [ -f "api/validate/check_repo_health.php" ]; then
1964
+ SCRIPT="api/validate/check_repo_health.php"
1965
+ elif [ -f "/tmp/mokostandards/api/validate/check_repo_health.php" ]; then
1966
+ SCRIPT="/tmp/mokostandards/api/validate/check_repo_health.php"
1967
+ fi
1968
+
1969
+ if [ -n "$SCRIPT" ]; then
1970
+ php "$SCRIPT" --verbose | tee /tmp/health-check.log
1971
+ EXIT_CODE=$?
1972
+
1973
+ echo "" >> $GITHUB_STEP_SUMMARY
1974
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1975
+ cat /tmp/health-check.log >> $GITHUB_STEP_SUMMARY
1976
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
1977
+
1978
+ if [ "$EXIT_CODE" -eq 0 ]; then
1979
+ echo "" >> $GITHUB_STEP_SUMMARY
1980
+ echo "✅ Repository health check passed!" >> $GITHUB_STEP_SUMMARY
1981
+ exit 0
1982
+ else
1983
+ echo "" >> $GITHUB_STEP_SUMMARY
1984
+ echo "⚠️ Repository health issues detected" >> $GITHUB_STEP_SUMMARY
1985
+ echo "**Note:** This is informational - review recommendations to improve" >> $GITHUB_STEP_SUMMARY
1986
+ exit 0 # Non-blocking
1987
+ fi
1988
+ else
1989
+ echo "ℹ️ Repository health check script not found - skipping" >> $GITHUB_STEP_SUMMARY
1990
+ exit 0
1991
+ fi
1992
+
1993
+ terraform-validation:
1994
+ name: Terraform Configuration Validation
1995
+ runs-on: ubuntu-latest
1996
+
1997
+ steps:
1998
+ - name: Checkout Repository
1999
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
2000
+
2001
+ - name: Setup Terraform
2002
+ uses: hashicorp/setup-terraform@5e8dbf3c6d9deaf4193ca7a8fb23f2ac83bb6c85 # v4.0.0
2003
+ with:
2004
+ terraform_version: "1.0"
2005
+
2006
+ - name: Validate Terraform Files
2007
+ run: |
2008
+ set -x
2009
+ echo "## 🏗️ Terraform Configuration Validation" >> $GITHUB_STEP_SUMMARY
2010
+ echo "" >> $GITHUB_STEP_SUMMARY
2011
+
2012
+ # Check if terraform files exist
2013
+ TF_COUNT=$(find . -name "*.tf" -type f | wc -l || echo 0)
2014
+
2015
+ if [ "$TF_COUNT" -eq 0 ]; then
2016
+ echo "ℹ️ No Terraform files found in repository" >> $GITHUB_STEP_SUMMARY
2017
+ exit 0
2018
+ fi
2019
+
2020
+ echo "**Terraform Files Found**: $TF_COUNT" >> $GITHUB_STEP_SUMMARY
2021
+ echo "" >> $GITHUB_STEP_SUMMARY
2022
+
2023
+ # Validation Results
2024
+ VALIDATION_PASSED=true
2025
+ WARNINGS=0
2026
+ ERRORS=0
2027
+
2028
+ # 1. Check .mokogit/config.tf location (not root override files)
2029
+ echo "### Override Configuration Check" >> $GITHUB_STEP_SUMMARY
2030
+ LEGACY_OVERRIDES=$(find . -maxdepth 1 -name "*override*.tf" -o -name "MokoCLI.override.tf" 2>/dev/null | wc -l || echo 0)
2031
+ if [ "$LEGACY_OVERRIDES" -gt 0 ]; then
2032
+ echo "⚠️ Found legacy override files in root directory" >> $GITHUB_STEP_SUMMARY
2033
+ echo "**Expected Location**: .mokogit/config.tf" >> $GITHUB_STEP_SUMMARY
2034
+ echo "**Legacy files found**: $LEGACY_OVERRIDES" >> $GITHUB_STEP_SUMMARY
2035
+ WARNINGS=$((WARNINGS + 1))
2036
+ else
2037
+ if [ -f ".mokogit/config.tf" ]; then
2038
+ echo "✅ Override configuration in correct location (.mokogit/config.tf)" >> $GITHUB_STEP_SUMMARY
2039
+ else
2040
+ echo "ℹ️ No override configuration found" >> $GITHUB_STEP_SUMMARY
2041
+ fi
2042
+ fi
2043
+ echo "" >> $GITHUB_STEP_SUMMARY
2044
+
2045
+ # 2. Terraform Syntax Validation
2046
+ echo "### Terraform Syntax Validation" >> $GITHUB_STEP_SUMMARY
2047
+ SYNTAX_ERRORS=0
2048
+
2049
+ # Find all directories with terraform files
2050
+ for dir in $(find . -name "*.tf" -type f -exec dirname {} \; | sort -u); do
2051
+ cd "$dir" || continue
2052
+ echo "Validating: $dir" >> $GITHUB_STEP_SUMMARY
2053
+
2054
+ # Initialize without backend
2055
+ terraform init -backend=false > /dev/null 2>&1 || true
2056
+
2057
+ # Validate
2058
+ if terraform validate -no-color > /tmp/tf_validate.txt 2>&1; then
2059
+ echo " ✅ Syntax valid" >> $GITHUB_STEP_SUMMARY
2060
+ else
2061
+ echo " ❌ Syntax errors found" >> $GITHUB_STEP_SUMMARY
2062
+ cat /tmp/tf_validate.txt >> $GITHUB_STEP_SUMMARY
2063
+ SYNTAX_ERRORS=$((SYNTAX_ERRORS + 1))
2064
+ VALIDATION_PASSED=false
2065
+ fi
2066
+ cd - > /dev/null
2067
+ done
2068
+ echo "" >> $GITHUB_STEP_SUMMARY
2069
+
2070
+ if [ "$SYNTAX_ERRORS" -eq 0 ]; then
2071
+ echo "✅ All Terraform files have valid syntax" >> $GITHUB_STEP_SUMMARY
2072
+ else
2073
+ echo "❌ Found $SYNTAX_ERRORS directories with syntax errors" >> $GITHUB_STEP_SUMMARY
2074
+ ERRORS=$((ERRORS + SYNTAX_ERRORS))
2075
+ fi
2076
+ echo "" >> $GITHUB_STEP_SUMMARY
2077
+
2078
+ # 3. Terraform Formatting Check
2079
+ echo "### Terraform Formatting Check" >> $GITHUB_STEP_SUMMARY
2080
+ FORMAT_ISSUES=0
2081
+
2082
+ for tf_file in $(find . -name "*.tf" -type f); do
2083
+ if ! terraform fmt -check=true -no-color "$tf_file" > /dev/null 2>&1; then
2084
+ FORMAT_ISSUES=$((FORMAT_ISSUES + 1))
2085
+ fi
2086
+ done
2087
+
2088
+ if [ "$FORMAT_ISSUES" -eq 0 ]; then
2089
+ echo "✅ All Terraform files properly formatted" >> $GITHUB_STEP_SUMMARY
2090
+ else
2091
+ echo "⚠️ Found $FORMAT_ISSUES files with formatting issues" >> $GITHUB_STEP_SUMMARY
2092
+ echo "**Fix**: Run \`terraform fmt -recursive\`" >> $GITHUB_STEP_SUMMARY
2093
+ WARNINGS=$((WARNINGS + 1))
2094
+ fi
2095
+ echo "" >> $GITHUB_STEP_SUMMARY
2096
+
2097
+ # 4. Check for file_metadata blocks
2098
+ echo "### File Metadata Validation" >> $GITHUB_STEP_SUMMARY
2099
+ MISSING_METADATA=0
2100
+
2101
+ for tf_file in $(find . -name "*.tf" -type f); do
2102
+ if ! grep -q "file_metadata" "$tf_file"; then
2103
+ MISSING_METADATA=$((MISSING_METADATA + 1))
2104
+ fi
2105
+ done
2106
+
2107
+ if [ "$MISSING_METADATA" -eq 0 ]; then
2108
+ echo "✅ All Terraform files contain file_metadata block" >> $GITHUB_STEP_SUMMARY
2109
+ else
2110
+ echo "⚠️ Found $MISSING_METADATA files missing file_metadata block" >> $GITHUB_STEP_SUMMARY
2111
+ echo "**Reference**: docs/policy/terraform-file-standards.md" >> $GITHUB_STEP_SUMMARY
2112
+ WARNINGS=$((WARNINGS + 1))
2113
+ fi
2114
+ echo "" >> $GITHUB_STEP_SUMMARY
2115
+
2116
+ # 5. Version Consistency Check
2117
+ echo "### Version Consistency Check" >> $GITHUB_STEP_SUMMARY
2118
+ VERSION_MISMATCHES=0
2119
+ EXPECTED_VERSION="04.00.04"
2120
+
2121
+ for tf_file in $(find . -name "*.tf" -type f); do
2122
+ if grep -q "version.*=" "$tf_file"; then
2123
+ if ! grep -q "version.*=.*\"$EXPECTED_VERSION\"" "$tf_file"; then
2124
+ VERSION_MISMATCHES=$((VERSION_MISMATCHES + 1))
2125
+ fi
2126
+ fi
2127
+ done
2128
+
2129
+ if [ "$VERSION_MISMATCHES" -eq 0 ]; then
2130
+ echo "✅ All Terraform file versions match $EXPECTED_VERSION" >> $GITHUB_STEP_SUMMARY
2131
+ else
2132
+ echo "⚠️ Found $VERSION_MISMATCHES files with version mismatches" >> $GITHUB_STEP_SUMMARY
2133
+ echo "**Expected Version**: $EXPECTED_VERSION" >> $GITHUB_STEP_SUMMARY
2134
+ WARNINGS=$((WARNINGS + 1))
2135
+ fi
2136
+ echo "" >> $GITHUB_STEP_SUMMARY
2137
+
2138
+ # 6. Copyright Header Check
2139
+ echo "### Copyright Header Check" >> $GITHUB_STEP_SUMMARY
2140
+ MISSING_COPYRIGHT=0
2141
+
2142
+ for tf_file in $(find . -name "*.tf" -type f); do
2143
+ if ! grep -q "Copyright (C)" "$tf_file"; then
2144
+ MISSING_COPYRIGHT=$((MISSING_COPYRIGHT + 1))
2145
+ fi
2146
+ done
2147
+
2148
+ if [ "$MISSING_COPYRIGHT" -eq 0 ]; then
2149
+ echo "✅ All Terraform files have copyright headers" >> $GITHUB_STEP_SUMMARY
2150
+ else
2151
+ echo "⚠️ Found $MISSING_COPYRIGHT files missing copyright headers" >> $GITHUB_STEP_SUMMARY
2152
+ echo "**Reference**: docs/policy/terraform-file-standards.md" >> $GITHUB_STEP_SUMMARY
2153
+ WARNINGS=$((WARNINGS + 1))
2154
+ fi
2155
+ echo "" >> $GITHUB_STEP_SUMMARY
2156
+
2157
+ # Summary
2158
+ echo "---" >> $GITHUB_STEP_SUMMARY
2159
+ echo "### Validation Summary" >> $GITHUB_STEP_SUMMARY
2160
+ echo "**Total Files**: $TF_COUNT" >> $GITHUB_STEP_SUMMARY
2161
+ echo "**Errors**: $ERRORS" >> $GITHUB_STEP_SUMMARY
2162
+ echo "**Warnings**: $WARNINGS" >> $GITHUB_STEP_SUMMARY
2163
+ echo "" >> $GITHUB_STEP_SUMMARY
2164
+
2165
+ if [ "$VALIDATION_PASSED" = true ] && [ "$ERRORS" -eq 0 ]; then
2166
+ echo "✅ **Terraform Validation: PASSED**" >> $GITHUB_STEP_SUMMARY
2167
+ exit 0
2168
+ elif [ "$ERRORS" -gt 0 ]; then
2169
+ echo "❌ **Terraform Validation: FAILED**" >> $GITHUB_STEP_SUMMARY
2170
+ echo "" >> $GITHUB_STEP_SUMMARY
2171
+ echo "**Note**: This is an informational check and does not block merges" >> $GITHUB_STEP_SUMMARY
2172
+ exit 0 # Informational only
2173
+ else
2174
+ echo "⚠️ **Terraform Validation: PASSED WITH WARNINGS**" >> $GITHUB_STEP_SUMMARY
2175
+ echo "" >> $GITHUB_STEP_SUMMARY
2176
+ echo "**Note**: This is an informational check and does not block merges" >> $GITHUB_STEP_SUMMARY
2177
+ exit 0 # Informational only
2178
+ fi
2179
+
2180
+ summary:
2181
+ name: Compliance Summary
2182
+ runs-on: ubuntu-latest
2183
+ needs: [
2184
+ repository-structure, documentation-quality, coding-standards, line-length-validation, license-compliance, git-hygiene, workflow-validation, version-consistency, script-integrity, enterprise-readiness, repository-health,
2185
+ todo-fixme-tracking, file-size-limits, broken-link-detection,
2186
+ dependency-vulnerabilities, code-duplication, unused-dependencies, readme-completeness,
2187
+ code-complexity, api-documentation, insecure-patterns, binary-file-detection,
2188
+ dead-code-detection, file-naming-standards, accessibility-check, performance-metrics, terraform-validation
2189
+ ]
2190
+ if: always()
2191
+
2192
+ steps:
2193
+ - name: Generate Compliance Report
2194
+ run: |
2195
+ set -x
2196
+ echo "# 📊 MokoCLI Compliance Report" >> $GITHUB_STEP_SUMMARY
2197
+ echo "" >> $GITHUB_STEP_SUMMARY
2198
+
2199
+ # Calculate overall status
2200
+ REPO_STATUS="${{ needs.repository-structure.result }}"
2201
+ DOCS_STATUS="${{ needs.documentation-quality.result }}"
2202
+ CODE_STATUS="${{ needs.coding-standards.result }}"
2203
+ LINE_LENGTH_STATUS="${{ needs.line-length-validation.result }}"
2204
+ LICENSE_STATUS="${{ needs.license-compliance.result }}"
2205
+ GIT_STATUS="${{ needs.git-hygiene.result }}"
2206
+ WORKFLOW_STATUS="${{ needs.workflow-validation.result }}"
2207
+ VERSION_STATUS="${{ needs.version-consistency.result }}"
2208
+ SCRIPT_STATUS="${{ needs.script-integrity.result }}"
2209
+ ENTERPRISE_STATUS="${{ needs.enterprise-readiness.result }}"
2210
+ HEALTH_STATUS="${{ needs.repository-health.result }}"
2211
+ TERRAFORM_STATUS="${{ needs.terraform-validation.result }}"
2212
+
2213
+ PASSED=0
2214
+ FAILED=0
2215
+ WARNINGS=0
2216
+ TOTAL=28
2217
+
2218
+ # Critical checks (must pass)
2219
+ [ "$REPO_STATUS" = "success" ] && PASSED=$((PASSED + 1)) || FAILED=$((FAILED + 1))
2220
+ [ "$DOCS_STATUS" = "success" ] && PASSED=$((PASSED + 1)) || FAILED=$((FAILED + 1))
2221
+ [ "$CODE_STATUS" = "success" ] && PASSED=$((PASSED + 1)) || FAILED=$((FAILED + 1))
2222
+ [ "$LICENSE_STATUS" = "success" ] && PASSED=$((PASSED + 1)) || FAILED=$((FAILED + 1))
2223
+ [ "$GIT_STATUS" = "success" ] && PASSED=$((PASSED + 1)) || FAILED=$((FAILED + 1))
2224
+ [ "$WORKFLOW_STATUS" = "success" ] && PASSED=$((PASSED + 1)) || FAILED=$((FAILED + 1))
2225
+ [ "$VERSION_STATUS" = "success" ] && PASSED=$((PASSED + 1)) || FAILED=$((FAILED + 1))
2226
+ [ "$SCRIPT_STATUS" = "success" ] && PASSED=$((PASSED + 1)) || FAILED=$((FAILED + 1))
2227
+
2228
+ # Informational checks (don't fail build)
2229
+ if [ "$ENTERPRISE_STATUS" = "success" ]; then
2230
+ PASSED=$((PASSED + 1))
2231
+ else
2232
+ WARNINGS=$((WARNINGS + 1))
2233
+ fi
2234
+
2235
+ if [ "$HEALTH_STATUS" = "success" ]; then
2236
+ PASSED=$((PASSED + 1))
2237
+ else
2238
+ WARNINGS=$((WARNINGS + 1))
2239
+ fi
2240
+
2241
+ if [ "$TERRAFORM_STATUS" = "success" ]; then
2242
+ PASSED=$((PASSED + 1))
2243
+ else
2244
+ WARNINGS=$((WARNINGS + 1))
2245
+ fi
2246
+
2247
+ # Adjust total to only count critical checks for compliance percentage
2248
+ CRITICAL_TOTAL=8
2249
+ CRITICAL_PASSED=$((PASSED - WARNINGS))
2250
+ COMPLIANCE_PERCENT=$((CRITICAL_PASSED * 100 / CRITICAL_TOTAL))
2251
+
2252
+ # Overall status badge
2253
+ if [ "$COMPLIANCE_PERCENT" -eq 100 ]; then
2254
+ echo "## ✅ Overall Status: **COMPLIANT** ($COMPLIANCE_PERCENT%)" >> $GITHUB_STEP_SUMMARY
2255
+ elif [ "$COMPLIANCE_PERCENT" -ge 80 ]; then
2256
+ echo "## ⚠️ Overall Status: **MOSTLY COMPLIANT** ($COMPLIANCE_PERCENT%)" >> $GITHUB_STEP_SUMMARY
2257
+ elif [ "$COMPLIANCE_PERCENT" -ge 50 ]; then
2258
+ echo "## ⚠️ Overall Status: **PARTIALLY COMPLIANT** ($COMPLIANCE_PERCENT%)" >> $GITHUB_STEP_SUMMARY
2259
+ else
2260
+ echo "## ❌ Overall Status: **NON-COMPLIANT** ($COMPLIANCE_PERCENT%)" >> $GITHUB_STEP_SUMMARY
2261
+ fi
2262
+
2263
+ echo "" >> $GITHUB_STEP_SUMMARY
2264
+ echo "**Critical Checks:** $CRITICAL_PASSED/$CRITICAL_TOTAL passed" >> $GITHUB_STEP_SUMMARY
2265
+ echo "**Total Checks:** $PASSED/$TOTAL passed" >> $GITHUB_STEP_SUMMARY
2266
+ if [ "$WARNINGS" -gt 0 ]; then
2267
+ echo "**Informational:** $WARNINGS warning(s)" >> $GITHUB_STEP_SUMMARY
2268
+ fi
2269
+ echo "" >> $GITHUB_STEP_SUMMARY
2270
+
2271
+ # Progress bar
2272
+ FILLED=$((COMPLIANCE_PERCENT / 5))
2273
+ EMPTY=$((20 - FILLED))
2274
+ BAR=""
2275
+ for i in $(seq 1 $FILLED); do BAR="${BAR}█"; done
2276
+ for i in $(seq 1 $EMPTY); do BAR="${BAR}░"; done
2277
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
2278
+ echo "$BAR $COMPLIANCE_PERCENT%" >> $GITHUB_STEP_SUMMARY
2279
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
2280
+ echo "" >> $GITHUB_STEP_SUMMARY
2281
+
2282
+ # Detailed breakdown
2283
+ echo "## Validation Results" >> $GITHUB_STEP_SUMMARY
2284
+ echo "" >> $GITHUB_STEP_SUMMARY
2285
+ echo "| Area | Status | Result | Priority |" >> $GITHUB_STEP_SUMMARY
2286
+ echo "|------|--------|--------|----------|" >> $GITHUB_STEP_SUMMARY
2287
+
2288
+ # Repository Structure
2289
+ if [ "$REPO_STATUS" = "success" ]; then
2290
+ echo "| 📁 Repository Structure | ✅ Pass | Compliant | - |" >> $GITHUB_STEP_SUMMARY
2291
+ else
2292
+ echo "| 📁 Repository Structure | ❌ Fail | **Action Required** | 🔴 Critical |" >> $GITHUB_STEP_SUMMARY
2293
+ fi
2294
+
2295
+ # Documentation Quality
2296
+ if [ "$DOCS_STATUS" = "success" ]; then
2297
+ echo "| 📚 Documentation Quality | ✅ Pass | Compliant | - |" >> $GITHUB_STEP_SUMMARY
2298
+ else
2299
+ echo "| 📚 Documentation Quality | ❌ Fail | **Action Required** | 🔴 Critical |" >> $GITHUB_STEP_SUMMARY
2300
+ fi
2301
+
2302
+ # Coding Standards
2303
+ if [ "$CODE_STATUS" = "success" ]; then
2304
+ echo "| 💻 Coding Standards | ✅ Pass | Compliant | - |" >> $GITHUB_STEP_SUMMARY
2305
+ else
2306
+ echo "| 💻 Coding Standards | ⚠️ Warning | Review Recommended | 🟡 Medium |" >> $GITHUB_STEP_SUMMARY
2307
+ fi
2308
+
2309
+ # License Compliance
2310
+ if [ "$LICENSE_STATUS" = "success" ]; then
2311
+ echo "| ⚖️ License Compliance | ✅ Pass | Compliant | - |" >> $GITHUB_STEP_SUMMARY
2312
+ else
2313
+ echo "| ⚖️ License Compliance | ❌ Fail | **Action Required** | 🔴 Critical |" >> $GITHUB_STEP_SUMMARY
2314
+ fi
2315
+
2316
+ # Git Hygiene
2317
+ if [ "$GIT_STATUS" = "success" ]; then
2318
+ echo "| 🧹 Git Repository Hygiene | ✅ Pass | Compliant | - |" >> $GITHUB_STEP_SUMMARY
2319
+ else
2320
+ echo "| 🧹 Git Repository Hygiene | ⚠️ Warning | Review Recommended | 🟡 Medium |" >> $GITHUB_STEP_SUMMARY
2321
+ fi
2322
+
2323
+ # Workflow Configuration
2324
+ if [ "$WORKFLOW_STATUS" = "success" ]; then
2325
+ echo "| ⚙️ Workflow Configuration | ✅ Pass | Compliant | - |" >> $GITHUB_STEP_SUMMARY
2326
+ else
2327
+ echo "| ⚙️ Workflow Configuration | ⚠️ Warning | Review Recommended | 🟡 Medium |" >> $GITHUB_STEP_SUMMARY
2328
+ fi
2329
+
2330
+ # Version Consistency
2331
+ if [ "$VERSION_STATUS" = "success" ]; then
2332
+ echo "| 🔢 Version Consistency | ✅ Pass | All versions match | - |" >> $GITHUB_STEP_SUMMARY
2333
+ else
2334
+ echo "| 🔢 Version Consistency | ❌ Fail | **Action Required** | 🔴 Critical |" >> $GITHUB_STEP_SUMMARY
2335
+ fi
2336
+
2337
+ # Script Integrity
2338
+ if [ "$SCRIPT_STATUS" = "success" ]; then
2339
+ echo "| 🔐 Script Integrity | ✅ Pass | SHA hashes validated | - |" >> $GITHUB_STEP_SUMMARY
2340
+ else
2341
+ echo "| 🔐 Script Integrity | ❌ Fail | **Action Required** | 🔴 Critical |" >> $GITHUB_STEP_SUMMARY
2342
+ fi
2343
+
2344
+ # Enterprise Readiness (Informational)
2345
+ if [ "$ENTERPRISE_STATUS" = "success" ]; then
2346
+ echo "| 🏢 Enterprise Readiness | ✅ Pass | Ready for enterprise | ℹ️ Info |" >> $GITHUB_STEP_SUMMARY
2347
+ else
2348
+ echo "| 🏢 Enterprise Readiness | ℹ️ Info | Review suggestions | ℹ️ Info |" >> $GITHUB_STEP_SUMMARY
2349
+ fi
2350
+
2351
+ # Repository Health (Informational)
2352
+ if [ "$HEALTH_STATUS" = "success" ]; then
2353
+ echo "| 🏥 Repository Health | ✅ Pass | Health check passed | ℹ️ Info |" >> $GITHUB_STEP_SUMMARY
2354
+ else
2355
+ echo "| 🏥 Repository Health | ℹ️ Info | Review recommendations | ℹ️ Info |" >> $GITHUB_STEP_SUMMARY
2356
+ fi
2357
+
2358
+ echo "" >> $GITHUB_STEP_SUMMARY
2359
+
2360
+ # Action items summary
2361
+ if [ "$FAILED" -gt 0 ]; then
2362
+ echo "## ⚡ Action Items" >> $GITHUB_STEP_SUMMARY
2363
+ echo "" >> $GITHUB_STEP_SUMMARY
2364
+ echo "**$FAILED validation area(s) require attention:**" >> $GITHUB_STEP_SUMMARY
2365
+ echo "" >> $GITHUB_STEP_SUMMARY
2366
+
2367
+ [ "$REPO_STATUS" != "success" ] && echo "- 🔴 **Critical:** Fix repository structure issues" >> $GITHUB_STEP_SUMMARY
2368
+ [ "$DOCS_STATUS" != "success" ] && echo "- 🔴 **Critical:** Improve documentation quality" >> $GITHUB_STEP_SUMMARY
2369
+ [ "$LICENSE_STATUS" != "success" ] && echo "- 🔴 **Critical:** Resolve license compliance issues" >> $GITHUB_STEP_SUMMARY
2370
+ [ "$CODE_STATUS" != "success" ] && echo "- 🟡 **Medium:** Review coding standards violations" >> $GITHUB_STEP_SUMMARY
2371
+ [ "$GIT_STATUS" != "success" ] && echo "- 🟡 **Medium:** Address git repository hygiene items" >> $GITHUB_STEP_SUMMARY
2372
+ [ "$WORKFLOW_STATUS" != "success" ] && echo "- 🟡 **Medium:** Review workflow configuration" >> $GITHUB_STEP_SUMMARY
2373
+
2374
+ echo "" >> $GITHUB_STEP_SUMMARY
2375
+ echo "**Next Steps:**" >> $GITHUB_STEP_SUMMARY
2376
+ echo "1. Review detailed results in individual job outputs above" >> $GITHUB_STEP_SUMMARY
2377
+ echo "2. Follow remediation steps provided for each failure" >> $GITHUB_STEP_SUMMARY
2378
+ echo "3. Re-run this workflow after making corrections" >> $GITHUB_STEP_SUMMARY
2379
+ echo "4. Reach 100% compliance before merging" >> $GITHUB_STEP_SUMMARY
2380
+ else
2381
+ echo "## 🎉 Excellent!" >> $GITHUB_STEP_SUMMARY
2382
+ echo "" >> $GITHUB_STEP_SUMMARY
2383
+ echo "Your repository is **fully compliant** with MokoCLI!" >> $GITHUB_STEP_SUMMARY
2384
+ echo "" >> $GITHUB_STEP_SUMMARY
2385
+ echo "**Achievements:**" >> $GITHUB_STEP_SUMMARY
2386
+ echo "- ✅ All required directories and files present" >> $GITHUB_STEP_SUMMARY
2387
+ echo "- ✅ Documentation meets quality standards" >> $GITHUB_STEP_SUMMARY
2388
+ echo "- ✅ Coding standards followed" >> $GITHUB_STEP_SUMMARY
2389
+ echo "- ✅ License compliance verified" >> $GITHUB_STEP_SUMMARY
2390
+ echo "- ✅ Git repository well-maintained" >> $GITHUB_STEP_SUMMARY
2391
+ echo "- ✅ Workflows properly configured" >> $GITHUB_STEP_SUMMARY
2392
+ fi
2393
+
2394
+ echo "" >> $GITHUB_STEP_SUMMARY
2395
+ echo "---" >> $GITHUB_STEP_SUMMARY
2396
+ echo "" >> $GITHUB_STEP_SUMMARY
2397
+ echo "📚 **Resources:**" >> $GITHUB_STEP_SUMMARY
2398
+ echo "- [MokoCLI Documentation](https://github.com/mokoconsulting-tech/mokocli)" >> $GITHUB_STEP_SUMMARY
2399
+ echo "- [Repository Structure Guide](https://github.com/mokoconsulting-tech/mokocli/tree/main/docs/policy/core-structure.md)" >> $GITHUB_STEP_SUMMARY
2400
+ echo "- [Documentation Standards](https://github.com/mokoconsulting-tech/mokocli/tree/main/docs/policy/document-formatting.md)" >> $GITHUB_STEP_SUMMARY
2401
+ echo "- [Coding Standards](https://github.com/mokoconsulting-tech/mokocli/tree/main/docs/policy/coding-style-guide.md)" >> $GITHUB_STEP_SUMMARY
2402
+ echo "" >> $GITHUB_STEP_SUMMARY
2403
+ echo "_Generated by MokoCLI Compliance Workflow v${WORKFLOW_VERSION}_" >> $GITHUB_STEP_SUMMARY
2404
+
2405
+ # Create tracking issue for non-compliance if on push
2406
+ if [ "$COMPLIANCE_PERCENT" -lt 100 ] && [ "${{ github.event_name }}" = "push" ]; then
2407
+ echo "Creating tracking issue for standards violations..."
2408
+ fi
2409
+
2410
+ # Exit with error if not fully compliant
2411
+ if [ "$COMPLIANCE_PERCENT" -lt 100 ]; then
2412
+ echo "" >> $GITHUB_STEP_SUMMARY
2413
+ echo "### ❌ Standards Compliance Failed" >> $GITHUB_STEP_SUMMARY
2414
+ echo "" >> $GITHUB_STEP_SUMMARY
2415
+ echo "**Overall Compliance:** $COMPLIANCE_PERCENT%" >> $GITHUB_STEP_SUMMARY
2416
+ echo "**Status:** Repository does not meet 100% compliance requirement" >> $GITHUB_STEP_SUMMARY
2417
+ echo "**Action Required:** Review and fix all validation failures above" >> $GITHUB_STEP_SUMMARY
2418
+ echo ""
2419
+ echo "❌ ERROR: Standards compliance at $COMPLIANCE_PERCENT% - 100% required"
2420
+ exit 1
2421
+ fi
2422
+
2423
+ echo "" >> $GITHUB_STEP_SUMMARY
2424
+ echo "### ✅ Full Standards Compliance Achieved" >> $GITHUB_STEP_SUMMARY
2425
+ echo "" >> $GITHUB_STEP_SUMMARY
2426
+ echo "**Overall Compliance:** 100%" >> $GITHUB_STEP_SUMMARY
2427
+ echo "**Status:** Repository meets all MokoCLI requirements" >> $GITHUB_STEP_SUMMARY
2428
+ echo ""
2429
+ echo "✅ SUCCESS: Repository is fully MokoCLI compliant"
2430
+
2431
+ - name: Create or reopen tracking issue for standards violations
2432
+ if: failure()
2433
+ env:
2434
+ GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
2435
+ run: |
2436
+ REPO="${{ github.repository }}"
2437
+ RUN_URL="${{ github.server_url }}/${REPO}/actions/runs/${{ github.run_id }}"
2438
+ DATE=$(date -u '+%Y-%m-%d')
2439
+ SHA="${{ github.sha }}"
2440
+ ACTOR="${{ github.actor }}"
2441
+ BRANCH="${{ github.ref_name }}"
2442
+
2443
+ # Collect failed checks
2444
+ FAILED=""
2445
+ [ "${{ needs.repository-structure.result }}" != "success" ] && FAILED="${FAILED}\n- Repository Structure"
2446
+ [ "${{ needs.documentation-quality.result }}" != "success" ] && FAILED="${FAILED}\n- Documentation Quality"
2447
+ [ "${{ needs.coding-standards.result }}" != "success" ] && FAILED="${FAILED}\n- Coding Standards"
2448
+ [ "${{ needs.license-compliance.result }}" != "success" ] && FAILED="${FAILED}\n- License Compliance"
2449
+ [ "${{ needs.git-hygiene.result }}" != "success" ] && FAILED="${FAILED}\n- Git Hygiene"
2450
+ [ "${{ needs.workflow-validation.result }}" != "success" ] && FAILED="${FAILED}\n- Workflow Validation"
2451
+ [ "${{ needs.version-consistency.result }}" != "success" ] && FAILED="${FAILED}\n- Version Consistency"
2452
+ [ "${{ needs.script-integrity.result }}" != "success" ] && FAILED="${FAILED}\n- Script Integrity"
2453
+ [ "${{ needs.line-length-validation.result }}" != "success" ] && FAILED="${FAILED}\n- Line Length"
2454
+ [ "${{ needs.file-size-limits.result }}" != "success" ] && FAILED="${FAILED}\n- File Size Limits"
2455
+ [ "${{ needs.readme-completeness.result }}" != "success" ] && FAILED="${FAILED}\n- README Completeness"
2456
+
2457
+ if [ -z "$FAILED" ]; then
2458
+ echo "No failed checks to report"
2459
+ exit 0
2460
+ fi
2461
+
2462
+ TITLE="[Standards] Compliance violations — ${DATE}"
2463
+ BODY="## Standards Compliance Violations
2464
+
2465
+ | Field | Value |
2466
+ |-------|-------|
2467
+ | **Branch** | \`${BRANCH}\` |
2468
+ | **Commit** | \`${SHA:0:7}\` |
2469
+ | **Actor** | @${ACTOR} |
2470
+ | **Run** | [View workflow](${RUN_URL}) |
2471
+
2472
+ ### Failed Checks
2473
+ $(printf '%b' "$FAILED")
2474
+
2475
+ ### Required Actions
2476
+ 1. Review the [workflow run](${RUN_URL}) for details
2477
+ 2. Fix each failed check
2478
+ 3. Push to trigger a new scan
2479
+
2480
+ ---
2481
+ *Auto-created by standards-compliance workflow*"
2482
+
2483
+ BODY=$(echo "$BODY" | sed 's/^ //')
2484
+ LABEL="standards-violation"
2485
+
2486
+ gh label create "$LABEL" --repo "$REPO" --color "D73A4A" --description "Standards compliance failure" --force 2>/dev/null || true
2487
+
2488
+ EXISTING=$(gh api "repos/${REPO}/issues?labels=${LABEL}&state=all&per_page=1&sort=created&direction=desc" \
2489
+ --jq '.[0].number' 2>/dev/null)
2490
+
2491
+ if [ -n "$EXISTING" ] && [ "$EXISTING" != "null" ]; then
2492
+ gh api "repos/${REPO}/issues/${EXISTING}" -X PATCH \
2493
+ -f title="$TITLE" -f body="$BODY" -f state="open" --silent
2494
+ echo "Updated issue #${EXISTING}"
2495
+ else
2496
+ gh issue create --repo "$REPO" --title "$TITLE" --body "$BODY" \
2497
+ --label "$LABEL" --assignee "jmiller"
2498
+ fi
2499
+
2500
+ # CUSTOMIZATION:
2501
+ #
2502
+ # 1. Adjust severity of checks (convert warnings to errors or vice versa)
2503
+ # 2. Add project-specific validation rules
2504
+ # 3. Integrate with custom linting tools
2505
+ # 4. Add notification steps for compliance failures
2506
+ # 5. Customize required files/directories for your project type
2507
+