@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.
- package/.gitattributes +94 -0
- package/.gitmessage +9 -0
- package/.mokogitea/ISSUE_TEMPLATE/adr.md +110 -0
- package/.mokogitea/ISSUE_TEMPLATE/bug_report.md +48 -0
- package/.mokogitea/ISSUE_TEMPLATE/config.yml +18 -0
- package/.mokogitea/ISSUE_TEMPLATE/documentation.md +52 -0
- package/.mokogitea/ISSUE_TEMPLATE/enterprise_support.md +85 -0
- package/.mokogitea/ISSUE_TEMPLATE/feature_request.md +51 -0
- package/.mokogitea/ISSUE_TEMPLATE/firewall-request.md +190 -0
- package/.mokogitea/ISSUE_TEMPLATE/mcp_api_integration.md +48 -0
- package/.mokogitea/ISSUE_TEMPLATE/mcp_connection_issue.md +67 -0
- package/.mokogitea/ISSUE_TEMPLATE/mcp_tool_request.md +49 -0
- package/.mokogitea/ISSUE_TEMPLATE/question.md +82 -0
- package/.mokogitea/ISSUE_TEMPLATE/rfc.md +126 -0
- package/.mokogitea/ISSUE_TEMPLATE/security.md +51 -0
- package/.mokogitea/ISSUE_TEMPLATE/version.md +24 -0
- package/.mokogitea/auto-assign.yml +76 -0
- package/.mokogitea/auto-dev-issue.yml +207 -0
- package/.mokogitea/auto-release.yml +337 -0
- package/.mokogitea/branch-protection.yml +251 -0
- package/.mokogitea/changelog-validation.yml +101 -0
- package/.mokogitea/codeql-analysis.yml +115 -0
- package/.mokogitea/copilot-agent.yml +44 -0
- package/.mokogitea/deploy-demo.yml +734 -0
- package/.mokogitea/deploy-dev.yml +700 -0
- package/.mokogitea/enterprise-firewall-setup.yml +758 -0
- package/.mokogitea/manifest.xml +25 -0
- package/.mokogitea/mcp-auto-release.yml +278 -0
- package/.mokogitea/mcp-build-test.yml +65 -0
- package/.mokogitea/mcp-sdk-check.yml +109 -0
- package/.mokogitea/mcp-tool-inventory.yml +61 -0
- package/.mokogitea/pr-branch-check.yml +90 -0
- package/.mokogitea/repository-cleanup.yml +525 -0
- package/.mokogitea/standards-compliance.yml +2614 -0
- package/.mokogitea/sync-version-on-merge.yml +133 -0
- package/.mokogitea/workflows/auto-assign.yml +76 -0
- package/.mokogitea/workflows/auto-bump.yml +66 -0
- package/.mokogitea/workflows/auto-dev-issue.yml +207 -0
- package/.mokogitea/workflows/auto-release.yml +341 -0
- package/.mokogitea/workflows/branch-cleanup.yml +48 -0
- package/.mokogitea/workflows/cascade-dev.yml +10 -0
- package/.mokogitea/workflows/changelog-validation.yml +101 -0
- package/.mokogitea/workflows/ci-generic.yml +204 -0
- package/.mokogitea/workflows/cleanup.yml +87 -0
- package/.mokogitea/workflows/codeql-analysis.yml +115 -0
- package/.mokogitea/workflows/copilot-agent.yml +44 -0
- package/.mokogitea/workflows/deploy-manual.yml +126 -0
- package/.mokogitea/workflows/enterprise-firewall-setup.yml +758 -0
- package/.mokogitea/workflows/gitleaks.yml +96 -0
- package/.mokogitea/workflows/issue-branch.yml +73 -0
- package/.mokogitea/workflows/mcp-auto-release.yml +280 -0
- package/.mokogitea/workflows/mcp-build-test.yml +65 -0
- package/.mokogitea/workflows/mcp-sdk-check.yml +109 -0
- package/.mokogitea/workflows/mcp-tool-inventory.yml +61 -0
- package/.mokogitea/workflows/notify.yml +70 -0
- package/.mokogitea/workflows/npm-publish.yml +51 -0
- package/.mokogitea/workflows/pr-check.yml +508 -0
- package/.mokogitea/workflows/pre-release.yml +11 -0
- package/.mokogitea/workflows/repo-health.yml +711 -0
- package/.mokogitea/workflows/repository-cleanup.yml +525 -0
- package/.mokogitea/workflows/security-audit.yml +82 -0
- package/.mokogitea/workflows/standards-compliance.yml +2614 -0
- package/.mokogitea/workflows/sync-version-on-merge.yml +130 -0
- package/.mokogitea/workflows/update-server.yml +312 -0
- package/CHANGELOG.md +145 -0
- package/CLAUDE.md +43 -0
- package/CONTRIBUTING.md +161 -0
- package/README.md +286 -0
- package/SECURITY.md +91 -0
- package/automation/ci-issue-reporter.sh +237 -0
- package/config.example.json +13 -0
- package/dist/client.d.ts +15 -0
- package/dist/client.js +104 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.js +48 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1119 -0
- package/dist/types.d.ts +20 -0
- package/dist/types.js +16 -0
- package/package.json +34 -0
- package/scripts/setup.mjs +40 -0
- package/src/client.ts +120 -0
- package/src/config.ts +58 -0
- package/src/index.ts +1712 -0
- package/src/types.ts +37 -0
- 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
|
+
|