diff --git a/.github/workflows/standards-compliance.yml b/.github/workflows/standards-compliance.yml
index a1ad082..2a091c7 100644
--- a/.github/workflows/standards-compliance.yml
+++ b/.github/workflows/standards-compliance.yml
@@ -5,16 +5,41 @@
# INGROUP: MokoStandards.Compliance
# REPO: https://github.com/mokoconsulting-tech/MokoStandards
# PATH: /.github/workflows/standards-compliance.yml
-# VERSION: 04.01.00
+# VERSION: 04.02.30
# BRIEF: MokoStandards compliance validation workflow
# NOTE: Validates repository structure, documentation, and coding standards
name: Standards Compliance
+# ╔════════════════════════════════════════════════════════════════════════╗
+# ║ MOKOSTANDARDS COMPLIANCE WORKFLOW ║
+# ╠════════════════════════════════════════════════════════════════════════╣
+# ║ ║
+# ║ 28 checks across 4 priority tiers: ║
+# ║ ║
+# ║ TIER 1 — CRITICAL (must pass) ║
+# ║ secret-scanning, license-compliance, repository-structure, ║
+# ║ coding-standards, version-consistency ║
+# ║ ║
+# ║ TIER 2 — IMPORTANT (should pass) ║
+# ║ workflow-validation, documentation-quality, readme-completeness, ║
+# ║ git-hygiene, script-integrity ║
+# ║ ║
+# ║ TIER 3 — QUALITY (code metrics) ║
+# ║ line-length, file-naming, insecure-patterns, complexity, ║
+# ║ duplication, dead-code ║
+# ║ ║
+# ║ TIER 4 — SUPPLEMENTARY (informational) ║
+# ║ file-size, binary, todo, deps, links, api-docs, accessibility, ║
+# ║ performance, enterprise, health, terraform ║
+# ║ ║
+# ║ File size: warning >15MB, critical >20MB ║
+# ║ Exempt: .mmdb, .woff2, .woff, .ttf, .otf ║
+# ║ ║
+# ╚════════════════════════════════════════════════════════════════════════╝
+
env:
- ACTIONS_STEP_DEBUG: true
- ACTIONS_RUNNER_DEBUG: true
- WORKFLOW_VERSION: "04.00.05"
+ WORKFLOW_VERSION: "04.02.12"
# MokoStandards Policy Compliance:
# - File formatting: Enforces organizational coding standards
@@ -63,22 +88,191 @@ env:
on:
push:
- branches:
- - main
- - dev/**
- - rc/**
+ branches: [main, dev/**, rc/**, version/**]
pull_request:
- branches:
- - main
- - dev/**
- - rc/**
+ branches: [main, dev/**, rc/**]
workflow_dispatch:
permissions:
contents: read
pull-requests: write
+ issues: write
+
+env:
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
+ # ════════════════════════════════════════════════════════════════════════
+ # TIER 1 — CRITICAL (must pass, blocks merge)
+ # ════════════════════════════════════════════════════════════════════════
+ secret-scanning:
+ name: Secret Scanning
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Scan for Secrets
+ run: |
+ set -x
+ echo "## 🔒 Secret Scanning" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "Scanning for hardcoded secrets and credentials." >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Define secret patterns
+ VIOLATIONS=0
+
+ # Check for common secret patterns
+ echo "### Secret Patterns" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Helper: scan with a pattern, show results with file:line, return count
+ scan_pattern() {
+ local label="$1" icon="$2" tmpfile="$3"
+ local count=0
+ if [ -f "$tmpfile" ]; then
+ count=$(wc -l < "$tmpfile")
+ fi
+ if [ "$count" -gt 0 ]; then
+ echo "${icon} **${label}**: ${count} finding(s)" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View locations
" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "| File | Line | Match |" >> $GITHUB_STEP_SUMMARY
+ echo "|------|------|-------|" >> $GITHUB_STEP_SUMMARY
+ head -20 "$tmpfile" | while IFS= read -r line; do
+ FILE=$(echo "$line" | cut -d: -f1 | sed 's|^\./||')
+ LINENO=$(echo "$line" | cut -d: -f2)
+ MATCH=$(echo "$line" | cut -d: -f3- | head -c 80 | sed 's/|/\\|/g')
+ echo "| \`${FILE}\` | ${LINENO} | \`${MATCH}\` |" >> $GITHUB_STEP_SUMMARY
+ done
+ if [ "$count" -gt 20 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "*... and $((count - 20)) more*" >> $GITHUB_STEP_SUMMARY
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ VIOLATIONS=$((VIOLATIONS + count))
+ fi
+ }
+
+ # Pattern 1: password/secret assignments
+ grep -r -n -E "(password|passwd|pwd|secret|api[_-]?key|token).*=.*['\"]" . \
+ --include="*.php" --include="*.py" --include="*.js" --include="*.ts" \
+ --exclude-dir=".git" --exclude-dir="vendor" --exclude-dir="node_modules" 2>/dev/null | \
+ grep -v -E '(test|example|sample|getenv|getString|getArgument|config\[|/\.\*/|^\s*//|^\s*\*|CREDENTIAL_PATTERNS|SecurityValidator|SECRET_PATTERN|===|!==|ApiClient|str_contains|gen_wrappers)' | \
+ grep -v "= ''" | grep -v '= ""' | grep -v '\$this->config' > /tmp/secrets1.txt 2>/dev/null || true
+ scan_pattern "Secret assignments" "⚠️" /tmp/secrets1.txt
+
+ # Pattern 2: Private keys
+ grep -r -n "BEGIN.*PRIVATE KEY" . \
+ --include="*.pem" --include="*.key" --include="*.txt" \
+ --exclude-dir=".git" --exclude-dir="vendor" --exclude-dir="node_modules" 2>/dev/null > /tmp/secrets2.txt || true
+ scan_pattern "Private keys" "❌" /tmp/secrets2.txt
+
+ # Pattern 3: AWS keys
+ grep -r -n -E "AKIA[0-9A-Z]{16}" . \
+ --include="*.php" --include="*.py" --include="*.js" --include="*.txt" --include="*.env" \
+ --exclude-dir=".git" --exclude-dir="vendor" --exclude-dir="node_modules" 2>/dev/null > /tmp/secrets3.txt || true
+ scan_pattern "AWS access keys" "❌" /tmp/secrets3.txt
+
+ # Pattern 4: GitHub tokens
+ grep -r -n -E "gh[ps]_[a-zA-Z0-9]{36}" . \
+ --include="*.php" --include="*.py" --include="*.js" --include="*.txt" --include="*.env" \
+ --exclude-dir=".git" --exclude-dir="vendor" --exclude-dir="node_modules" 2>/dev/null > /tmp/secrets4.txt || true
+ scan_pattern "GitHub tokens" "❌" /tmp/secrets4.txt
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$VIOLATIONS" -gt 0 ]; then
+ echo "**Total Violations**: $VIOLATIONS" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View detected secrets (file paths only)
" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ cat /tmp/secrets*.txt 2>/dev/null | cut -d: -f1 | sort -u >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required**: Remove hardcoded secrets immediately!" >> $GITHUB_STEP_SUMMARY
+ echo "Use environment variables or secrets management instead." >> $GITHUB_STEP_SUMMARY
+ exit 1
+ else
+ echo "✅ No hardcoded secrets detected" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ license-compliance:
+ name: License Header Validation
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Check SPDX Headers
+ run: |
+ set -x
+ echo "### SPDX License Header Check" >> $GITHUB_STEP_SUMMARY
+
+ # Count source files with and without SPDX headers
+ TOTAL_PHP=0
+ WITH_SPDX_PHP=0
+
+ if find . -name "*.php" -type f ! -path "./vendor/*" | head -1 | grep -q .; then
+ TOTAL_PHP=$(find . -name "*.php" -type f ! -path "./vendor/*" | wc -l)
+ WITH_SPDX_PHP=$(find . -name "*.php" -type f ! -path "./vendor/*" -exec grep -l "SPDX-License-Identifier" {} \; | wc -l)
+ fi
+
+ if [ "$TOTAL_PHP" -gt 0 ]; then
+ PERCENT=$((WITH_SPDX_PHP * 100 / TOTAL_PHP))
+ echo "- PHP files: $WITH_SPDX_PHP/$TOTAL_PHP ($PERCENT%) with SPDX headers" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$PERCENT" -lt 80 ]; then
+ echo "⚠️ Less than 80% of PHP files have SPDX headers" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ Good SPDX header coverage" >> $GITHUB_STEP_SUMMARY
+ fi
+ fi
+
+ - name: Validate License File
+ run: |
+ set -x
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### License File Validation" >> $GITHUB_STEP_SUMMARY
+
+ if [ ! -f "LICENSE" ]; then
+ echo "❌ LICENSE file not found" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ❌ Validation Failed: LICENSE File Missing" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Error:** LICENSE file is required for all MokoStandards-compliant repositories" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required:** Add LICENSE file with appropriate open-source license (GPL-3.0-or-later recommended)" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "❌ ERROR: LICENSE file not found - This is a critical requirement"
+ exit 1
+ fi
+
+ # Check license type
+ if grep -qi "GNU GENERAL PUBLIC LICENSE" LICENSE; then
+ VERSION=$(grep -i "Version 3" LICENSE || echo "")
+ if [ -n "$VERSION" ]; then
+ echo "✅ GPL-3.0-or-later license detected" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "⚠️ GPL license detected but version unclear" >> $GITHUB_STEP_SUMMARY
+ fi
+ elif grep -qi "MIT License" LICENSE; then
+ echo "✅ MIT license detected" >> $GITHUB_STEP_SUMMARY
+ elif grep -qi "Apache License" LICENSE; then
+ echo "✅ Apache license detected" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "ℹ️ License type could not be automatically detected" >> $GITHUB_STEP_SUMMARY
+ fi
+
repository-structure:
name: Repository Structure Validation
runs-on: ubuntu-latest
@@ -206,6 +400,387 @@ jobs:
exit 1
fi
+ coding-standards:
+ name: Coding Standards Check
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Check for Tab Characters
+ run: |
+ set -x
+ echo "### Tab Character Detection" >> $GITHUB_STEP_SUMMARY
+
+ # Policy: Tabs are DEFAULT. Only check for tabs in files that REQUIRE spaces.
+ # Languages requiring spaces: YAML, Python, Haskell, F#, CoffeeScript, Nim, JSON, RST
+ TABS_IN_SPACES_FILES=$(find . -type f \
+ \( -name "*.yml" -o -name "*.yaml" \
+ -o -name "*.py" \
+ -o -name "*.hs" -o -name "*.lhs" \
+ -o -name "*.fs" -o -name "*.fsx" -o -name "*.fsi" \
+ -o -name "*.coffee" -o -name "*.litcoffee" \
+ -o -name "*.nim" -o -name "*.nims" -o -name "*.nimble" \
+ -o -name "*.json" \
+ -o -name "*.rst" \) \
+ ! -path "./vendor/*" \
+ ! -path "./node_modules/*" \
+ ! -path "./.git/*" \
+ -exec grep -l $'\t' {} \; 2>/dev/null | head -10)
+
+ if [ -n "$TABS_IN_SPACES_FILES" ]; then
+ echo "⚠️ Tab characters found in files that require spaces:" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "$TABS_IN_SPACES_FILES" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "These languages require spaces (tabs will break): YAML, Python, Haskell, F#, CoffeeScript, Nim, JSON, RST" >> $GITHUB_STEP_SUMMARY
+ echo "All other files (including .md, .ps1, LICENSE, etc.) may use tabs per MokoStandards policy" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ No tabs found in files requiring spaces" >> $GITHUB_STEP_SUMMARY
+ echo "Note: Tabs are allowed in most files (policy default). Only checked files requiring spaces." >> $GITHUB_STEP_SUMMARY
+ fi
+
+ - name: Check File Encoding
+ run: |
+ set -x
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### File Encoding Check" >> $GITHUB_STEP_SUMMARY
+
+ # Check for UTF-8 encoding (ASCII is a subset of UTF-8 and is acceptable)
+ NON_UTF8=$(find . -type f \( -name "*.php" -o -name "*.js" -o -name "*.md" \) \
+ ! -path "./vendor/*" \
+ ! -path "./node_modules/*" \
+ ! -path "./.git/*" \
+ -exec file {} \; | grep -v "UTF-8" | grep -v "ASCII" | head -5)
+
+ if [ -n "$NON_UTF8" ]; then
+ echo "⚠️ Non-UTF-8 files detected:" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "$NON_UTF8" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ All source files appear to be UTF-8 encoded" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ - name: Check Line Endings
+ run: |
+ set -x
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### Line Ending Check" >> $GITHUB_STEP_SUMMARY
+
+ # Check for CRLF line endings
+ CRLF_FILES=$(find . -type f \( -name "*.php" -o -name "*.js" -o -name "*.md" \) \
+ ! -path "./vendor/*" \
+ ! -path "./node_modules/*" \
+ ! -path "./.git/*" \
+ -exec file {} \; | grep "CRLF" | head -5)
+
+ if [ -n "$CRLF_FILES" ]; then
+ echo "⚠️ Files with CRLF line endings found:" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "$CRLF_FILES" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "MokoStandards requires LF line endings" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ Line endings are consistent (LF)" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ version-consistency:
+ name: Version Consistency Check
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Set up PHP
+ uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.31.0
+ with:
+ php-version: '8.1'
+ extensions: json
+ tools: composer
+ coverage: none
+
+ - name: Install API Package
+ run: composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
+ env:
+ COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN }}"}}'
+
+ - name: Run Version Consistency Check
+ id: version_check
+ run: |
+ set -x
+ echo "## 🔢 Version Consistency Validation" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Use PHP enterprise library for version consistency check
+ if [ -f "vendor/bin/moko" ]; then
+ php vendor/bin/moko check:version -- --path . --verbose 2>&1 | tee /tmp/version-check.log
+ EXIT_CODE=${PIPESTATUS[0]}
+ elif [ -f "/tmp/mokostandards/api/validate/check_version_consistency.php" ]; then
+ php /tmp/mokostandards/api/validate/check_version_consistency.php --path . --verbose 2>&1 | tee /tmp/version-check.log
+ EXIT_CODE=${PIPESTATUS[0]}
+ elif [ -f "api/validate/check_version_consistency.php" ]; then
+ php api/validate/check_version_consistency.php --path . --verbose 2>&1 | tee /tmp/version-check.log
+ EXIT_CODE=${PIPESTATUS[0]}
+ else
+ echo "⏭️ Install mokoconsulting-tech/enterprise via Composer for version checks" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ fi
+
+ echo '```' >> $GITHUB_STEP_SUMMARY
+ cat /tmp/version-check.log >> $GITHUB_STEP_SUMMARY
+ echo '```' >> $GITHUB_STEP_SUMMARY
+
+ if [ "$EXIT_CODE" -eq 0 ]; then
+ echo "✅ All version numbers are consistent" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "❌ Version drift detected" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ fi
+
+
+ # ════════════════════════════════════════════════════════════════════════
+ # TIER 2 — IMPORTANT (should pass)
+ # ════════════════════════════════════════════════════════════════════════
+ workflow-validation:
+ name: Workflow Configuration Check
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Check Required Workflows
+ run: |
+ set -x
+ echo "### GitHub Actions Workflows" >> $GITHUB_STEP_SUMMARY
+
+ WORKFLOWS_DIR=".github/workflows"
+
+ if [ ! -d "$WORKFLOWS_DIR" ]; then
+ echo "❌ No workflows directory found" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ❌ Validation Failed: Workflows Directory Missing" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Error:** .github/workflows directory is required for CI/CD automation" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required:** Create .github/workflows directory and add GitHub Actions workflows" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "❌ ERROR: .github/workflows directory not found"
+ exit 1
+ fi
+
+ # Check for recommended workflows
+ CI_FOUND=false
+ for wf in ci.yml build.yml ci-dolibarr.yml ci-joomla.yml; do
+ if [ -f "$WORKFLOWS_DIR/$wf" ]; then
+ echo "✅ CI workflow present ($wf)" >> $GITHUB_STEP_SUMMARY
+ CI_FOUND=true
+ break
+ fi
+ done
+ if [ "$CI_FOUND" = "false" ]; then
+ echo "⚠️ No CI workflow found (ci.yml, build.yml, ci-dolibarr.yml, or ci-joomla.yml)" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ if [ -f "$WORKFLOWS_DIR/codeql-analysis.yml" ]; then
+ echo "✅ CodeQL security scanning present" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "⚠️ CodeQL workflow not found" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Check for MokoStandards-synced workflows
+ 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
+ if [ -f "$WORKFLOWS_DIR/$wf" ]; then
+ echo "✅ ${wf}" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "⚠️ ${wf} not found (synced from MokoStandards)" >> $GITHUB_STEP_SUMMARY
+ fi
+ done
+
+ - name: Validate Workflow Syntax
+ run: |
+ set -x
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### Workflow YAML Syntax" >> $GITHUB_STEP_SUMMARY
+
+ INVALID=0
+ for workflow in $(find .github/workflows -maxdepth 1 -type f \( -name "*.yml" -o -name "*.yaml" \) 2>/dev/null); do
+ if [ -f "$workflow" ]; then
+ if python3 -c "import yaml, sys; yaml.safe_load(open(sys.argv[1]))" "$workflow" 2>/dev/null; then
+ echo "✅ $(basename $workflow)" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "❌ $(basename $workflow) - invalid YAML" >> $GITHUB_STEP_SUMMARY
+ INVALID=$((INVALID + 1))
+ fi
+ fi
+ done
+
+ if [ "$INVALID" -gt 0 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ❌ Validation Failed: Invalid Workflow YAML Syntax" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Error:** $INVALID workflow file(s) have invalid YAML syntax" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required:** Fix YAML syntax errors in the marked workflow files" >> $GITHUB_STEP_SUMMARY
+ echo "**Tool:** Run \`python3 -c \"import yaml; yaml.safe_load(open('.github/workflows/FILE.yml'))\"\` locally" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "❌ ERROR: $INVALID workflow file(s) with invalid YAML syntax"
+ exit 1
+ fi
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ✅ All Workflow Files Have Valid YAML Syntax" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "✅ SUCCESS: All workflow files passed YAML validation"
+
+ - name: Validate CodeQL Configuration
+ if: hashFiles('.github/workflows/codeql-analysis.yml') != ''
+ run: |
+ set -e
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### CodeQL Language Configuration" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Inline validation (rewritten from Python to bash for PHP-only architecture)
+ CODEQL_FILE=".github/workflows/codeql-analysis.yml"
+
+ if [ ! -f "$CODEQL_FILE" ]; then
+ echo "⚠️ CodeQL workflow file not found" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ⚠️ CodeQL Workflow Not Found" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Status:** CodeQL workflow file not present - skipping language validation" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "⚠️ INFO: CodeQL workflow not found - Skipping validation"
+ exit 0
+ fi
+
+ echo "**CodeQL Configuration Analysis**" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Extract configured languages from workflow
+ LANGUAGES=$(grep -A5 "language:" "$CODEQL_FILE" | grep -oP "(?<=')[^']+(?=')" | tr '\n' ' ' || echo "")
+
+ # Check if this is a configuration-only scan (no languages specified)
+ if grep -q "category.*language:config" "$CODEQL_FILE"; then
+ echo "**Scan Type:** Configuration-only (no language matrix)" >> $GITHUB_STEP_SUMMARY
+ echo "**Status:** ✅ Valid configuration for PHP-only repository" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "This CodeQL workflow scans YAML, JSON, shell scripts for security issues." >> $GITHUB_STEP_SUMMARY
+ echo "PHP security is handled by SecurityValidator enterprise library." >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "✅ SUCCESS: CodeQL configuration-only scan properly configured"
+ exit 0
+ fi
+
+ if [ -z "$LANGUAGES" ]; then
+ echo "❌ No languages configured in CodeQL workflow" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ❌ Validation Failed: CodeQL Languages Not Configured" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Error:** CodeQL workflow exists but has no languages configured" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required:** Configure appropriate languages in codeql-analysis.yml" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "❌ ERROR: No languages configured in CodeQL workflow"
+ exit 1
+ fi
+
+ echo "**Configured Languages:** $LANGUAGES" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Validate language presence in repository
+ INVALID_LANGS=""
+ VALID_LANGS=""
+
+ for LANG in $LANGUAGES; do
+ case "$LANG" in
+ python)
+ # Check for Python files (should be none in v04.00.04)
+ if find . -name "*.py" -type f ! -path "./.git/*" | grep -q .; then
+ VALID_LANGS="$VALID_LANGS python"
+ echo "✅ Python: Found Python files" >> $GITHUB_STEP_SUMMARY
+ else
+ INVALID_LANGS="$INVALID_LANGS python"
+ echo "❌ Python: No Python files found (PHP-only repository)" >> $GITHUB_STEP_SUMMARY
+ fi
+ ;;
+ javascript|typescript)
+ # Check for JS/TS files
+ if find . \( -name "*.js" -o -name "*.ts" -o -name "*.json" \) -type f ! -path "./.git/*" ! -path "./node_modules/*" | grep -q .; then
+ VALID_LANGS="$VALID_LANGS $LANG"
+ echo "✅ $LANG: Found JavaScript/TypeScript/JSON files" >> $GITHUB_STEP_SUMMARY
+ else
+ INVALID_LANGS="$INVALID_LANGS $LANG"
+ echo "⚠️ $LANG: No JavaScript/TypeScript files found" >> $GITHUB_STEP_SUMMARY
+ fi
+ ;;
+ java)
+ if find . -name "*.java" -type f ! -path "./.git/*" | grep -q .; then
+ VALID_LANGS="$VALID_LANGS java"
+ echo "✅ Java: Found Java files" >> $GITHUB_STEP_SUMMARY
+ else
+ INVALID_LANGS="$INVALID_LANGS java"
+ echo "⚠️ Java: No Java files found" >> $GITHUB_STEP_SUMMARY
+ fi
+ ;;
+ go)
+ if find . -name "*.go" -type f ! -path "./.git/*" | grep -q .; then
+ VALID_LANGS="$VALID_LANGS go"
+ echo "✅ Go: Found Go files" >> $GITHUB_STEP_SUMMARY
+ else
+ INVALID_LANGS="$INVALID_LANGS go"
+ echo "⚠️ Go: No Go files found" >> $GITHUB_STEP_SUMMARY
+ fi
+ ;;
+ cpp|c)
+ if find . \( -name "*.cpp" -o -name "*.c" -o -name "*.h" \) -type f ! -path "./.git/*" | grep -q .; then
+ VALID_LANGS="$VALID_LANGS $LANG"
+ echo "✅ $LANG: Found C/C++ files" >> $GITHUB_STEP_SUMMARY
+ else
+ INVALID_LANGS="$INVALID_LANGS $LANG"
+ echo "⚠️ $LANG: No C/C++ files found" >> $GITHUB_STEP_SUMMARY
+ fi
+ ;;
+ ruby)
+ if find . -name "*.rb" -type f ! -path "./.git/*" | grep -q .; then
+ VALID_LANGS="$VALID_LANGS ruby"
+ echo "✅ Ruby: Found Ruby files" >> $GITHUB_STEP_SUMMARY
+ else
+ INVALID_LANGS="$INVALID_LANGS ruby"
+ echo "⚠️ Ruby: No Ruby files found" >> $GITHUB_STEP_SUMMARY
+ fi
+ ;;
+ *)
+ echo "⚠️ $LANG: Unknown language, skipping validation" >> $GITHUB_STEP_SUMMARY
+ ;;
+ esac
+ done
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Report results
+ if [ -n "$INVALID_LANGS" ]; then
+ echo "**⚠️ Warning:** Some configured languages may not have corresponding files:" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "Invalid languages: $INVALID_LANGS" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Note:** This is informational. CodeQL will skip languages without source files." >> $GITHUB_STEP_SUMMARY
+ echo "For PHP repository (v04.00.04), JavaScript language covers JSON/YAML/shell scripts." >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ **All configured CodeQL languages have corresponding source files**" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # Always succeed - this is informational only
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ✅ CodeQL Configuration Validation Complete" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Status:** CodeQL language configuration reviewed successfully" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "✅ SUCCESS: CodeQL validation complete"
+ exit 0
+
documentation-quality:
name: Documentation Quality Check
runs-on: ubuntu-latest
@@ -407,92 +982,164 @@ jobs:
echo "⚠️ No documentation index (docs/index.md or docs/README.md)" >> $GITHUB_STEP_SUMMARY
fi
- coding-standards:
- name: Coding Standards Check
+ readme-completeness:
+ name: README Completeness Check
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- - name: Check for Tab Characters
+ - name: Check README Sections
run: |
set -x
- echo "### Tab Character Detection" >> $GITHUB_STEP_SUMMARY
+ echo "## 📄 README Completeness Check" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
- # Policy: Tabs are DEFAULT. Only check for tabs in files that REQUIRE spaces.
- # Languages requiring spaces: YAML, Python, Haskell, F#, CoffeeScript, Nim, JSON, RST
- TABS_IN_SPACES_FILES=$(find . -type f \
- \( -name "*.yml" -o -name "*.yaml" \
- -o -name "*.py" \
- -o -name "*.hs" -o -name "*.lhs" \
- -o -name "*.fs" -o -name "*.fsx" -o -name "*.fsi" \
- -o -name "*.coffee" -o -name "*.litcoffee" \
- -o -name "*.nim" -o -name "*.nims" -o -name "*.nimble" \
- -o -name "*.json" \
- -o -name "*.rst" \) \
- ! -path "./vendor/*" \
- ! -path "./node_modules/*" \
- ! -path "./.git/*" \
- -exec grep -l $'\t' {} \; 2>/dev/null | head -10)
-
- if [ -n "$TABS_IN_SPACES_FILES" ]; then
- echo "⚠️ Tab characters found in files that require spaces:" >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- echo "$TABS_IN_SPACES_FILES" >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- echo "These languages require spaces (tabs will break): YAML, Python, Haskell, F#, CoffeeScript, Nim, JSON, RST" >> $GITHUB_STEP_SUMMARY
- echo "All other files (including .md, .ps1, LICENSE, etc.) may use tabs per MokoStandards policy" >> $GITHUB_STEP_SUMMARY
- else
- echo "✅ No tabs found in files requiring spaces" >> $GITHUB_STEP_SUMMARY
- echo "Note: Tabs are allowed in most files (policy default). Only checked files requiring spaces." >> $GITHUB_STEP_SUMMARY
+ if [ ! -f "README.md" ]; then
+ echo "❌ README.md not found" >> $GITHUB_STEP_SUMMARY
+ exit 1
fi
- - name: Check File Encoding
+ # Required sections
+ REQUIRED_SECTIONS=("Installation" "Usage" "Contributing" "License")
+ MISSING=0
+ PRESENT=0
+
+ echo "### Required Sections" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ for section in "${REQUIRED_SECTIONS[@]}"; do
+ if grep -qi "##.*$section" README.md; then
+ echo "✅ $section" >> $GITHUB_STEP_SUMMARY
+ PRESENT=$((PRESENT + 1))
+ else
+ echo "❌ $section" >> $GITHUB_STEP_SUMMARY
+ MISSING=$((MISSING + 1))
+ fi
+ done
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Completeness**: $PRESENT/${#REQUIRED_SECTIONS[@]} required sections present" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$MISSING" -gt 0 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required**: Add missing sections to README.md" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ fi
+
+ # ============================================================================
+ # PHASE 3: Future Enhancements
+ # ============================================================================
+
+ git-hygiene:
+ name: Git Repository Hygiene
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+ with:
+ fetch-depth: 0
+
+ - name: Check .gitignore
+ run: |
+ set -x
+ echo "### .gitignore Validation" >> $GITHUB_STEP_SUMMARY
+
+ if [ ! -f ".gitignore" ]; then
+ echo "⚠️ .gitignore file not found" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "### ⚠️ Warning: .gitignore Not Found" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Status:** .gitignore file is recommended but not required" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation:** Add .gitignore to exclude build artifacts, dependencies, and temporary files" >> $GITHUB_STEP_SUMMARY
+ echo ""
+ echo "⚠️ WARNING: .gitignore file not found - Continuing validation"
+ exit 0
+ fi
+
+ # Check for common exclusions
+ MISSING=""
+ grep -q "vendor/" .gitignore || MISSING="${MISSING}vendor/ "
+ grep -q "node_modules/" .gitignore || MISSING="${MISSING}node_modules/ "
+
+ if [ -n "$MISSING" ]; then
+ echo "⚠️ .gitignore may be missing common exclusions: $MISSING" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ .gitignore appears complete" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ - name: Check for Large Files
run: |
set -x
echo "" >> $GITHUB_STEP_SUMMARY
- echo "### File Encoding Check" >> $GITHUB_STEP_SUMMARY
+ echo "### Large File Detection" >> $GITHUB_STEP_SUMMARY
- # Check for UTF-8 encoding (ASCII is a subset of UTF-8 and is acceptable)
- NON_UTF8=$(find . -type f \( -name "*.php" -o -name "*.js" -o -name "*.md" \) \
- ! -path "./vendor/*" \
- ! -path "./node_modules/*" \
- ! -path "./.git/*" \
- -exec file {} \; | grep -v "UTF-8" | grep -v "ASCII" | head -5)
+ # Find files larger than 1MB
+ LARGE_FILES=$(find . -type f -size +1M ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" | head -5)
- if [ -n "$NON_UTF8" ]; then
- echo "⚠️ Non-UTF-8 files detected:" >> $GITHUB_STEP_SUMMARY
+ if [ -n "$LARGE_FILES" ]; then
+ echo "⚠️ Large files detected (>1MB):" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- echo "$NON_UTF8" >> $GITHUB_STEP_SUMMARY
+ echo "$LARGE_FILES" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo "Consider using Git LFS for large binary files" >> $GITHUB_STEP_SUMMARY
else
- echo "✅ All source files appear to be UTF-8 encoded" >> $GITHUB_STEP_SUMMARY
+ echo "✅ No unusually large files detected" >> $GITHUB_STEP_SUMMARY
fi
- - name: Check Line Endings
+ script-integrity:
+ name: Script Integrity Validation
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Set up Python
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ with:
+ python-version: '3.x'
+
+ - name: Validate Script Integrity
+ id: script_check
run: |
set -x
+ echo "## 🔐 Script Integrity Validation" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
- echo "### Line Ending Check" >> $GITHUB_STEP_SUMMARY
- # Check for CRLF line endings
- CRLF_FILES=$(find . -type f \( -name "*.php" -o -name "*.js" -o -name "*.md" \) \
- ! -path "./vendor/*" \
- ! -path "./node_modules/*" \
- ! -path "./.git/*" \
- -exec file {} \; | grep "CRLF" | head -5)
+ if [ -f "api/.script-registry.json" ]; then
+ echo "### Critical Scripts" >> $GITHUB_STEP_SUMMARY
+ php api/maintenance/update_sha_hashes.php \
+ --dry-run --verbose | tee /tmp/script-validation.log
- if [ -n "$CRLF_FILES" ]; then
- echo "⚠️ Files with CRLF line endings found:" >> $GITHUB_STEP_SUMMARY
+ EXIT_CODE=$?
+
+ echo "" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- echo "$CRLF_FILES" >> $GITHUB_STEP_SUMMARY
+ cat /tmp/script-validation.log >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- echo "MokoStandards requires LF line endings" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$EXIT_CODE" -eq 0 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "✅ All critical scripts validated successfully!" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ else
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "❌ Script integrity violations detected" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required:** Review validation report and update registry" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ fi
else
- echo "✅ Line endings are consistent (LF)" >> $GITHUB_STEP_SUMMARY
+ echo "ℹ️ Script registry not found - skipping integrity check" >> $GITHUB_STEP_SUMMARY
+ exit 0
fi
+
+ # ════════════════════════════════════════════════════════════════════════
+ # TIER 3 — QUALITY (code quality metrics)
+ # ════════════════════════════════════════════════════════════════════════
line-length-validation:
name: Line Length Check
runs-on: ubuntu-latest
@@ -588,550 +1235,338 @@ jobs:
echo "Line length standards help maintain code readability." >> $GITHUB_STEP_SUMMARY
echo "Exceptions documented in: \`docs/policy/coding-style-guide.md\`" >> $GITHUB_STEP_SUMMARY
- license-compliance:
- name: License Header Validation
+ file-naming-standards:
+ name: File Naming Standards
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- - name: Check SPDX Headers
- run: |
- set -x
- echo "### SPDX License Header Check" >> $GITHUB_STEP_SUMMARY
-
- # Count source files with and without SPDX headers
- TOTAL_PHP=0
- WITH_SPDX_PHP=0
-
- if find . -name "*.php" -type f ! -path "./vendor/*" | head -1 | grep -q .; then
- TOTAL_PHP=$(find . -name "*.php" -type f ! -path "./vendor/*" | wc -l)
- WITH_SPDX_PHP=$(find . -name "*.php" -type f ! -path "./vendor/*" -exec grep -l "SPDX-License-Identifier" {} \; | wc -l)
- fi
-
- if [ "$TOTAL_PHP" -gt 0 ]; then
- PERCENT=$((WITH_SPDX_PHP * 100 / TOTAL_PHP))
- echo "- PHP files: $WITH_SPDX_PHP/$TOTAL_PHP ($PERCENT%) with SPDX headers" >> $GITHUB_STEP_SUMMARY
-
- if [ "$PERCENT" -lt 80 ]; then
- echo "⚠️ Less than 80% of PHP files have SPDX headers" >> $GITHUB_STEP_SUMMARY
- else
- echo "✅ Good SPDX header coverage" >> $GITHUB_STEP_SUMMARY
- fi
- fi
-
- - name: Validate License File
+ - name: Check File Naming
run: |
set -x
+ echo "## 📝 File Naming Standards" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
- echo "### License File Validation" >> $GITHUB_STEP_SUMMARY
- if [ ! -f "LICENSE" ]; then
- echo "❌ LICENSE file not found" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "### ❌ Validation Failed: LICENSE File Missing" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Error:** LICENSE file is required for all MokoStandards-compliant repositories" >> $GITHUB_STEP_SUMMARY
- echo "**Action Required:** Add LICENSE file with appropriate open-source license (GPL-3.0-or-later recommended)" >> $GITHUB_STEP_SUMMARY
- echo ""
- echo "❌ ERROR: LICENSE file not found - This is a critical requirement"
- exit 1
- fi
+ VIOLATIONS=0
- # Check license type
- if grep -qi "GNU GENERAL PUBLIC LICENSE" LICENSE; then
- VERSION=$(grep -i "Version 3" LICENSE || echo "")
- if [ -n "$VERSION" ]; then
- echo "✅ GPL-3.0-or-later license detected" >> $GITHUB_STEP_SUMMARY
- else
- echo "⚠️ GPL license detected but version unclear" >> $GITHUB_STEP_SUMMARY
- fi
- elif grep -qi "MIT License" LICENSE; then
- echo "✅ MIT license detected" >> $GITHUB_STEP_SUMMARY
- elif grep -qi "Apache License" LICENSE; then
- echo "✅ Apache license detected" >> $GITHUB_STEP_SUMMARY
- else
- echo "ℹ️ License type could not be automatically detected" >> $GITHUB_STEP_SUMMARY
- fi
+ # Check PHP files (should be PascalCase for classes)
+ 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)
- git-hygiene:
- name: Git Repository Hygiene
- runs-on: ubuntu-latest
+ # Check config files (should be kebab-case)
+ 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)
- steps:
- - name: Checkout Repository
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- with:
- fetch-depth: 0
-
- - name: Check .gitignore
- run: |
- set -x
- echo "### .gitignore Validation" >> $GITHUB_STEP_SUMMARY
-
- if [ ! -f ".gitignore" ]; then
- echo "⚠️ .gitignore file not found" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "### ⚠️ Warning: .gitignore Not Found" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Status:** .gitignore file is recommended but not required" >> $GITHUB_STEP_SUMMARY
- echo "**Recommendation:** Add .gitignore to exclude build artifacts, dependencies, and temporary files" >> $GITHUB_STEP_SUMMARY
- echo ""
- echo "⚠️ WARNING: .gitignore file not found - Continuing validation"
- exit 0
- fi
-
- # Check for common exclusions
- MISSING=""
- grep -q "vendor/" .gitignore || MISSING="${MISSING}vendor/ "
- grep -q "node_modules/" .gitignore || MISSING="${MISSING}node_modules/ "
-
- if [ -n "$MISSING" ]; then
- echo "⚠️ .gitignore may be missing common exclusions: $MISSING" >> $GITHUB_STEP_SUMMARY
- else
- echo "✅ .gitignore appears complete" >> $GITHUB_STEP_SUMMARY
- fi
-
- - name: Check for Large Files
- run: |
- set -x
+ echo "### Naming Violations" >> $GITHUB_STEP_SUMMARY
+ echo "- **PHP files not PascalCase**: $INVALID_PHP" >> $GITHUB_STEP_SUMMARY
+ echo "- **Config files not kebab-case**: $INVALID_CONFIG" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
- echo "### Large File Detection" >> $GITHUB_STEP_SUMMARY
- # Find files larger than 1MB
- LARGE_FILES=$(find . -type f -size +1M ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" | head -5)
+ VIOLATIONS=$((INVALID_PHP + INVALID_CONFIG))
- if [ -n "$LARGE_FILES" ]; then
- echo "⚠️ Large files detected (>1MB):" >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- echo "$LARGE_FILES" >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- echo "Consider using Git LFS for large binary files" >> $GITHUB_STEP_SUMMARY
+ if [ "$VIOLATIONS" -gt 0 ]; then
+ echo "⚠️ Found $VIOLATIONS naming convention violation(s)" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation**: Follow naming conventions for consistency" >> $GITHUB_STEP_SUMMARY
else
- echo "✅ No unusually large files detected" >> $GITHUB_STEP_SUMMARY
+ echo "✅ File naming conventions followed" >> $GITHUB_STEP_SUMMARY
fi
- workflow-validation:
- name: Workflow Configuration Check
+ insecure-patterns:
+ name: Insecure Code Pattern Detection
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- - name: Check Required Workflows
+ - name: Scan for Insecure Patterns
run: |
set -x
- echo "### GitHub Actions Workflows" >> $GITHUB_STEP_SUMMARY
+ echo "## 🔒 Insecure Code Pattern Detection" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
- WORKFLOWS_DIR=".github/workflows"
+ VIOLATIONS=0
- if [ ! -d "$WORKFLOWS_DIR" ]; then
- echo "❌ No workflows directory found" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "### ❌ Validation Failed: Workflows Directory Missing" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Error:** .github/workflows directory is required for CI/CD automation" >> $GITHUB_STEP_SUMMARY
- echo "**Action Required:** Create .github/workflows directory and add GitHub Actions workflows" >> $GITHUB_STEP_SUMMARY
- echo ""
- echo "❌ ERROR: .github/workflows directory not found"
- exit 1
+ # PHP: SQL injection patterns
+ if grep -r -n "\\$_\(GET\|POST\|REQUEST\).*mysql_query\|mysqli_query" . --include="*.php" ! -path "./vendor/*" 2>/dev/null > /tmp/sql_inject.txt; then
+ COUNT=$(wc -l < /tmp/sql_inject.txt)
+ echo "⚠️ Found $COUNT potential SQL injection pattern(s)" >> $GITHUB_STEP_SUMMARY
+ VIOLATIONS=$((VIOLATIONS + COUNT))
fi
- # Check for recommended workflows
- if [ -f "$WORKFLOWS_DIR/ci.yml" ] || [ -f "$WORKFLOWS_DIR/build.yml" ]; then
- echo "✅ CI workflow present" >> $GITHUB_STEP_SUMMARY
+ # PHP: eval/exec usage
+ if grep -r -n "eval\|exec\|system\|passthru\|shell_exec" . --include="*.php" ! -path "./vendor/*" 2>/dev/null > /tmp/exec.txt; then
+ COUNT=$(wc -l < /tmp/exec.txt)
+ echo "⚠️ Found $COUNT dangerous function call(s)" >> $GITHUB_STEP_SUMMARY
+ VIOLATIONS=$((VIOLATIONS + COUNT))
+ fi
+
+ # Python: eval usage
+ if grep -r -n "eval(" . --include="*.py" 2>/dev/null > /tmp/py_eval.txt; then
+ COUNT=$(wc -l < /tmp/py_eval.txt)
+ echo "⚠️ Found $COUNT Python eval() usage(s)" >> $GITHUB_STEP_SUMMARY
+ VIOLATIONS=$((VIOLATIONS + COUNT))
+ fi
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$VIOLATIONS" -gt 0 ]; then
+ echo "**Total Violations**: $VIOLATIONS" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation**: Review and secure flagged patterns" >> $GITHUB_STEP_SUMMARY
else
- echo "⚠️ No CI workflow found (ci.yml or build.yml)" >> $GITHUB_STEP_SUMMARY
+ echo "✅ No insecure patterns detected" >> $GITHUB_STEP_SUMMARY
fi
- if [ -f "$WORKFLOWS_DIR/codeql-analysis.yml" ]; then
- echo "✅ CodeQL security scanning present" >> $GITHUB_STEP_SUMMARY
- else
- echo "⚠️ CodeQL workflow not found" >> $GITHUB_STEP_SUMMARY
- fi
-
- - name: Validate Workflow Syntax
- run: |
- set -x
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "### Workflow YAML Syntax" >> $GITHUB_STEP_SUMMARY
-
- INVALID=0
- for workflow in $(find .github/workflows -maxdepth 1 -type f \( -name "*.yml" -o -name "*.yaml" \) 2>/dev/null); do
- if [ -f "$workflow" ]; then
- if python3 -c "import yaml, sys; yaml.safe_load(open(sys.argv[1]))" "$workflow" 2>/dev/null; then
- echo "✅ $(basename $workflow)" >> $GITHUB_STEP_SUMMARY
- else
- echo "❌ $(basename $workflow) - invalid YAML" >> $GITHUB_STEP_SUMMARY
- INVALID=$((INVALID + 1))
- fi
- fi
- done
-
- if [ "$INVALID" -gt 0 ]; then
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "### ❌ Validation Failed: Invalid Workflow YAML Syntax" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Error:** $INVALID workflow file(s) have invalid YAML syntax" >> $GITHUB_STEP_SUMMARY
- echo "**Action Required:** Fix YAML syntax errors in the marked workflow files" >> $GITHUB_STEP_SUMMARY
- echo "**Tool:** Run \`python3 -c \"import yaml; yaml.safe_load(open('.github/workflows/FILE.yml'))\"\` locally" >> $GITHUB_STEP_SUMMARY
- echo ""
- echo "❌ ERROR: $INVALID workflow file(s) with invalid YAML syntax"
- exit 1
- fi
-
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "### ✅ All Workflow Files Have Valid YAML Syntax" >> $GITHUB_STEP_SUMMARY
- echo ""
- echo "✅ SUCCESS: All workflow files passed YAML validation"
-
- - name: Validate CodeQL Configuration
- if: hashFiles('.github/workflows/codeql-analysis.yml') != ''
- run: |
- set -e
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "### CodeQL Language Configuration" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- # Inline validation (rewritten from Python to bash for PHP-only architecture)
- CODEQL_FILE=".github/workflows/codeql-analysis.yml"
-
- if [ ! -f "$CODEQL_FILE" ]; then
- echo "⚠️ CodeQL workflow file not found" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "### ⚠️ CodeQL Workflow Not Found" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Status:** CodeQL workflow file not present - skipping language validation" >> $GITHUB_STEP_SUMMARY
- echo ""
- echo "⚠️ INFO: CodeQL workflow not found - Skipping validation"
- exit 0
- fi
-
- echo "**CodeQL Configuration Analysis**" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- # Extract configured languages from workflow
- LANGUAGES=$(grep -A5 "language:" "$CODEQL_FILE" | grep -oP "(?<=')[^']+(?=')" | tr '\n' ' ' || echo "")
-
- # Check if this is a configuration-only scan (no languages specified)
- if grep -q "category.*language:config" "$CODEQL_FILE"; then
- echo "**Scan Type:** Configuration-only (no language matrix)" >> $GITHUB_STEP_SUMMARY
- echo "**Status:** ✅ Valid configuration for PHP-only repository" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "This CodeQL workflow scans YAML, JSON, shell scripts for security issues." >> $GITHUB_STEP_SUMMARY
- echo "PHP security is handled by SecurityValidator enterprise library." >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "✅ SUCCESS: CodeQL configuration-only scan properly configured"
- exit 0
- fi
-
- if [ -z "$LANGUAGES" ]; then
- echo "❌ No languages configured in CodeQL workflow" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "### ❌ Validation Failed: CodeQL Languages Not Configured" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Error:** CodeQL workflow exists but has no languages configured" >> $GITHUB_STEP_SUMMARY
- echo "**Action Required:** Configure appropriate languages in codeql-analysis.yml" >> $GITHUB_STEP_SUMMARY
- echo ""
- echo "❌ ERROR: No languages configured in CodeQL workflow"
- exit 1
- fi
-
- echo "**Configured Languages:** $LANGUAGES" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- # Validate language presence in repository
- INVALID_LANGS=""
- VALID_LANGS=""
-
- for LANG in $LANGUAGES; do
- case "$LANG" in
- python)
- # Check for Python files (should be none in v04.00.04)
- if find . -name "*.py" -type f ! -path "./.git/*" | grep -q .; then
- VALID_LANGS="$VALID_LANGS python"
- echo "✅ Python: Found Python files" >> $GITHUB_STEP_SUMMARY
- else
- INVALID_LANGS="$INVALID_LANGS python"
- echo "❌ Python: No Python files found (PHP-only repository)" >> $GITHUB_STEP_SUMMARY
- fi
- ;;
- javascript|typescript)
- # Check for JS/TS files
- if find . \( -name "*.js" -o -name "*.ts" -o -name "*.json" \) -type f ! -path "./.git/*" ! -path "./node_modules/*" | grep -q .; then
- VALID_LANGS="$VALID_LANGS $LANG"
- echo "✅ $LANG: Found JavaScript/TypeScript/JSON files" >> $GITHUB_STEP_SUMMARY
- else
- INVALID_LANGS="$INVALID_LANGS $LANG"
- echo "⚠️ $LANG: No JavaScript/TypeScript files found" >> $GITHUB_STEP_SUMMARY
- fi
- ;;
- java)
- if find . -name "*.java" -type f ! -path "./.git/*" | grep -q .; then
- VALID_LANGS="$VALID_LANGS java"
- echo "✅ Java: Found Java files" >> $GITHUB_STEP_SUMMARY
- else
- INVALID_LANGS="$INVALID_LANGS java"
- echo "⚠️ Java: No Java files found" >> $GITHUB_STEP_SUMMARY
- fi
- ;;
- go)
- if find . -name "*.go" -type f ! -path "./.git/*" | grep -q .; then
- VALID_LANGS="$VALID_LANGS go"
- echo "✅ Go: Found Go files" >> $GITHUB_STEP_SUMMARY
- else
- INVALID_LANGS="$INVALID_LANGS go"
- echo "⚠️ Go: No Go files found" >> $GITHUB_STEP_SUMMARY
- fi
- ;;
- cpp|c)
- if find . \( -name "*.cpp" -o -name "*.c" -o -name "*.h" \) -type f ! -path "./.git/*" | grep -q .; then
- VALID_LANGS="$VALID_LANGS $LANG"
- echo "✅ $LANG: Found C/C++ files" >> $GITHUB_STEP_SUMMARY
- else
- INVALID_LANGS="$INVALID_LANGS $LANG"
- echo "⚠️ $LANG: No C/C++ files found" >> $GITHUB_STEP_SUMMARY
- fi
- ;;
- ruby)
- if find . -name "*.rb" -type f ! -path "./.git/*" | grep -q .; then
- VALID_LANGS="$VALID_LANGS ruby"
- echo "✅ Ruby: Found Ruby files" >> $GITHUB_STEP_SUMMARY
- else
- INVALID_LANGS="$INVALID_LANGS ruby"
- echo "⚠️ Ruby: No Ruby files found" >> $GITHUB_STEP_SUMMARY
- fi
- ;;
- *)
- echo "⚠️ $LANG: Unknown language, skipping validation" >> $GITHUB_STEP_SUMMARY
- ;;
- esac
- done
-
- echo "" >> $GITHUB_STEP_SUMMARY
-
- # Report results
- if [ -n "$INVALID_LANGS" ]; then
- echo "**⚠️ Warning:** Some configured languages may not have corresponding files:" >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- echo "Invalid languages: $INVALID_LANGS" >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Note:** This is informational. CodeQL will skip languages without source files." >> $GITHUB_STEP_SUMMARY
- echo "For PHP repository (v04.00.04), JavaScript language covers JSON/YAML/shell scripts." >> $GITHUB_STEP_SUMMARY
- else
- echo "✅ **All configured CodeQL languages have corresponding source files**" >> $GITHUB_STEP_SUMMARY
- fi
-
- # Always succeed - this is informational only
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "### ✅ CodeQL Configuration Validation Complete" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Status:** CodeQL language configuration reviewed successfully" >> $GITHUB_STEP_SUMMARY
- echo ""
- echo "✅ SUCCESS: CodeQL validation complete"
- exit 0
-
- version-consistency:
- name: Version Consistency Check
+ code-complexity:
+ name: Code Complexity Analysis
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- - name: Set up PHP
- uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.31.0
+ - name: Setup PHP
+ uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.31.0
with:
php-version: '8.1'
- extensions: json
- tools: composer
- coverage: none
- - name: Install API Package
- run: composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
- env:
- COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN }}"}}'
-
- - name: Run Version Consistency Check
- id: version_check
+ - name: Analyze Complexity
run: |
set -x
- echo "## 🔢 Version Consistency Validation" >> $GITHUB_STEP_SUMMARY
+ echo "## 📊 Code Complexity Analysis" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
- if [ -f "api/validate/check_version_consistency.php" ]; then
- php api/validate/check_version_consistency.php --verbose | tee /tmp/version-check.log
- EXIT_CODE=$?
+ PHP_COUNT=$(find . -name "*.php" ! -path "./vendor/*" ! -path "./.git/*" | wc -l)
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- cat /tmp/version-check.log >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ if [ "$PHP_COUNT" -gt 0 ]; then
+ # Install phploc
+ wget https://phar.phpunit.de/phploc.phar 2>/dev/null
+ chmod +x phploc.phar
- if [ "$EXIT_CODE" -eq 0 ]; then
+ echo "### PHP Code Metrics" >> $GITHUB_STEP_SUMMARY
+ if ./phploc.phar --exclude vendor --exclude .git . 2>&1 | tee /tmp/phploc.txt; then
+ COMPLEXITY=$(grep "Cyclomatic Complexity" /tmp/phploc.txt | grep "Average" | awk '{print $NF}' || echo "N/A")
+ echo "**Average Cyclomatic Complexity**: $COMPLEXITY" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
- echo "✅ All version numbers are consistent!" >> $GITHUB_STEP_SUMMARY
- exit 0
- else
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "❌ Version mismatches detected - Please update all version references" >> $GITHUB_STEP_SUMMARY
- exit 1
+
+ if [ "$COMPLEXITY" != "N/A" ] && [ $(echo "$COMPLEXITY > 10" | bc -l) -eq 1 ]; then
+ echo "⚠️ Average complexity exceeds recommended threshold (10)" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation**: Refactor complex functions" >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ Code complexity within acceptable limits" >> $GITHUB_STEP_SUMMARY
+ fi
fi
else
- echo "ℹ️ Version consistency check script not found - skipping" >> $GITHUB_STEP_SUMMARY
- exit 0
+ echo "ℹ️ No PHP files found for complexity analysis" >> $GITHUB_STEP_SUMMARY
fi
- script-integrity:
- name: Script Integrity Validation
+ code-duplication:
+ name: Code Duplication Detection
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- - name: Set up Python
+ - name: Setup PHP
+ uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.31.0
+ with:
+ php-version: '8.1'
+
+ - name: Detect Duplicates
+ run: |
+ set -x
+ echo "## 🔁 Code Duplication Detection" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ # Check if PHP files exist
+ PHP_COUNT=$(find . -name "*.php" ! -path "./vendor/*" ! -path "./.git/*" | wc -l)
+
+ if [ "$PHP_COUNT" -gt 0 ]; then
+ echo "### PHP Code Duplication" >> $GITHUB_STEP_SUMMARY
+
+ # Install phpcpd
+ wget https://phar.phpunit.de/phpcpd.phar 2>/dev/null
+ chmod +x phpcpd.phar
+
+ # Run duplication detection
+ if ./phpcpd.phar --exclude vendor --exclude .git . 2>&1 | tee /tmp/phpcpd.txt; then
+ DUPLICATION=$(grep "Found" /tmp/phpcpd.txt | grep -oE "[0-9]+\.[0-9]+%" | head -1 || echo "0.00%")
+ echo "📊 **Duplication Rate**: $DUPLICATION" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ DUPLICATION_NUM=$(echo "$DUPLICATION" | sed 's/%//')
+ if [ $(echo "$DUPLICATION_NUM > 5.0" | bc -l) -eq 1 ]; then
+ echo "⚠️ Code duplication exceeds 5% threshold" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View duplication details
" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ cat /tmp/phpcpd.txt >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ Code duplication within acceptable limits (<5%)" >> $GITHUB_STEP_SUMMARY
+ fi
+ else
+ echo "✅ No significant code duplication detected" >> $GITHUB_STEP_SUMMARY
+ fi
+ else
+ echo "ℹ️ No PHP files found for duplication analysis" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Note**: This is an informational check to encourage DRY principles." >> $GITHUB_STEP_SUMMARY
+
+ dead-code-detection:
+ name: Dead Code Detection
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Setup Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: '3.x'
- - name: Validate Script Integrity
- id: script_check
+ - name: Detect Dead Code
run: |
set -x
- echo "## 🔐 Script Integrity Validation" >> $GITHUB_STEP_SUMMARY
+ echo "## 🗑️ Dead Code Detection" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
- if [ -f "api/.script-registry.json" ]; then
- echo "### Critical Scripts" >> $GITHUB_STEP_SUMMARY
- php api/maintenance/update_sha_hashes.php \
- --dry-run --verbose | tee /tmp/script-validation.log
+ PY_COUNT=$(find . -name "*.py" ! -path "./vendor/*" ! -path "./.git/*" ! -path "./venv/*" | wc -l)
- EXIT_CODE=$?
+ if [ "$PY_COUNT" -gt 0 ]; then
+ pip install vulture 2>/dev/null
+ echo "### Python Dead Code" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- cat /tmp/script-validation.log >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
-
- if [ "$EXIT_CODE" -eq 0 ]; then
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "✅ All critical scripts validated successfully!" >> $GITHUB_STEP_SUMMARY
- exit 0
- else
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "❌ Script integrity violations detected" >> $GITHUB_STEP_SUMMARY
- echo "**Action Required:** Review validation report and update registry" >> $GITHUB_STEP_SUMMARY
- exit 1
+ if vulture . --exclude vendor,venv,.git 2>&1 | tee /tmp/vulture.txt; then
+ DEAD_COUNT=$(wc -l < /tmp/vulture.txt || echo 0)
+ if [ "$DEAD_COUNT" -gt 0 ]; then
+ echo "⚠️ Found $DEAD_COUNT potential dead code item(s)" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View dead code
" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ head -50 /tmp/vulture.txt >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ No dead code detected" >> $GITHUB_STEP_SUMMARY
+ fi
fi
else
- echo "ℹ️ Script registry not found - skipping integrity check" >> $GITHUB_STEP_SUMMARY
- exit 0
+ echo "ℹ️ No Python files found for dead code analysis" >> $GITHUB_STEP_SUMMARY
fi
- enterprise-readiness:
- name: Enterprise Readiness Check
+
+ # ════════════════════════════════════════════════════════════════════════
+ # TIER 4 — SUPPLEMENTARY (informational)
+ # ════════════════════════════════════════════════════════════════════════
+ file-size-limits:
+ name: File Size Limits
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- - name: Set up PHP
- uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.31.0
- with:
- php-version: '8.1'
- extensions: json, mbstring
- tools: composer
- coverage: none
-
- - name: Install API Package
- run: composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
- env:
- COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN }}"}}'
-
- - name: Check Enterprise Readiness
- id: enterprise_check
+ - name: Check File Sizes
run: |
+ set -x
+ echo "## 📦 File Size Validation" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
- if [ -f "api/validate/check_enterprise_readiness.php" ]; then
- php api/validate/check_enterprise_readiness.php --verbose | tee /tmp/enterprise-check.log
- EXIT_CODE=$?
+ # Exempt file types (allowed to be large)
+ EXEMPT="! -name *.mmdb ! -name *.woff2 ! -name *.woff ! -name *.ttf ! -name *.otf"
+ # Find large files (>15MB warning, >20MB critical)
+ LARGE_FILES=$(find . -type f -size +15M $EXEMPT ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" 2>/dev/null | wc -l)
+ HUGE_FILES=$(find . -type f -size +20M $EXEMPT ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" 2>/dev/null | wc -l)
+
+ echo "### Size Thresholds" >> $GITHUB_STEP_SUMMARY
+ echo "- **Warning**: Files >15MB" >> $GITHUB_STEP_SUMMARY
+ echo "- **Critical**: Files >20MB" >> $GITHUB_STEP_SUMMARY
+ echo "- **Exempt**: .mmdb, .woff2, .woff, .ttf, .otf" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$HUGE_FILES" -gt 0 ]; then
+ echo "❌ **Critical**: Found $HUGE_FILES file(s) exceeding 20MB" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View files >20MB
" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- cat /tmp/enterprise-check.log >> $GITHUB_STEP_SUMMARY
+ 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
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
-
- if [ "$EXIT_CODE" -eq 0 ]; then
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "✅ Repository meets enterprise readiness criteria!" >> $GITHUB_STEP_SUMMARY
- exit 0
- else
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "⚠️ Enterprise readiness issues detected" >> $GITHUB_STEP_SUMMARY
- echo "**Note:** This is informational - review recommendations to improve" >> $GITHUB_STEP_SUMMARY
- exit 0 # Non-blocking
- fi
+ echo " " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required**: Remove or optimize files >20MB" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ elif [ "$LARGE_FILES" -gt 0 ]; then
+ echo "⚠️ **Warning**: Found $LARGE_FILES file(s) between 15MB and 20MB" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View files >15MB
" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ 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
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation**: Consider optimizing large files" >> $GITHUB_STEP_SUMMARY
else
- echo "ℹ️ Enterprise readiness check script not found - skipping" >> $GITHUB_STEP_SUMMARY
- exit 0
+ echo "✅ All files within acceptable size limits" >> $GITHUB_STEP_SUMMARY
fi
- repository-health:
- name: Repository Health Check
+ binary-file-detection:
+ name: Binary File Detection
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- - name: Set up PHP
- uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.31.0
- with:
- php-version: '8.1'
- extensions: json, mbstring
- tools: composer
- coverage: none
-
- - name: Install API Package
- run: composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
- env:
- COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN }}"}}'
-
- - name: Check Repository Health
- id: health_check
+ - name: Detect Binary Files
run: |
+ set -x
+ echo "## 🔍 Binary File Detection" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
- if [ -f "api/validate/check_repo_health.php" ]; then
- php api/validate/check_repo_health.php --verbose | tee /tmp/health-check.log
- EXIT_CODE=$?
+ # Find binary files excluding allowed types
+ BINARIES=$(find . -type f ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" \
+ ! -name "*.png" ! -name "*.jpg" ! -name "*.jpeg" ! -name "*.gif" ! -name "*.svg" ! -name "*.ico" \
+ ! -name "*.woff" ! -name "*.woff2" ! -name "*.ttf" ! -name "*.eot" \
+ -exec file {} \; | grep -v "text" | grep -v "empty" | wc -l || echo 0)
+ if [ "$BINARIES" -gt 0 ]; then
+ echo "⚠️ Found $BINARIES non-image binary file(s)" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View binary files
" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- cat /tmp/health-check.log >> $GITHUB_STEP_SUMMARY
+ find . -type f ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" \
+ ! -name "*.png" ! -name "*.jpg" ! -name "*.jpeg" ! -name "*.gif" ! -name "*.svg" ! -name "*.ico" \
+ ! -name "*.woff" ! -name "*.woff2" ! -name "*.ttf" ! -name "*.eot" \
+ -exec file {} \; | grep -v "text" | grep -v "empty" | cut -d: -f1 >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
-
- if [ "$EXIT_CODE" -eq 0 ]; then
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "✅ Repository health check passed!" >> $GITHUB_STEP_SUMMARY
- exit 0
- else
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "⚠️ Repository health issues detected" >> $GITHUB_STEP_SUMMARY
- echo "**Note:** This is informational - review recommendations to improve" >> $GITHUB_STEP_SUMMARY
- exit 0 # Non-blocking
- fi
+ echo " " >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation**: Source control should primarily contain text files" >> $GITHUB_STEP_SUMMARY
else
- echo "ℹ️ Repository health check script not found - skipping" >> $GITHUB_STEP_SUMMARY
- exit 0
+ echo "✅ No unexpected binary files detected" >> $GITHUB_STEP_SUMMARY
fi
+ # ============================================================================
+ # PHASE 4: Nice to Have Checks
+ # ============================================================================
+
todo-fixme-tracking:
name: TODO/FIXME Tracking
runs-on: ubuntu-latest
@@ -1181,154 +1616,131 @@ jobs:
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Note**: This is an informational check. Technical debt items don't block compliance." >> $GITHUB_STEP_SUMMARY
- file-size-limits:
- name: File Size Limits
+ dependency-vulnerabilities:
+ name: Dependency Vulnerability Scanning
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- - name: Check File Sizes
+ - name: Setup PHP
+ uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.31.0
+ with:
+ php-version: '8.1'
+
+ - name: Setup Python
+ uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
+ with:
+ python-version: '3.x'
+
+ - name: Scan Dependencies
run: |
set -x
- echo "## 📦 File Size Validation" >> $GITHUB_STEP_SUMMARY
+ echo "## 🛡️ Dependency Vulnerability Scanning" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
- # Find large files (>1MB)
- LARGE_FILES=$(find . -type f -size +1M ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" 2>/dev/null | wc -l)
- HUGE_FILES=$(find . -type f -size +15M ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" 2>/dev/null | wc -l)
+ VULNERABILITIES=0
- echo "### Size Thresholds" >> $GITHUB_STEP_SUMMARY
- echo "- **Warning**: Files >1MB" >> $GITHUB_STEP_SUMMARY
- echo "- **Critical**: Files >15MB" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- if [ "$HUGE_FILES" -gt 0 ]; then
- echo "❌ **Critical**: Found $HUGE_FILES file(s) exceeding 15MB" >> $GITHUB_STEP_SUMMARY
+ # PHP Dependencies
+ if [ -f "composer.json" ]; then
+ echo "### PHP Dependencies (composer)" >> $GITHUB_STEP_SUMMARY
+ if composer audit --no-dev 2>&1 | tee /tmp/php_audit.txt; then
+ echo "✅ No PHP vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
+ else
+ VULN_COUNT=$(grep -c "vulnerability" /tmp/php_audit.txt || echo 0)
+ echo "⚠️ Found $VULN_COUNT PHP vulnerability/vulnerabilities" >> $GITHUB_STEP_SUMMARY
+ VULNERABILITIES=$((VULNERABILITIES + VULN_COUNT))
+ fi
echo "" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "View files >15MB
" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- find . -type f -size +15M ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" -exec ls -lh {} + 2>/dev/null | awk '{print $5, $9}' >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- echo " " >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Action Required**: Remove or optimize files >15MB" >> $GITHUB_STEP_SUMMARY
- exit 1
- elif [ "$LARGE_FILES" -gt 0 ]; then
- echo "⚠️ **Warning**: Found $LARGE_FILES file(s) between 1MB and 15MB" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "View files >1MB
" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- find . -type f -size +1M ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" -exec ls -lh {} + 2>/dev/null | awk '{print $5, $9}' >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- echo " " >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Recommendation**: Consider optimizing or documenting large files" >> $GITHUB_STEP_SUMMARY
- else
- echo "✅ All files within acceptable size limits (<1MB)" >> $GITHUB_STEP_SUMMARY
fi
- secret-scanning:
- name: Secret Scanning
+ # Python Dependencies
+ if [ -f "requirements.txt" ]; then
+ echo "### Python Dependencies" >> $GITHUB_STEP_SUMMARY
+ pip install pip-audit 2>&1 > /dev/null
+ if pip-audit -r requirements.txt 2>&1 | tee /tmp/py_audit.txt; then
+ echo "✅ No Python vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
+ else
+ VULN_COUNT=$(grep -c "vulnerability" /tmp/py_audit.txt || echo 0)
+ echo "⚠️ Found $VULN_COUNT Python vulnerability/vulnerabilities" >> $GITHUB_STEP_SUMMARY
+ VULNERABILITIES=$((VULNERABILITIES + VULN_COUNT))
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ # NPM Dependencies
+ if [ -f "package.json" ]; then
+ echo "### NPM Dependencies" >> $GITHUB_STEP_SUMMARY
+ if npm audit --production 2>&1 | tee /tmp/npm_audit.txt; then
+ echo "✅ No NPM vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
+ else
+ VULN_COUNT=$(grep -c "vulnerability" /tmp/npm_audit.txt || echo 0)
+ echo "⚠️ Found $VULN_COUNT NPM vulnerability/vulnerabilities" >> $GITHUB_STEP_SUMMARY
+ VULNERABILITIES=$((VULNERABILITIES + VULN_COUNT))
+ fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ if [ "$VULNERABILITIES" -gt 0 ]; then
+ echo "**Total Vulnerabilities**: $VULNERABILITIES" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Action Required**: Update vulnerable dependencies" >> $GITHUB_STEP_SUMMARY
+ exit 1
+ else
+ echo "✅ No dependency vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
+ fi
+
+ unused-dependencies:
+ name: Unused Dependencies Check
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- - name: Scan for Secrets
+ - name: Setup PHP
+ uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.31.0
+ with:
+ php-version: '8.1'
+
+ - name: Check Unused Dependencies
run: |
set -x
- echo "## 🔒 Secret Scanning" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "Scanning for hardcoded secrets and credentials." >> $GITHUB_STEP_SUMMARY
+ echo "## 📦 Unused Dependencies Check" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
- # Define secret patterns
- VIOLATIONS=0
+ if [ -f "composer.json" ]; then
+ echo "### PHP Dependencies" >> $GITHUB_STEP_SUMMARY
- # Check for common secret patterns
- echo "### Secret Patterns" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
+ # Install composer-unused
+ composer global require icanhazstring/composer-unused 2>/dev/null || true
- # Pattern 1: password/secret assignments
- # Exclusions:
- # test|example|sample - test/example files
- # getenv - environment-variable reads
- # /\.\*/|^\s*// - regex patterns and commented lines
- # CREDENTIAL_PATTERNS|SecurityValidator|SECRET_PATTERN - scanner internals
- # ===|!== - strict comparison operators (not assignments)
- # ApiClient - constructor calls where token is a variable arg
- if grep -r -n -E "(password|passwd|pwd|secret|api[_-]?key|token).*=.*['\"]" . \
- --include="*.php" --include="*.py" --include="*.js" --include="*.ts" \
- --exclude-dir=".git" --exclude-dir="vendor" --exclude-dir="node_modules" 2>/dev/null | \
- grep -v -E '(test|example|sample|getenv|/\.\*/|^\s*//|CREDENTIAL_PATTERNS|SecurityValidator|SECRET_PATTERN|===|!==|ApiClient)' | \
- grep -v "= ''" | grep -v '= ""' > /tmp/secrets1.txt 2>/dev/null; then
- COUNT=$(wc -l < /tmp/secrets1.txt)
- if [ "$COUNT" -gt 0 ]; then
- echo "⚠️ Found $COUNT potential secret assignment(s)" >> $GITHUB_STEP_SUMMARY
- VIOLATIONS=$((VIOLATIONS + COUNT))
+ if composer global exec composer-unused 2>&1 | tee /tmp/unused.txt; then
+ UNUSED_COUNT=$(grep "unused" /tmp/unused.txt | wc -l || echo 0)
+ if [ "$UNUSED_COUNT" -gt 0 ]; then
+ echo "⚠️ Found $UNUSED_COUNT unused dependency/dependencies" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "View unused dependencies
" >> $GITHUB_STEP_SUMMARY
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ cat /tmp/unused.txt >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ echo " " >> $GITHUB_STEP_SUMMARY
+ else
+ echo "✅ No unused dependencies detected" >> $GITHUB_STEP_SUMMARY
+ fi
+ else
+ echo "✅ All dependencies appear to be in use" >> $GITHUB_STEP_SUMMARY
fi
- fi
-
- # Pattern 2: Private keys
- if grep -r -n "BEGIN.*PRIVATE KEY" . \
- --include="*.pem" --include="*.key" --include="*.txt" \
- --exclude-dir=".git" --exclude-dir="vendor" --exclude-dir="node_modules" 2>/dev/null > /tmp/secrets2.txt; then
- COUNT=$(wc -l < /tmp/secrets2.txt)
- if [ "$COUNT" -gt 0 ]; then
- echo "❌ Found $COUNT private key file(s)" >> $GITHUB_STEP_SUMMARY
- VIOLATIONS=$((VIOLATIONS + COUNT))
- fi
- fi
-
- # Pattern 3: AWS keys
- if grep -r -n -E "AKIA[0-9A-Z]{16}" . \
- --include="*.php" --include="*.py" --include="*.js" --include="*.txt" --include="*.env" \
- --exclude-dir=".git" --exclude-dir="vendor" --exclude-dir="node_modules" 2>/dev/null > /tmp/secrets3.txt; then
- COUNT=$(wc -l < /tmp/secrets3.txt)
- if [ "$COUNT" -gt 0 ]; then
- echo "❌ Found $COUNT potential AWS access key(s)" >> $GITHUB_STEP_SUMMARY
- VIOLATIONS=$((VIOLATIONS + COUNT))
- fi
- fi
-
- # Pattern 4: GitHub tokens
- if grep -r -n -E "gh[ps]_[a-zA-Z0-9]{36}" . \
- --include="*.php" --include="*.py" --include="*.js" --include="*.txt" --include="*.env" \
- --exclude-dir=".git" --exclude-dir="vendor" --exclude-dir="node_modules" 2>/dev/null > /tmp/secrets4.txt; then
- COUNT=$(wc -l < /tmp/secrets4.txt)
- if [ "$COUNT" -gt 0 ]; then
- echo "❌ Found $COUNT potential GitHub token(s)" >> $GITHUB_STEP_SUMMARY
- VIOLATIONS=$((VIOLATIONS + COUNT))
- fi
- fi
-
- echo "" >> $GITHUB_STEP_SUMMARY
-
- if [ "$VIOLATIONS" -gt 0 ]; then
- echo "**Total Violations**: $VIOLATIONS" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "View detected secrets (file paths only)
" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- cat /tmp/secrets*.txt 2>/dev/null | cut -d: -f1 | sort -u >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- echo " " >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Action Required**: Remove hardcoded secrets immediately!" >> $GITHUB_STEP_SUMMARY
- echo "Use environment variables or secrets management instead." >> $GITHUB_STEP_SUMMARY
- exit 1
else
- echo "✅ No hardcoded secrets detected" >> $GITHUB_STEP_SUMMARY
+ echo "ℹ️ No composer.json found" >> $GITHUB_STEP_SUMMARY
fi
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "**Recommendation**: Remove unused dependencies to reduce attack surface" >> $GITHUB_STEP_SUMMARY
+
broken-link-detection:
name: Broken Link Detection
runs-on: ubuntu-latest
@@ -1418,283 +1830,6 @@ jobs:
# PHASE 2: Medium Priority Checks
# ============================================================================
- dependency-vulnerabilities:
- name: Dependency Vulnerability Scanning
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout Repository
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
-
- - name: Setup PHP
- uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.31.0
- with:
- php-version: '8.1'
-
- - name: Setup Python
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
- with:
- python-version: '3.x'
-
- - name: Scan Dependencies
- run: |
- set -x
- echo "## 🛡️ Dependency Vulnerability Scanning" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- VULNERABILITIES=0
-
- # PHP Dependencies
- if [ -f "composer.json" ]; then
- echo "### PHP Dependencies (composer)" >> $GITHUB_STEP_SUMMARY
- if composer audit --no-dev 2>&1 | tee /tmp/php_audit.txt; then
- echo "✅ No PHP vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
- else
- VULN_COUNT=$(grep -c "vulnerability" /tmp/php_audit.txt || echo 0)
- echo "⚠️ Found $VULN_COUNT PHP vulnerability/vulnerabilities" >> $GITHUB_STEP_SUMMARY
- VULNERABILITIES=$((VULNERABILITIES + VULN_COUNT))
- fi
- echo "" >> $GITHUB_STEP_SUMMARY
- fi
-
- # Python Dependencies
- if [ -f "requirements.txt" ]; then
- echo "### Python Dependencies" >> $GITHUB_STEP_SUMMARY
- pip install pip-audit 2>&1 > /dev/null
- if pip-audit -r requirements.txt 2>&1 | tee /tmp/py_audit.txt; then
- echo "✅ No Python vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
- else
- VULN_COUNT=$(grep -c "vulnerability" /tmp/py_audit.txt || echo 0)
- echo "⚠️ Found $VULN_COUNT Python vulnerability/vulnerabilities" >> $GITHUB_STEP_SUMMARY
- VULNERABILITIES=$((VULNERABILITIES + VULN_COUNT))
- fi
- echo "" >> $GITHUB_STEP_SUMMARY
- fi
-
- # NPM Dependencies
- if [ -f "package.json" ]; then
- echo "### NPM Dependencies" >> $GITHUB_STEP_SUMMARY
- if npm audit --production 2>&1 | tee /tmp/npm_audit.txt; then
- echo "✅ No NPM vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
- else
- VULN_COUNT=$(grep -c "vulnerability" /tmp/npm_audit.txt || echo 0)
- echo "⚠️ Found $VULN_COUNT NPM vulnerability/vulnerabilities" >> $GITHUB_STEP_SUMMARY
- VULNERABILITIES=$((VULNERABILITIES + VULN_COUNT))
- fi
- echo "" >> $GITHUB_STEP_SUMMARY
- fi
-
- if [ "$VULNERABILITIES" -gt 0 ]; then
- echo "**Total Vulnerabilities**: $VULNERABILITIES" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Action Required**: Update vulnerable dependencies" >> $GITHUB_STEP_SUMMARY
- exit 1
- else
- echo "✅ No dependency vulnerabilities detected" >> $GITHUB_STEP_SUMMARY
- fi
-
- code-duplication:
- name: Code Duplication Detection
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout Repository
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
-
- - name: Setup PHP
- uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.31.0
- with:
- php-version: '8.1'
-
- - name: Detect Duplicates
- run: |
- set -x
- echo "## 🔁 Code Duplication Detection" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- # Check if PHP files exist
- PHP_COUNT=$(find . -name "*.php" ! -path "./vendor/*" ! -path "./.git/*" | wc -l)
-
- if [ "$PHP_COUNT" -gt 0 ]; then
- echo "### PHP Code Duplication" >> $GITHUB_STEP_SUMMARY
-
- # Install phpcpd
- wget https://phar.phpunit.de/phpcpd.phar 2>/dev/null
- chmod +x phpcpd.phar
-
- # Run duplication detection
- if ./phpcpd.phar --exclude vendor --exclude .git . 2>&1 | tee /tmp/phpcpd.txt; then
- DUPLICATION=$(grep "Found" /tmp/phpcpd.txt | grep -oE "[0-9]+\.[0-9]+%" | head -1 || echo "0.00%")
- echo "📊 **Duplication Rate**: $DUPLICATION" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- DUPLICATION_NUM=$(echo "$DUPLICATION" | sed 's/%//')
- if [ $(echo "$DUPLICATION_NUM > 5.0" | bc -l) -eq 1 ]; then
- echo "⚠️ Code duplication exceeds 5% threshold" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "View duplication details
" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- cat /tmp/phpcpd.txt >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- echo " " >> $GITHUB_STEP_SUMMARY
- else
- echo "✅ Code duplication within acceptable limits (<5%)" >> $GITHUB_STEP_SUMMARY
- fi
- else
- echo "✅ No significant code duplication detected" >> $GITHUB_STEP_SUMMARY
- fi
- else
- echo "ℹ️ No PHP files found for duplication analysis" >> $GITHUB_STEP_SUMMARY
- fi
-
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Note**: This is an informational check to encourage DRY principles." >> $GITHUB_STEP_SUMMARY
-
- unused-dependencies:
- name: Unused Dependencies Check
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout Repository
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
-
- - name: Setup PHP
- uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.31.0
- with:
- php-version: '8.1'
-
- - name: Check Unused Dependencies
- run: |
- set -x
- echo "## 📦 Unused Dependencies Check" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- if [ -f "composer.json" ]; then
- echo "### PHP Dependencies" >> $GITHUB_STEP_SUMMARY
-
- # Install composer-unused
- composer global require icanhazstring/composer-unused 2>/dev/null || true
-
- if composer global exec composer-unused 2>&1 | tee /tmp/unused.txt; then
- UNUSED_COUNT=$(grep "unused" /tmp/unused.txt | wc -l || echo 0)
- if [ "$UNUSED_COUNT" -gt 0 ]; then
- echo "⚠️ Found $UNUSED_COUNT unused dependency/dependencies" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "View unused dependencies
" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- cat /tmp/unused.txt >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- echo " " >> $GITHUB_STEP_SUMMARY
- else
- echo "✅ No unused dependencies detected" >> $GITHUB_STEP_SUMMARY
- fi
- else
- echo "✅ All dependencies appear to be in use" >> $GITHUB_STEP_SUMMARY
- fi
- else
- echo "ℹ️ No composer.json found" >> $GITHUB_STEP_SUMMARY
- fi
-
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Recommendation**: Remove unused dependencies to reduce attack surface" >> $GITHUB_STEP_SUMMARY
-
- readme-completeness:
- name: README Completeness Check
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout Repository
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
-
- - name: Check README Sections
- run: |
- set -x
- echo "## 📄 README Completeness Check" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- if [ ! -f "README.md" ]; then
- echo "❌ README.md not found" >> $GITHUB_STEP_SUMMARY
- exit 1
- fi
-
- # Required sections
- REQUIRED_SECTIONS=("Installation" "Usage" "Contributing" "License")
- MISSING=0
- PRESENT=0
-
- echo "### Required Sections" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- for section in "${REQUIRED_SECTIONS[@]}"; do
- if grep -qi "##.*$section" README.md; then
- echo "✅ $section" >> $GITHUB_STEP_SUMMARY
- PRESENT=$((PRESENT + 1))
- else
- echo "❌ $section" >> $GITHUB_STEP_SUMMARY
- MISSING=$((MISSING + 1))
- fi
- done
-
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Completeness**: $PRESENT/${#REQUIRED_SECTIONS[@]} required sections present" >> $GITHUB_STEP_SUMMARY
-
- if [ "$MISSING" -gt 0 ]; then
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Action Required**: Add missing sections to README.md" >> $GITHUB_STEP_SUMMARY
- exit 1
- fi
-
- # ============================================================================
- # PHASE 3: Future Enhancements
- # ============================================================================
-
- code-complexity:
- name: Code Complexity Analysis
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout Repository
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
-
- - name: Setup PHP
- uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2.31.0
- with:
- php-version: '8.1'
-
- - name: Analyze Complexity
- run: |
- set -x
- echo "## 📊 Code Complexity Analysis" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- PHP_COUNT=$(find . -name "*.php" ! -path "./vendor/*" ! -path "./.git/*" | wc -l)
-
- if [ "$PHP_COUNT" -gt 0 ]; then
- # Install phploc
- wget https://phar.phpunit.de/phploc.phar 2>/dev/null
- chmod +x phploc.phar
-
- echo "### PHP Code Metrics" >> $GITHUB_STEP_SUMMARY
- if ./phploc.phar --exclude vendor --exclude .git . 2>&1 | tee /tmp/phploc.txt; then
- COMPLEXITY=$(grep "Cyclomatic Complexity" /tmp/phploc.txt | grep "Average" | awk '{print $NF}' || echo "N/A")
- echo "**Average Cyclomatic Complexity**: $COMPLEXITY" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- if [ "$COMPLEXITY" != "N/A" ] && [ $(echo "$COMPLEXITY > 10" | bc -l) -eq 1 ]; then
- echo "⚠️ Average complexity exceeds recommended threshold (10)" >> $GITHUB_STEP_SUMMARY
- echo "**Recommendation**: Refactor complex functions" >> $GITHUB_STEP_SUMMARY
- else
- echo "✅ Code complexity within acceptable limits" >> $GITHUB_STEP_SUMMARY
- fi
- fi
- else
- echo "ℹ️ No PHP files found for complexity analysis" >> $GITHUB_STEP_SUMMARY
- fi
-
api-documentation:
name: API Documentation Coverage
runs-on: ubuntu-latest
@@ -1728,176 +1863,6 @@ jobs:
echo "ℹ️ No public methods found for documentation check" >> $GITHUB_STEP_SUMMARY
fi
- insecure-patterns:
- name: Insecure Code Pattern Detection
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout Repository
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
-
- - name: Scan for Insecure Patterns
- run: |
- set -x
- echo "## 🔒 Insecure Code Pattern Detection" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- VIOLATIONS=0
-
- # PHP: SQL injection patterns
- if grep -r -n "\\$_\(GET\|POST\|REQUEST\).*mysql_query\|mysqli_query" . --include="*.php" ! -path "./vendor/*" 2>/dev/null > /tmp/sql_inject.txt; then
- COUNT=$(wc -l < /tmp/sql_inject.txt)
- echo "⚠️ Found $COUNT potential SQL injection pattern(s)" >> $GITHUB_STEP_SUMMARY
- VIOLATIONS=$((VIOLATIONS + COUNT))
- fi
-
- # PHP: eval/exec usage
- if grep -r -n "eval\|exec\|system\|passthru\|shell_exec" . --include="*.php" ! -path "./vendor/*" 2>/dev/null > /tmp/exec.txt; then
- COUNT=$(wc -l < /tmp/exec.txt)
- echo "⚠️ Found $COUNT dangerous function call(s)" >> $GITHUB_STEP_SUMMARY
- VIOLATIONS=$((VIOLATIONS + COUNT))
- fi
-
- # Python: eval usage
- if grep -r -n "eval(" . --include="*.py" 2>/dev/null > /tmp/py_eval.txt; then
- COUNT=$(wc -l < /tmp/py_eval.txt)
- echo "⚠️ Found $COUNT Python eval() usage(s)" >> $GITHUB_STEP_SUMMARY
- VIOLATIONS=$((VIOLATIONS + COUNT))
- fi
-
- echo "" >> $GITHUB_STEP_SUMMARY
-
- if [ "$VIOLATIONS" -gt 0 ]; then
- echo "**Total Violations**: $VIOLATIONS" >> $GITHUB_STEP_SUMMARY
- echo "**Recommendation**: Review and secure flagged patterns" >> $GITHUB_STEP_SUMMARY
- else
- echo "✅ No insecure patterns detected" >> $GITHUB_STEP_SUMMARY
- fi
-
- binary-file-detection:
- name: Binary File Detection
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout Repository
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
-
- - name: Detect Binary Files
- run: |
- set -x
- echo "## 🔍 Binary File Detection" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- # Find binary files excluding allowed types
- BINARIES=$(find . -type f ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" \
- ! -name "*.png" ! -name "*.jpg" ! -name "*.jpeg" ! -name "*.gif" ! -name "*.svg" ! -name "*.ico" \
- ! -name "*.woff" ! -name "*.woff2" ! -name "*.ttf" ! -name "*.eot" \
- -exec file {} \; | grep -v "text" | grep -v "empty" | wc -l || echo 0)
-
- if [ "$BINARIES" -gt 0 ]; then
- echo "⚠️ Found $BINARIES non-image binary file(s)" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "View binary files
" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- find . -type f ! -path "./.git/*" ! -path "./vendor/*" ! -path "./node_modules/*" \
- ! -name "*.png" ! -name "*.jpg" ! -name "*.jpeg" ! -name "*.gif" ! -name "*.svg" ! -name "*.ico" \
- ! -name "*.woff" ! -name "*.woff2" ! -name "*.ttf" ! -name "*.eot" \
- -exec file {} \; | grep -v "text" | grep -v "empty" | cut -d: -f1 >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- echo " " >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "**Recommendation**: Source control should primarily contain text files" >> $GITHUB_STEP_SUMMARY
- else
- echo "✅ No unexpected binary files detected" >> $GITHUB_STEP_SUMMARY
- fi
-
- # ============================================================================
- # PHASE 4: Nice to Have Checks
- # ============================================================================
-
- dead-code-detection:
- name: Dead Code Detection
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout Repository
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
-
- - name: Setup Python
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
- with:
- python-version: '3.x'
-
- - name: Detect Dead Code
- run: |
- set -x
- echo "## 🗑️ Dead Code Detection" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- PY_COUNT=$(find . -name "*.py" ! -path "./vendor/*" ! -path "./.git/*" ! -path "./venv/*" | wc -l)
-
- if [ "$PY_COUNT" -gt 0 ]; then
- pip install vulture 2>/dev/null
- echo "### Python Dead Code" >> $GITHUB_STEP_SUMMARY
-
- if vulture . --exclude vendor,venv,.git 2>&1 | tee /tmp/vulture.txt; then
- DEAD_COUNT=$(wc -l < /tmp/vulture.txt || echo 0)
- if [ "$DEAD_COUNT" -gt 0 ]; then
- echo "⚠️ Found $DEAD_COUNT potential dead code item(s)" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "View dead code
" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- head -50 /tmp/vulture.txt >> $GITHUB_STEP_SUMMARY
- echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
- echo " " >> $GITHUB_STEP_SUMMARY
- else
- echo "✅ No dead code detected" >> $GITHUB_STEP_SUMMARY
- fi
- fi
- else
- echo "ℹ️ No Python files found for dead code analysis" >> $GITHUB_STEP_SUMMARY
- fi
-
- file-naming-standards:
- name: File Naming Standards
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout Repository
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
-
- - name: Check File Naming
- run: |
- set -x
- echo "## 📝 File Naming Standards" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- VIOLATIONS=0
-
- # Check PHP files (should be PascalCase for classes)
- 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)
-
- # Check config files (should be kebab-case)
- 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)
-
- echo "### Naming Violations" >> $GITHUB_STEP_SUMMARY
- echo "- **PHP files not PascalCase**: $INVALID_PHP" >> $GITHUB_STEP_SUMMARY
- echo "- **Config files not kebab-case**: $INVALID_CONFIG" >> $GITHUB_STEP_SUMMARY
- echo "" >> $GITHUB_STEP_SUMMARY
-
- VIOLATIONS=$((INVALID_PHP + INVALID_CONFIG))
-
- if [ "$VIOLATIONS" -gt 0 ]; then
- echo "⚠️ Found $VIOLATIONS naming convention violation(s)" >> $GITHUB_STEP_SUMMARY
- echo "**Recommendation**: Follow naming conventions for consistency" >> $GITHUB_STEP_SUMMARY
- else
- echo "✅ File naming conventions followed" >> $GITHUB_STEP_SUMMARY
- fi
-
accessibility-check:
name: Accessibility Check
runs-on: ubuntu-latest
@@ -1980,6 +1945,106 @@ jobs:
echo "ℹ️ Not a JavaScript project" >> $GITHUB_STEP_SUMMARY
fi
+ enterprise-readiness:
+ name: Enterprise Readiness Check
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Set up PHP
+ uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.31.0
+ with:
+ php-version: '8.1'
+ extensions: json, mbstring
+ tools: composer
+ coverage: none
+
+ - name: Install API Package
+ run: composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
+ env:
+ COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN }}"}}'
+
+ - name: Check Enterprise Readiness
+ id: enterprise_check
+ run: |
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ -f "api/validate/check_enterprise_readiness.php" ]; then
+ php api/validate/check_enterprise_readiness.php --verbose | tee /tmp/enterprise-check.log
+ EXIT_CODE=$?
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ cat /tmp/enterprise-check.log >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$EXIT_CODE" -eq 0 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "✅ Repository meets enterprise readiness criteria!" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ else
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "⚠️ Enterprise readiness issues detected" >> $GITHUB_STEP_SUMMARY
+ echo "**Note:** This is informational - review recommendations to improve" >> $GITHUB_STEP_SUMMARY
+ exit 0 # Non-blocking
+ fi
+ else
+ echo "ℹ️ Enterprise readiness check script not found - skipping" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ fi
+
+ repository-health:
+ name: Repository Health Check
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
+
+ - name: Set up PHP
+ uses: shivammathur/setup-php@accd6127cb78bee3e8082180cb391013d204ef9f # v2.31.0
+ with:
+ php-version: '8.1'
+ extensions: json, mbstring
+ tools: composer
+ coverage: none
+
+ - name: Install API Package
+ run: composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader
+ env:
+ COMPOSER_AUTH: '{"github-oauth":{"github.com":"${{ secrets.GH_TOKEN }}"}}'
+
+ - name: Check Repository Health
+ id: health_check
+ run: |
+ echo "" >> $GITHUB_STEP_SUMMARY
+
+ if [ -f "api/validate/check_repo_health.php" ]; then
+ php api/validate/check_repo_health.php --verbose | tee /tmp/health-check.log
+ EXIT_CODE=$?
+
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+ cat /tmp/health-check.log >> $GITHUB_STEP_SUMMARY
+ echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
+
+ if [ "$EXIT_CODE" -eq 0 ]; then
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "✅ Repository health check passed!" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ else
+ echo "" >> $GITHUB_STEP_SUMMARY
+ echo "⚠️ Repository health issues detected" >> $GITHUB_STEP_SUMMARY
+ echo "**Note:** This is informational - review recommendations to improve" >> $GITHUB_STEP_SUMMARY
+ exit 0 # Non-blocking
+ fi
+ else
+ echo "ℹ️ Repository health check script not found - skipping" >> $GITHUB_STEP_SUMMARY
+ exit 0
+ fi
+
terraform-validation:
name: Terraform Configuration Validation
runs-on: ubuntu-latest
@@ -2420,110 +2485,73 @@ jobs:
- name: Create tracking issue for standards violations
if: failure() && github.event_name == 'push'
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8
- with:
- script: |
- const compliancePercent = '${{ needs.compliance-check.outputs.compliance_percentage }}' || '0';
- const failedChecks = [];
+ env:
+ GH_TOKEN: ${{ secrets.GH_TOKEN || github.token }}
+ run: |
+ REPO="${{ github.repository }}"
+ RUN_URL="${{ github.server_url }}/${REPO}/actions/runs/${{ github.run_id }}"
+ DATE=$(date -u '+%Y-%m-%d')
+ SHA="${{ github.sha }}"
+ ACTOR="${{ github.actor }}"
+ BRANCH="${{ github.ref_name }}"
- // Collect failed checks from job outputs
- const jobs = [
- { name: 'File Headers', failed: '${{ needs.compliance-check.outputs.headers_ok }}' !== 'true' },
- { name: 'Required Files', failed: '${{ needs.compliance-check.outputs.required_files_ok }}' !== 'true' },
- { name: 'Documentation', failed: '${{ needs.compliance-check.outputs.documentation_ok }}' !== 'true' },
- { name: 'Code Quality', failed: '${{ needs.compliance-check.outputs.code_quality_ok }}' !== 'true' }
- ];
+ # Collect failed checks
+ FAILED=""
+ [ "${{ needs.repository-structure.result }}" != "success" ] && FAILED="${FAILED}\n- Repository Structure"
+ [ "${{ needs.documentation-quality.result }}" != "success" ] && FAILED="${FAILED}\n- Documentation Quality"
+ [ "${{ needs.coding-standards.result }}" != "success" ] && FAILED="${FAILED}\n- Coding Standards"
+ [ "${{ needs.license-compliance.result }}" != "success" ] && FAILED="${FAILED}\n- License Compliance"
+ [ "${{ needs.git-hygiene.result }}" != "success" ] && FAILED="${FAILED}\n- Git Hygiene"
+ [ "${{ needs.workflow-validation.result }}" != "success" ] && FAILED="${FAILED}\n- Workflow Validation"
+ [ "${{ needs.version-consistency.result }}" != "success" ] && FAILED="${FAILED}\n- Version Consistency"
+ [ "${{ needs.script-integrity.result }}" != "success" ] && FAILED="${FAILED}\n- Script Integrity"
+ [ "${{ needs.secret-scanning.result }}" != "success" ] && FAILED="${FAILED}\n- Secret Scanning"
+ [ "${{ needs.line-length-validation.result }}" != "success" ] && FAILED="${FAILED}\n- Line Length"
+ [ "${{ needs.file-size-limits.result }}" != "success" ] && FAILED="${FAILED}\n- File Size Limits"
+ [ "${{ needs.readme-completeness.result }}" != "success" ] && FAILED="${FAILED}\n- README Completeness"
- jobs.forEach(job => {
- if (job.failed) failedChecks.push(job.name);
- });
+ if [ -z "$FAILED" ]; then
+ echo "No failed checks to report"
+ exit 0
+ fi
- const body = `## 📋 Standards Compliance Violations Detected
+ TITLE="[Standards] Compliance violations — ${DATE}"
+ BODY="## Standards Compliance Violations
- **Branch**: \`${context.ref}\`
- **Commit**: ${context.sha.substring(0, 7)}
- **Triggered by**: @${context.actor}
- **Date**: ${new Date().toISOString()}
+ | Field | Value |
+ |-------|-------|
+ | **Branch** | \`${BRANCH}\` |
+ | **Commit** | \`${SHA:0:7}\` |
+ | **Actor** | @${ACTOR} |
+ | **Run** | [View workflow](${RUN_URL}) |
- ### Compliance Score: ${compliancePercent}%
+ ### Failed Checks
+ $(printf '%b' "$FAILED")
- ### ❌ Failed Checks
- ${failedChecks.length > 0 ? failedChecks.map(check => `- ${check}`).join('\n') : '_Details available in workflow run_'}
+ ### Required Actions
+ 1. Review the [workflow run](${RUN_URL}) for details
+ 2. Fix each failed check
+ 3. Push to trigger a new scan
- ### 📊 What This Means
- Your repository does not meet the required MokoStandards compliance threshold. This can affect:
- - Code quality and maintainability
- - Team collaboration efficiency
- - Automated tooling integration
- - Repository discoverability
+ ---
+ *Auto-created by standards-compliance workflow*"
- ### ✅ Required Actions
- 1. Review the [workflow run](${context.payload.repository.html_url}/actions/runs/${context.runId}) for detailed findings
- 2. Address each failed check according to MokoStandards documentation
- 3. Push changes to trigger a new compliance scan
- 4. Ensure compliance reaches 100% before merging
+ BODY=$(echo "$BODY" | sed 's/^ //')
+ LABEL="standards-violation"
- ### 📚 Resources
- - [MokoStandards Documentation](https://github.com/mokoconsulting-tech/MokoStandards)
- - [Repository Structure Guide](https://github.com/mokoconsulting-tech/MokoStandards/tree/main/docs/policy/core-structure.md)
- - [Documentation Standards](https://github.com/mokoconsulting-tech/MokoStandards/tree/main/docs/policy/document-formatting.md)
- - [Coding Standards](https://github.com/mokoconsulting-tech/MokoStandards/tree/main/docs/policy/coding-style-guide.md)
+ gh label create "$LABEL" --repo "$REPO" --color "D73A4A" --description "Standards compliance failure" --force 2>/dev/null || true
- ### 🔄 Resolution
- This issue will be automatically closed when compliance reaches 100%.
+ EXISTING=$(gh api "repos/${REPO}/issues?labels=${LABEL}&state=all&per_page=1&sort=created&direction=desc" \
+ --jq '.[0].number' 2>/dev/null)
- ---
- *This issue was automatically created by the Standards Compliance workflow.*
- `;
-
- // Validate assignees before creating issue
- async function validateAssignees(assignees) {
- const validAssignees = [];
- for (const assignee of assignees) {
- try {
- await github.rest.users.getByUsername({ username: assignee });
- validAssignees.push(assignee);
- console.log(`✓ Validated assignee: ${assignee}`);
- } catch (error) {
- console.log(`✗ Invalid assignee (skipping): ${assignee} - ${error.message}`);
- }
- }
- return validAssignees;
- }
-
- const requestedAssignees = ['jmiller-moko'];
- const validAssignees = await validateAssignees(requestedAssignees);
-
- // Check for existing open issue
- const issues = await github.rest.issues.listForRepo({
- owner: context.repo.owner,
- repo: context.repo.repo,
- state: 'open',
- labels: 'standards-violation',
- per_page: 1
- });
-
- if (issues.data.length > 0) {
- // Update existing issue
- await github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: issues.data[0].number,
- body: `### 🔄 Updated Scan Results\n\n${body}`
- });
- console.log(`Updated existing issue #${issues.data[0].number}`);
- } else {
- // Create new issue with validated assignees
- const issue = await github.rest.issues.create({
- owner: context.repo.owner,
- repo: context.repo.repo,
- title: `[Standards] Compliance Violations - ${new Date().toISOString().split('T')[0]}`,
- body: body,
- labels: ['standards-violation', 'compliance', 'automation'],
- assignees: validAssignees
- });
- console.log(`Created new issue #${issue.data.number}`);
- }
+ if [ -n "$EXISTING" ] && [ "$EXISTING" != "null" ]; then
+ gh api "repos/${REPO}/issues/${EXISTING}" -X PATCH \
+ -f title="$TITLE" -f body="$BODY" -f state="open" --silent
+ echo "Updated issue #${EXISTING}"
+ else
+ gh issue create --repo "$REPO" --title "$TITLE" --body "$BODY" \
+ --label "$LABEL" --assignee "jmiller-moko"
+ fi
# CUSTOMIZATION:
#
@@ -2532,3 +2560,4 @@ jobs:
# 3. Integrate with custom linting tools
# 4. Add notification steps for compliance failures
# 5. Customize required files/directories for your project type
+