refactor: 整理脚本文件到 scripts 目录(任务 2.1/20)

This commit is contained in:
张翔
2026-04-12 15:16:41 +08:00
parent 337284166f
commit f6b9031cd7
28 changed files with 2486 additions and 239 deletions
+122
View File
@@ -0,0 +1,122 @@
#!/usr/bin/env python3
"""
Woodpecker CI 自动触发诊断工具
排查 CI 无法自动触发的可能原因
"""
import yaml
from pathlib import Path
def diagnose_auto_trigger(config_path):
"""诊断自动触发问题"""
with open(config_path, 'r', encoding='utf-8') as f:
config = yaml.safe_load(f)
print("="*70)
print("Woodpecker CI 自动触发诊断")
print("="*70)
print("\n🔍 可能导致 CI 无法自动触发的原因:")
print("-"*70)
reasons = [
{
"原因": "1. Webhook 未配置或配置错误",
"检查": "Git 仓库设置 → Webhooks → 确认有指向 Woodpecker CI 的 Webhook",
"解决": "添加 WebhookURL 格式: http://woodpecker-server/hook"
},
{
"原因": "2. Woodpecker CI 仓库未激活",
"检查": "Woodpecker CI Web 界面 → 确认仓库已激活",
"解决": "在 Woodpecker CI 中激活仓库"
},
{
"原因": "3. 分支保护或限制",
"检查": "Woodpecker CI 仓库设置 → 查看 'Trusted''Protected' 设置",
"解决": "取消分支保护或添加受信任的分支"
},
{
"原因": "4. 配置文件语法错误",
"检查": "使用 yamllint 或在线 YAML 验证器检查配置文件",
"解决": "修复 YAML 语法错误"
},
{
"原因": "5. when 条件过于严格",
"检查": "检查配置文件中的 when 条件",
"解决": "确保 when 条件包含正确的分支和事件"
},
{
"原因": "6. Woodpecker CI 全局配置限制",
"检查": "检查 Woodpecker CI 的全局配置文件",
"解决": "修改全局配置,允许自动触发"
},
{
"原因": "7. Git 仓库权限问题",
"检查": "确认 Woodpecker CI 有访问仓库的权限",
"解决": "重新授权 Woodpecker CI 访问仓库"
},
{
"原因": "8. 提交信息包含跳过关键词",
"检查": "检查提交信息是否包含 [skip ci], [ci skip] 等",
"解决": "避免在提交信息中使用跳过关键词"
}
]
for i, reason in enumerate(reasons, 1):
print(f"\n{reason['原因']}")
print(f" 检查: {reason['检查']}")
print(f" 解决: {reason['解决']}")
# 检查配置文件中的 when 条件
print("\n\n📋 当前配置的 when 条件:")
print("-"*70)
for step_name, step_config in config.get('steps', {}).items():
if not isinstance(step_config, dict):
continue
when = step_config.get('when', {})
if not when:
continue
if isinstance(when, dict):
events = when.get('event', [])
branches = when.get('branch', [])
if events or branches:
print(f"\n步骤: {step_name}")
if events:
print(f" 事件: {events}")
if branches:
print(f" 分支: {branches}")
elif isinstance(when, list):
print(f"\n步骤: {step_name}")
for condition in when:
if isinstance(condition, dict):
events = condition.get('event', [])
branches = condition.get('branch', [])
if events:
print(f" 事件: {events}")
if branches:
print(f" 分支: {branches}")
print("\n\n💡 快速排查步骤:")
print("="*70)
print("1. 访问 Git 仓库设置 → Webhooks")
print(" - 确认有 Woodpecker CI 的 Webhook")
print(" - 查看 'Recent Deliveries' 是否有发送记录")
print("\n2. 访问 Woodpecker CI Web 界面")
print(" - 确认仓库已激活")
print(" - 检查仓库设置中的 'Trusted' 选项")
print("\n3. 查看提交记录")
print(" - 确认提交信息不包含 [skip ci] 等关键词")
print("\n4. 手动触发测试")
print(" - 在 Woodpecker CI 中手动触发 Pipeline")
print(" - 观察是否能够正常执行")
print("\n" + "="*70)
if __name__ == "__main__":
diagnose_auto_trigger(".woodpecker.yml")
+48
View File
@@ -0,0 +1,48 @@
#!/bin/bash
echo "=========================================="
echo "CI/CD 问题诊断脚本"
echo "=========================================="
echo ""
echo "📋 问题1: Git LFS 配置检查"
echo "----------------------------------------"
if command -v git-lfs &> /dev/null; then
echo "✅ Git LFS 已安装"
git lfs version
else
echo "❌ Git LFS 未安装"
fi
if [ -f ".gitattributes" ]; then
echo "✅ .gitattributes 文件存在"
cat .gitattributes
else
echo "❌ .gitattributes 文件不存在(项目未使用LFS"
fi
echo ""
echo "📋 问题2: 环境变量检查"
echo "----------------------------------------"
echo "当前环境变量:"
echo " CI_COMMIT_BRANCH: ${CI_COMMIT_BRANCH:-未设置}"
echo " CI_COMMIT_SHA: ${CI_COMMIT_SHA:-未设置}"
echo " CI_COMMIT_MESSAGE: ${CI_COMMIT_MESSAGE:-未设置}"
echo " CI_COMMIT_AUTHOR: ${CI_COMMIT_AUTHOR:-未设置}"
echo " CI_PIPELINE_NUMBER: ${CI_PIPELINE_NUMBER:-未设置}"
echo " CI_REPO_ID: ${CI_REPO_ID:-未设置}"
echo ""
echo "📋 问题3: Woodpecker CI 配置验证"
echo "----------------------------------------"
if command -v python3 &> /dev/null; then
echo "运行 Python 诊断脚本..."
python3 diagnose-woodpecker.py 2>/dev/null || echo "诊断脚本执行失败"
else
echo "⚠️ Python3 未安装,跳过配置验证"
fi
echo ""
echo "=========================================="
echo "诊断完成"
echo "=========================================="
@@ -0,0 +1,37 @@
#!/bin/bash
echo "=== Woodpecker CI Webhook 诊断 ==="
echo ""
echo "1. 检查 Forgejo Webhook 配置..."
echo " Webhook URL: https://ci.f.novalon.cn/api/hook?access_token=..."
echo " Content Type: application/json"
echo " Trigger: push"
echo ""
echo "2. 检查 Woodpecker CI 期望的 Header..."
echo " X-Gitea-Event: push"
echo " X-Gitea-Delivery: <uuid>"
echo " X-Gitea-Signature: <signature>"
echo ""
echo "3. 检查 Nginx 配置..."
docker exec novalon-nginx cat /etc/nginx/conf.d/ci.f.novalon.cn.conf | grep -A 15 "location /api/"
echo ""
echo "4. 测试 Webhook 接收..."
echo " 发送测试 webhook..."
curl -X POST \
-H "Content-Type: application/json" \
-H "X-Gitea-Event: push" \
-H "X-Gitea-Delivery: test-123" \
-d '{"ref":"refs/heads/test"}' \
"https://ci.f.novalon.cn/api/hook?access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb3JnZS1pZCI6IjEiLCJyZXBvLWZvcmdlLXJlbW90ZS1pZCI6IjEiLCJ0eXBlIjoiaG9vayJ9.gu3mi1VAQfGB3d9HcuwWmMAcf-0BmmvQyGjqdiC20dA" \
-v 2>&1 | grep -E "(< HTTP|X-Gitea|hook)"
echo ""
echo "5. 检查 Woodpecker CI 日志..."
docker logs woodpecker-server --since 10s 2>&1 | grep -E "(hook|event|push)"
echo ""
echo "=== 诊断完成 ==="
+137
View File
@@ -0,0 +1,137 @@
#!/usr/bin/env python3
"""
Woodpecker CI 配置诊断工具
检查配置文件中可能导致 CI 未触发的问题
"""
import yaml
from pathlib import Path
def diagnose_woodpecker_config(config_path):
"""诊断 Woodpecker CI 配置"""
with open(config_path, 'r', encoding='utf-8') as f:
config = yaml.safe_load(f)
print("="*70)
print("Woodpecker CI 配置诊断报告")
print("="*70)
issues = []
warnings = []
# 检查是否有 steps
if 'steps' not in config:
issues.append("❌ 缺少 'steps' 配置")
else:
print(f"\n✅ 找到 {len(config['steps'])} 个步骤")
# 检查每个步骤的 when 条件
print("\n📋 步骤触发条件检查:")
print("-" * 70)
for step_name, step_config in config.get('steps', {}).items():
if not isinstance(step_config, dict):
continue
when = step_config.get('when', {})
if not when:
warnings.append(f"⚠️ 步骤 '{step_name}' 没有 when 条件,将始终执行")
continue
# 检查 when 条件的格式
if isinstance(when, list):
print(f"\n步骤: {step_name}")
print(f" when 条件格式: 列表(多个条件)")
for i, condition in enumerate(when):
if isinstance(condition, dict):
events = condition.get('event', [])
branches = condition.get('branch', [])
print(f" 条件 {i+1}:")
print(f" 事件: {events}")
print(f" 分支: {branches}")
elif isinstance(when, dict):
print(f"\n步骤: {step_name}")
print(f" when 条件格式: 字典(单个条件)")
events = when.get('event', [])
branches = when.get('branch', [])
print(f" 事件: {events}")
print(f" 分支: {branches}")
# 检查可能导致问题的配置
print("\n\n🔍 潜在问题分析:")
print("-" * 70)
# 检查是否有 skip_clone
if config.get('skip_clone'):
warnings.append("⚠️ skip_clone 设置为 true,可能影响代码获取")
# 检查 clone 配置
clone_config = config.get('clone', {})
if clone_config:
print(f"\nClone 配置: {clone_config}")
# 检查 services
services = config.get('services', {})
if services:
print(f"\n服务配置: {list(services.keys())}")
# 检查 workspace
workspace = config.get('workspace', {})
if workspace:
print(f"\n工作区配置: {workspace}")
# 输出问题
print("\n\n📊 诊断结果:")
print("="*70)
if issues:
print("\n❌ 发现的问题:")
for issue in issues:
print(f" {issue}")
if warnings:
print("\n⚠️ 警告:")
for warning in warnings:
print(f" {warning}")
if not issues and not warnings:
print("\n✅ 配置文件语法正确,未发现明显问题")
# 输出可能的原因
print("\n\n🔍 CI 未触发的可能原因:")
print("-" * 70)
possible_reasons = [
"1. Woodpecker CI 的 Webhook 未正确配置",
"2. Git 仓库设置中禁用了该分支的 CI 触发",
"3. Woodpecker CI 服务器未运行或配置错误",
"4. 配置文件中的分支匹配规则与 Woodpecker CI 版本不兼容",
"5. 需要在 Woodpecker CI 界面手动激活该仓库",
"6. Woodpecker CI 的全局配置限制了某些分支",
"7. 推送的提交信息触发了 CI 跳过(如包含 [skip ci]",
]
for reason in possible_reasons:
print(f" {reason}")
print("\n\n💡 建议的排查步骤:")
print("-" * 70)
suggestions = [
"1. 检查 Woodpecker CI Web 界面,确认仓库已激活",
"2. 检查 Git 仓库的 Webhook 设置",
"3. 查看 Woodpecker CI 的日志",
"4. 尝试手动触发 CI(如果支持)",
"5. 检查 Woodpecker CI 的全局配置",
"6. 创建一个简单的测试分支验证配置",
]
for suggestion in suggestions:
print(f" {suggestion}")
print("\n" + "="*70)
if __name__ == "__main__":
diagnose_woodpecker_config(".woodpecker.yml")