name: CI - Test & Lint on: pull_request: branches: [main, develop] push: branches: [main, develop] jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: PHP Syntax Check run: | ERR=0 while IFS= read -r f; do php -l "$f" || ERR=1 done < <(find . -name "*.php" -not -path "./.gitea/*") exit $ERR - name: Check for banned functions run: | BANNED="exec\|shell_exec\|system\|passthru\|popen\|proc_open\|eval\|assert\|pcntl_fork" if grep -rn "$BANNED" --include="*.php" . 2>/dev/null | grep -v "BANNED="; then echo "FAILED: Banned function found!" exit 1 fi echo "OK: No banned functions — safe for RoketServer cPanel" - name: Validate WP plugin headers run: | for HEADER in "Plugin Name" "Version" "Description" "Author"; do grep -q "$HEADER:" hermes-ai-bridge.php || { echo "Missing: $HEADER"; exit 1; } done echo "OK: All required plugin headers present" security: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Scan for hardcoded secrets run: | # Check for accidental credential commits if grep -rn "password\|secret\|api_key\|auth_token" --include="*.php" \ --include="*.json" . 2>/dev/null | grep -v "WP_APP_PASSWORD\|get_option\|secrets\.\|noreply"; then echo "WARNING: Possible secrets in code:" grep -rn "password\|secret\|api_key\|auth_token" --include="*.php" \ --include="*.json" . | grep -v "WP_APP_PASSWORD\|get_option\|secrets\.\|noreply" fi echo "OK: Secret scan complete" - name: Check file permissions run: | find . -perm /o+w -not -path "./.git/*" -not -path "./.gitea/*" \ -not -path "./.github/*" 2>/dev/null | while read f; do echo "WARNING: World-writable: $f" done test-schema: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Verify REST API namespace is declared run: | if grep -q "namespace.*hermes/v1" includes/rest-controller.php; then echo "OK: REST namespace hermes/v1 found" else echo "FAILED: REST namespace hermes/v1 missing" exit 1 fi - name: Verify autoloader loads all classes run: | for CLASS in Core Installer RestController AiProvider Scheduler NextcloudBridge; do if grep -q "$CLASS" includes/class-autoloader.php; then echo "OK: $CLASS mapped in autoloader" else echo "FAILED: $CLASS not in autoloader" exit 1 fi done