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