- phpcs-scan.sh: WordPress-Extra 标准扫描,提取安全发现输出 JSON - 报告生成器集成 PHPCS 维度(高危: SQL注入/CSRF, 中危: 输出未转义) - acceptance-criteria.json 新增 phpcs 阈值,整体门槛调整为 8/10 - Justfile 新增 phpcs-scan 独立任务,test-plugin 流程自动集成 - plugin-check.sh: PCP 自动化脚本(Playground 集成,待完善) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
94 lines
3.1 KiB
Bash
Executable file
94 lines
3.1 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# WordPress Plugin Check (PCP) 自动化
|
|
# 用法: plugin-check.sh <plugin-zip> [output-dir]
|
|
# 需要: Playground CLI, plugin-check.zip
|
|
set -euo pipefail
|
|
|
|
PLUGIN_ZIP="${1:?用法: $0 <plugin-zip> [output-dir]}"
|
|
OUTPUT_DIR="${2:-/tmp/pcp-results}"
|
|
PCP_ZIP="/tmp/plugin-check.zip"
|
|
PORT=9401
|
|
PLUGIN_NAME=$(basename "$PLUGIN_ZIP" .zip)
|
|
|
|
mkdir -p "$OUTPUT_DIR"
|
|
|
|
# 确保 PCP zip 存在
|
|
if [ ! -f "$PCP_ZIP" ]; then
|
|
echo "[pcp] 下载 Plugin Check..."
|
|
curl -sL "https://downloads.wordpress.org/plugin/plugin-check.latest-stable.zip" -o "$PCP_ZIP"
|
|
fi
|
|
|
|
# 启动 HTTP server 服务 zip 文件
|
|
SERVE_DIR=$(mktemp -d)
|
|
cp "$PLUGIN_ZIP" "$SERVE_DIR/"
|
|
cp "$PCP_ZIP" "$SERVE_DIR/"
|
|
python3 -m http.server 8889 --directory "$SERVE_DIR" &>/dev/null &
|
|
HTTP_PID=$!
|
|
trap "kill $HTTP_PID 2>/dev/null; rm -rf $SERVE_DIR" EXIT
|
|
sleep 1
|
|
|
|
# 生成临时 Blueprint
|
|
BLUEPRINT=$(mktemp --suffix=.json)
|
|
cat > "$BLUEPRINT" <<BPEOF
|
|
{
|
|
"\$schema": "https://playground.wordpress.net/blueprint-schema.json",
|
|
"landingPage": "/wp-admin/",
|
|
"preferredVersions": { "wp": "6.8", "php": "8.4" },
|
|
"steps": [
|
|
{ "step": "login", "username": "admin", "password": "password" },
|
|
{ "step": "installPlugin", "pluginData": { "resource": "url", "url": "http://127.0.0.1:8889/plugin-check.zip" }, "options": { "activate": true } },
|
|
{ "step": "installPlugin", "pluginData": { "resource": "url", "url": "http://127.0.0.1:8889/$(basename "$PLUGIN_ZIP")" }, "options": { "activate": true } }
|
|
]
|
|
}
|
|
BPEOF
|
|
|
|
echo "[pcp] 启动 Playground (port $PORT)..."
|
|
npx @wp-playground/cli@3.0.52 server --port=$PORT --login --blueprint="$BLUEPRINT" &>/dev/null &
|
|
PG_PID=$!
|
|
trap "kill $HTTP_PID $PG_PID 2>/dev/null; rm -rf $SERVE_DIR $BLUEPRINT" EXIT
|
|
|
|
# 等待 Playground 就绪
|
|
echo "[pcp] 等待 Playground..."
|
|
for i in $(seq 1 30); do
|
|
if curl -s "http://localhost:$PORT/" >/dev/null 2>&1; then break; fi
|
|
sleep 2
|
|
done
|
|
|
|
# 通过 Playground 的 PHP 执行 WP-CLI plugin check
|
|
echo "[pcp] 运行 Plugin Check..."
|
|
node -e "
|
|
const http = require('http');
|
|
const php = \`
|
|
<?php
|
|
// Bootstrap WordPress
|
|
define('ABSPATH', '/wordpress/');
|
|
require_once ABSPATH . 'wp-load.php';
|
|
|
|
// Run plugin check via WP-CLI if available
|
|
if (class_exists('WP_CLI')) {
|
|
WP_CLI::run_command(['plugin', 'check', '${PLUGIN_NAME}', '--format=json']);
|
|
} else {
|
|
// Fallback: use PCP API directly
|
|
if (function_exists('wp_plugin_check_get_checks')) {
|
|
echo json_encode(['status' => 'pcp_loaded', 'note' => 'Direct API not implemented yet']);
|
|
} else {
|
|
echo json_encode(['status' => 'pcp_not_found']);
|
|
}
|
|
}
|
|
\`;
|
|
// For now, just verify PCP is active
|
|
http.get('http://localhost:${PORT}/wp-admin/admin.php?page=plugin-check', (res) => {
|
|
let data = '';
|
|
res.on('data', c => data += c);
|
|
res.on('end', () => {
|
|
const active = data.includes('plugin-check') || data.includes('Plugin Check');
|
|
console.log(JSON.stringify({ pcpActive: active, statusCode: res.statusCode }));
|
|
});
|
|
}).on('error', e => console.log(JSON.stringify({ error: e.message })));
|
|
" > "$OUTPUT_DIR/pcp-status.json"
|
|
|
|
echo "[pcp] 结果: $OUTPUT_DIR/pcp-status.json"
|
|
cat "$OUTPUT_DIR/pcp-status.json"
|
|
|
|
# 清理
|
|
kill $PG_PID 2>/dev/null || true
|