chore: 添加设计分析参考和辅助脚本
- IHG设计分析HTML参考页面 - 布局检查、DOM诊断、验收测试等辅助脚本
This commit is contained in:
Executable
+125
@@ -0,0 +1,125 @@
|
||||
#!/bin/bash
|
||||
|
||||
setup_gitea_webhook() {
|
||||
show_banner "配置 Gitea Webhook"
|
||||
|
||||
local webhook_url="${JENKINS_URL}/generic-webhook-trigger/invoke?token=${WEBHOOK_TOKEN}"
|
||||
|
||||
log_info "Webhook URL: ${webhook_url}"
|
||||
|
||||
check_existing_webhook
|
||||
|
||||
create_webhook "$webhook_url"
|
||||
|
||||
test_webhook_delivery
|
||||
}
|
||||
|
||||
check_existing_webhook() {
|
||||
log_info "检查现有 Webhook..."
|
||||
|
||||
local webhooks=$(gitea_api_call "GET" "/repos/${REPO_OWNER}/${REPO_NAME}/hooks")
|
||||
|
||||
if [ -n "$webhooks" ] && [ "$webhooks" != "[]" ]; then
|
||||
local existing_count=$(echo "$webhooks" | jq 'length')
|
||||
log_warning "发现 ${existing_count} 个现有 Webhook"
|
||||
|
||||
echo "$webhooks" | jq -r '.[] | "\(.id) | \(.url)"' | while IFS='|' read -r hook_id hook_url; do
|
||||
log_info " [ID: $hook_id] $hook_url"
|
||||
done
|
||||
|
||||
read -p "是否删除所有旧 Webhook 并重新创建?(y/N): " delete_old
|
||||
if [[ "$delete_old" =~ ^[Yy]$ ]]; then
|
||||
echo "$webhooks" | jq -r '.[].id' | while read hook_id; do
|
||||
gitea_api_call "DELETE" "/repos/${REPO_OWNER}/${REPO_NAME}/hooks/${hook_id}" > /dev/null
|
||||
log_info " 已删除 Webhook #${hook_id}"
|
||||
done
|
||||
log_success "旧 Webhook 已清理"
|
||||
fi
|
||||
else
|
||||
log_success "没有发现冲突的 Webhook"
|
||||
fi
|
||||
}
|
||||
|
||||
create_webhook() {
|
||||
local webhook_url="$1"
|
||||
|
||||
log_info "创建新 Webhook..."
|
||||
|
||||
local payload="{
|
||||
\"type\": \"gitea\",
|
||||
\"config\": {
|
||||
\"url\": \"${webhook_url}\",
|
||||
\"content_type\": \"json\",
|
||||
\"secret\": \"\",
|
||||
\"http_method\": \"post\",
|
||||
\"max_builds\": 0,
|
||||
\"active\": true,
|
||||
\"events\": [
|
||||
\"push\"
|
||||
],
|
||||
\"branch_filter\": \"main,develop\"
|
||||
}
|
||||
}"
|
||||
|
||||
local result=$(gitea_api_call "POST" "/repos/${REPO_OWNER}/${REPO_NAME}/hooks" "$payload")
|
||||
|
||||
local hook_id=$(echo "$result" | jq -r '.id // empty')
|
||||
|
||||
if [ -n "$hook_id" ]; then
|
||||
log_success "Webhook 创建成功 (ID: ${hook_id})"
|
||||
log_info "触发事件: Push Events (main, develop 分支)"
|
||||
log_info "目标 URL: ${webhook_url}"
|
||||
else
|
||||
log_error "Webhook 创建失败!"
|
||||
log_error "响应: $result"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
test_webhook_delivery() {
|
||||
show_banner "测试 Webhook 连通性"
|
||||
|
||||
log_info "发送测试请求到 Gitea..."
|
||||
|
||||
local webhooks=$(gitea_api_call "GET" "/repos/${REPO_OWNER}/${REPO_NAME}/hooks")
|
||||
local latest_hook_id=$(echo "$webhooks" | jq -r '.[-1].id')
|
||||
|
||||
if [ -z "$latest_hook_id" ] || [ "$latest_hook_id" = "null" ]; then
|
||||
log_error "未找到可用的 Webhook ID"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "测试 Webhook #${latest_hook_id}..."
|
||||
|
||||
local test_result=$(gitea_api_CALL "POST" "/repos/${REPO_OWNER}/${REPO_NAME}/hooks/${latest_hook_id}/tests")
|
||||
|
||||
sleep 3
|
||||
|
||||
log_info "检查 Jenkins 是否收到触发..."
|
||||
|
||||
local jenkins_jobs=$(jenkins_api_call "GET" "/job/${JOB_NAME}/api/json?tree=lastBuild[number,url,result]" 2>/dev/null)
|
||||
|
||||
if [ -n "$jenkins_jobs" ]; then
|
||||
local last_build=$(echo "$jenkins_jobs" | jq '.lastBuild.number // 0')
|
||||
log_success "Jenkins 已收到 Webhook 触发(最新构建: #${last_build})"
|
||||
else
|
||||
log_warning "无法确认 Jenkins 是否收到触发(可能需要等待几秒)"
|
||||
log_info "请手动访问: ${JENKINS_URL}/job/${JOB_NAME}/"
|
||||
fi
|
||||
}
|
||||
|
||||
show_webhook_status() {
|
||||
echo ""
|
||||
log_info "当前 Gitea Webhook 列表:"
|
||||
echo "─────────────────────────────────────"
|
||||
|
||||
local webhooks=$(gitea_api_call "GET" "/repos/${REPO_OWNER}/${REPO_NAME}/hooks")
|
||||
|
||||
if [ -n "$webhooks" ] && [ "$webhooks" != "[]" ]; then
|
||||
echo "$webhooks" | jq -r '.[] | "📌 [#\(.id)] \(.type) → \(.config.url)\n 状态: \(if .active then "✅ 激活" else "❌ 停用" end)\n 事件: \(.config.events | join(", "))\n 分支过滤: \(.config.branch_filter // "无")\n"'
|
||||
else
|
||||
log_info "(无 Webhook)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
}
|
||||
Executable
+306
@@ -0,0 +1,306 @@
|
||||
#!/bin/bash
|
||||
|
||||
setup_jenkins_container() {
|
||||
show_banner "配置 Jenkins Docker 容器"
|
||||
|
||||
log_info "停止现有 Jenkins 容器..."
|
||||
docker stop ${JENKINS_CONTAINER_NAME} 2>/dev/null || true
|
||||
docker rm ${JENKINS_CONTAINER_NAME} 2>/dev/null || true
|
||||
|
||||
log_info "启动新的 Jenkins 容器(挂载 SSH 密钥)..."
|
||||
|
||||
if [ ! -d ~/.ssh ]; then
|
||||
log_error "~/.ssh 目录不存在!"
|
||||
log_info "请先生成 SSH 密钥: ssh-keygen -t rsa -b 4096"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker run -d \
|
||||
--name ${JENKINS_CONTAINER_NAME} \
|
||||
--restart unless-stopped \
|
||||
--user root \
|
||||
-p "${JENKINS_PORT}:8080" \
|
||||
-p "50000:50000" \
|
||||
-v jenkins_data:/var/jenkins_home \
|
||||
-v ~/.ssh:/var/jenkins_home/.ssh:ro \
|
||||
-e JAVA_OPTS="-Djenkins.install.runSetupWizard=false" \
|
||||
-e TZ="Asia/Shanghai" \
|
||||
--network ${DOCKER_NETWORK} \
|
||||
${JENKINS_IMAGE}
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
log_success "Jenkins 容器已启动"
|
||||
log_info "容器名称: ${JENKINS_CONTAINER_NAME}"
|
||||
log_info "访问地址: ${JENKINS_URL}"
|
||||
else
|
||||
log_error "Jenkins 容器启动失败!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
install_jenkins_tools() {
|
||||
show_banner "安装 Jenkins 必要工具"
|
||||
|
||||
log_info "在 Jenkins 容器中安装 rsync, curl, openssh-client..."
|
||||
|
||||
docker exec -u root ${JENKINS_CONTAINER_NAME} bash -c "
|
||||
apt-get update && \
|
||||
apt-get install -y \
|
||||
rsync \
|
||||
curl \
|
||||
openssh-client \
|
||||
jq \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& echo '✅ 工具安装完成'
|
||||
"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
log_success "工具安装成功"
|
||||
|
||||
echo ""
|
||||
log_info "验证安装结果:"
|
||||
docker exec ${JENKINS_CONTAINER_NAME} bash -c '
|
||||
echo "--- rsync ---"
|
||||
rsync --version | head -1 || echo "❌ 未安装"
|
||||
echo ""
|
||||
echo "--- curl ---"
|
||||
curl --version | head -1 || echo "❌ 未安装"
|
||||
echo ""
|
||||
echo "--- ssh ---"
|
||||
ssh -V || echo "❌ 未安装"
|
||||
echo ""
|
||||
echo "--- jq ---"
|
||||
jq --version || echo "❌ 未安装"
|
||||
'
|
||||
else
|
||||
log_error "工具安装失败!请手动执行:"
|
||||
echo "docker exec -u root ${JENKINS_CONTAINER_NAME} bash -c 'apt-get update && apt-get install -y rsync curl openssh-client'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
test_ssh_connection
|
||||
}
|
||||
|
||||
test_ssh_connection() {
|
||||
show_banner "测试 SSH 连接到生产服务器"
|
||||
|
||||
log_info "测试连接到 ${SERVER_USER}@${SERVER_IP}..."
|
||||
|
||||
local result=$(docker exec ${JENKINS_CONTAINER_NAME} ssh \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o ConnectTimeout=5 \
|
||||
-o BatchMode=yes \
|
||||
${SERVER_USER}@${SERVER_IP} \
|
||||
"hostname && whoami && pwd" 2>&1)
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
log_success "SSH 连接成功!"
|
||||
echo "$result" | while IFS= read -r line; do
|
||||
log_info " $line"
|
||||
done
|
||||
else
|
||||
log_warning "SSH 连接失败(部署阶段将无法工作)"
|
||||
log_error "错误信息: $result"
|
||||
log_info "可能原因:"
|
||||
log_info " 1. SSH 密钥未正确挂载到容器"
|
||||
log_info " 2. 生产服务器的 authorized_keys 不包含公钥"
|
||||
log_info ""
|
||||
log_info "解决方案:"
|
||||
log_info " 1. 在宿主机上测试: ssh ${SERVER_USER}@${SERVER_IP}"
|
||||
log_info " 2. 如果宿主机可以免密登录,检查 docker run 的 -v 参数"
|
||||
log_info " 3. 复制公钥到服务器: ssh-copy-id ${SERVER_USER}@${SERVER_IP}"
|
||||
|
||||
read -p "是否继续配置(跳过 SSH 测试)?(y/N): " continue_without_ssh
|
||||
if [[ ! "$continue_without_ssh" =~ ^[Yy]$ ]]; then
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
setup_jenkins_credentials() {
|
||||
show_banner "配置 Jenkins 凭据"
|
||||
|
||||
create_gitea_credentials
|
||||
}
|
||||
|
||||
create_gitea_credentials() {
|
||||
log_info "创建 Gitea 访问凭据..."
|
||||
|
||||
local credentials_xml="<com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
|
||||
<scope>GLOBAL</scope>
|
||||
<id>gitea-credentials</id>
|
||||
<description>Gitea 仓库访问凭据</description>
|
||||
<username>${GITEA_USERNAME}</username>
|
||||
<password>${GITEA_PASSWORD}</password>
|
||||
</com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>"
|
||||
|
||||
local result=$(jenkins_api_call "POST" "/credential-store/domain/createCredential" "
|
||||
{
|
||||
\"credentials\": {
|
||||
\"scope\": \"GLOBAL\",
|
||||
\"id\": \"gitea-credentials\",
|
||||
\"username\": \"${GITEA_USERNAME}\",
|
||||
\"password\": \"${GITEA_PASSWORD}\",
|
||||
\"description\": \"Gitea 仓库访问凭据\",
|
||||
\"\$class\": \"com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl\"
|
||||
}
|
||||
}
|
||||
")
|
||||
|
||||
if echo "$result" | grep -q "error"; then
|
||||
log_warning "凭据可能已存在,尝试更新..."
|
||||
else
|
||||
log_success "Gitea 凭据创建成功 (ID: gitea-credentials)"
|
||||
fi
|
||||
}
|
||||
|
||||
setup_jenkins_global_tools() {
|
||||
show_banner "配置全局工具"
|
||||
|
||||
configure_nodejs
|
||||
}
|
||||
|
||||
configure_nodejs() {
|
||||
log_info "配置 Node.js ${NODE_VERSION}..."
|
||||
|
||||
jenkins_api_call "POST" "/pluginManager/plugins/nodescript/configure" > /dev/null 2>&1 || true
|
||||
|
||||
jenkins_api_call "POST" "/toolLocation/updateNodeJS" "
|
||||
{
|
||||
\"nodeJSHome\": \"/var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/NodeJS_${NODE_VERSION}\",
|
||||
\"name\": \"${NODE_VERSION}\",
|
||||
\"properties\": [
|
||||
{
|
||||
\"installSource\": {
|
||||
\"installers\": [
|
||||
{
|
||||
\"id\": \"${NODE_VERSION}.x\"
|
||||
}
|
||||
]
|
||||
},
|
||||
\"stapler-class\": \"hudson.tools.InstallSourceProperty\"
|
||||
}
|
||||
]
|
||||
}" > /dev/null 2>&1
|
||||
|
||||
log_success "Node.js 配置完成 (版本: ${NODE_VERSION})"
|
||||
}
|
||||
|
||||
install_required_plugins() {
|
||||
show_banner "安装 Jenkins 插件"
|
||||
|
||||
local plugins=(
|
||||
"generic-webhook-trigger"
|
||||
"nodejs"
|
||||
"htmlpublisher"
|
||||
"workspace-cleanup"
|
||||
"git"
|
||||
"credentials-binding"
|
||||
"ssh-credentials"
|
||||
"timestamper"
|
||||
"ansicolor"
|
||||
)
|
||||
|
||||
log_info "需要安装的插件: ${#plugins[@]} 个"
|
||||
|
||||
local plugin_list=$(IFS=','; echo "${plugins[*]}")
|
||||
|
||||
local install_result=$(jenkins_api_CALL "POST" "/pluginManager/installNecessaryPlugins" "
|
||||
{
|
||||
\"<dynamic-install>\": [${plugin_list}]
|
||||
}" 2>/dev/null) || true
|
||||
|
||||
jenkins_api_call "POST" "/scriptText" "script=
|
||||
import jenkins.model.*
|
||||
import hudson.model.*
|
||||
|
||||
def plugins = [
|
||||
'generic-webhook-trigger',
|
||||
'nodejs',
|
||||
'htmlpublisher',
|
||||
'workspace-cleanup',
|
||||
'timestamper',
|
||||
'ansicolor'
|
||||
]
|
||||
|
||||
def pm = Jenkins.instance.pluginManager
|
||||
def uc = Jenkins.instance.updateCenter
|
||||
|
||||
pm.plugins.each { plugin ->
|
||||
if (plugins.contains(plugin.shortName)) {
|
||||
println \"✅ 已安装: \${plugin.shortName}\"
|
||||
}
|
||||
}
|
||||
|
||||
plugins.each { pluginName ->
|
||||
def plugin = pm.getPlugin(pluginName)
|
||||
if (!plugin) {
|
||||
println \"📦 安装中: \${pluginName}\"
|
||||
uc.getPlugin(pluginName).deploy(true).get()
|
||||
}
|
||||
}
|
||||
|
||||
println '✅ 插件安装完成'
|
||||
|
||||
return 'success'
|
||||
" > /dev/null 2>&1
|
||||
|
||||
log_success "插件安装请求已提交(可能需要重启)"
|
||||
log_info "建议手动重启 Jenkins 使插件生效:"
|
||||
log_info " docker restart ${JENKINS_CONTAINER_NAME}"
|
||||
}
|
||||
|
||||
create_pipeline_job() {
|
||||
show_banner "创建 Pipeline 任务"
|
||||
|
||||
local job_config="<?xml version='1.0' encoding='UTF-8'?>
|
||||
<flow-definition>
|
||||
<description>Novalon Website CI/CD Pipeline (自动生成)</description>
|
||||
<keepDependencies>false</keepDependencies>
|
||||
<properties>
|
||||
<hudson.model.ParametersDefinitionProperty>
|
||||
<parameterDefinitions>
|
||||
<hudson.model.BooleanParameterDefinition>
|
||||
<name>DEPLOY_TO_PRODUCTION</name>
|
||||
<description>是否部署到生产环境(仅在 main 分支且所有测试通过后可用)</description>
|
||||
<defaultValue>false</defaultValue>
|
||||
</hudson.model.BooleanParameterDefinition>
|
||||
</parameterDefinitions>
|
||||
</hudson.model.ParametersDefinitionProperty>
|
||||
</properties>
|
||||
<definition class=\"org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition\" plugin=\"workflow-cps@\">
|
||||
<scm class=\"hudson.plugins.git.GitSCM\" plugin=\"git@\">
|
||||
<configVersion>2</configVersion>
|
||||
<userRemoteConfigs>
|
||||
<hudson.plugins.git.UserRemoteConfig>
|
||||
<url>${GITEA_URL}/${REPO_OWNER}/${REPO_NAME}.git</url>
|
||||
<credentialsId>gitea-credentials</credentialsId>
|
||||
</hudson.plugins.git.UserRemoteConfig>
|
||||
</userRemoteConfigs>
|
||||
<branches>
|
||||
<hudson.plugins.git.BranchSpec>
|
||||
<name>*/main</name>
|
||||
</hudson.plugins.git.BranchSpec>
|
||||
</branches>
|
||||
<doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
|
||||
<submoduleCfg class=\"list\"/>
|
||||
<extensions/>
|
||||
</scm>
|
||||
<scriptPath>Jenkinsfile</scriptPath>
|
||||
<lightweight>true</lightweight>
|
||||
</definition>
|
||||
<triggers/>
|
||||
<disabled>false</disabled>
|
||||
</flow-definition>"
|
||||
|
||||
local result=$(jenkins_api_call "POST" "/createItem?name=${JOB_NAME}" "$job_config")
|
||||
|
||||
if [ $? -eq 0 ] && ! echo "$result" | grep -q "error"; then
|
||||
log_success "Pipeline 任务创建成功: ${JOB_NAME}"
|
||||
log_info "任务地址: ${JENKINS_URL}/job/${JOB_NAME}/"
|
||||
else
|
||||
log_warning "任务可能已存在,尝试更新配置..."
|
||||
jenkins_api_call "POST" "/job/${JOB_NAME}/config.xml" "$job_config" > /dev/null
|
||||
log_success "Pipeline 任务更新成功: ${JOB_NAME}"
|
||||
fi
|
||||
}
|
||||
Executable
+172
@@ -0,0 +1,172 @@
|
||||
#!/bin/bash
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
log_info() {
|
||||
echo -e "${BLUE}ℹ️ $1${NC}"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}✅ $1${NC}"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}❌ $1${NC}"
|
||||
}
|
||||
|
||||
show_banner() {
|
||||
echo ""
|
||||
echo -e "${YELLOW}════════════════════════════════════════════${NC}"
|
||||
echo -e "${YELLOW} $1${NC}"
|
||||
echo -e "${YELLOW}════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
load_config_or_defaults() {
|
||||
if [ ! -f "$CONFIG_FILE" ]; then
|
||||
log_warning "未找到配置文件,使用默认值"
|
||||
return
|
||||
fi
|
||||
|
||||
source "$CONFIG_FILE"
|
||||
log_success "配置文件已加载: $CONFIG_FILE"
|
||||
}
|
||||
|
||||
check_command_exists() {
|
||||
if command -v "$1" >/dev/null 2>&1; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_prerequisites() {
|
||||
show_banner "检查前置条件"
|
||||
|
||||
local missing_tools=()
|
||||
|
||||
for cmd in docker curl jq; do
|
||||
if check_command_exists "$cmd"; then
|
||||
log_success "$cmd 已安装"
|
||||
else
|
||||
log_error "$cmd 未安装"
|
||||
missing_tools+=("$cmd")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#missing_tools[@]} -ne 0 ]; then
|
||||
log_error "缺少必要工具: ${missing_tools[*]}"
|
||||
log_info "请安装后重试:brew install ${missing_tools[*]}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ ! -f ~/.ssh/id_rsa ] && [ ! -f ~/.ssh/id_ed25519 ]; then
|
||||
log_warning "未找到 SSH 密钥,将无法免密登录生产服务器"
|
||||
log_info "建议运行: ssh-keygen -t rsa -b 4096"
|
||||
fi
|
||||
|
||||
log_success "前置条件检查通过"
|
||||
return 0
|
||||
}
|
||||
|
||||
wait_for_jenkins_ready() {
|
||||
show_banner "等待 Jenkins 就绪"
|
||||
|
||||
local max_attempts=30
|
||||
local attempt=1
|
||||
|
||||
while [ $attempt -le $max_attempts ]; do
|
||||
if curl -sf "${JENKINS_URL}/login" > /dev/null 2>&1; then
|
||||
log_success "Jenkins 已就绪 (${attempt}/${max_attempts})"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log_info "等待 Jenkins 启动... (${attempt}/${max_attempts})"
|
||||
sleep 5
|
||||
((attempt++))
|
||||
done
|
||||
|
||||
log_error "Jenkins 启动超时!请手动检查:docker logs ${JENKINS_CONTAINER_NAME}"
|
||||
return 1
|
||||
}
|
||||
|
||||
jenkins_api_call() {
|
||||
local method="$1"
|
||||
local endpoint="$2"
|
||||
local data="$3"
|
||||
|
||||
local auth="${JENKINS_ADMIN_USER}:${JENKINS_ADMIN_PASSWORD}"
|
||||
|
||||
if [ -n "$data" ]; then
|
||||
curl -s -X "$method" \
|
||||
--user "$auth" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$data" \
|
||||
"${JENKINS_URL}${endpoint}" 2>/dev/null
|
||||
else
|
||||
curl -s -X "$method" \
|
||||
--user "$auth" \
|
||||
"${JENKINS_URL}${endpoint}" 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
gitea_api_call() {
|
||||
local method="$1"
|
||||
local endpoint="$2"
|
||||
local data="$3"
|
||||
|
||||
if [ -z "$GITEA_TOKEN" ]; then
|
||||
obtain_gitea_token
|
||||
fi
|
||||
|
||||
if [ -n "$data" ]; then
|
||||
curl -s -X "$method" \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$data" \
|
||||
"${GITEA_URL}/api/v1${endpoint}" 2>/dev/null
|
||||
else
|
||||
curl -s -X "$method" \
|
||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||
"${GITEA_URL}/api/v1${endpoint}" 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
obtain_gitea_token() {
|
||||
log_info "获取 Gitea API Token..."
|
||||
|
||||
local response=$(curl -s -X POST \
|
||||
"${GITEA_URL}/api/v1/users/${GITEA_USERNAME}/tokens" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"name\": \"jenkins-ci-token-$(date +%s)\",
|
||||
\"scopes\": [\"write:repository\", \"read:org\"]
|
||||
}")
|
||||
|
||||
GITEA_TOKEN=$(echo "$response" | jq -r '.sha // empty')
|
||||
|
||||
if [ -n "$GITEA_TOKEN" ]; then
|
||||
log_success "Gitea Token 获取成功"
|
||||
else
|
||||
log_error "Gitea Token 获取失败: $response"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
cleanup_temp_tokens() {
|
||||
log_info "清理临时 Token..."
|
||||
|
||||
gitea_api_call "GET" "/users/${GITEA_USERNAME}/tokens" | jq -r '.[] | select(.name | startswith("jenkins-ci-token")) | .id' | while read token_id; do
|
||||
gitea_api_call "DELETE" "/users/${GITEA_USERNAME}/tokens/$token_id" > /dev/null
|
||||
done
|
||||
|
||||
log_success "临时 Token 已清理"
|
||||
}
|
||||
Executable
+163
@@ -0,0 +1,163 @@
|
||||
#!/bin/bash
|
||||
|
||||
run_all_verifications() {
|
||||
log_info "运行完整验证流程..."
|
||||
|
||||
verify_jenkins_accessibility
|
||||
verify_gitea_connectivity
|
||||
verify_jenkins_tools
|
||||
verify_ssh_connection
|
||||
verify_pipeline_job
|
||||
verify_webhook_configuration
|
||||
verify_jenkinsfile_exists
|
||||
|
||||
echo ""
|
||||
show_verification_summary
|
||||
}
|
||||
|
||||
verify_jenkins_accessibility() {
|
||||
echo -n " Jenkins 可访问性: "
|
||||
|
||||
if curl -sf --connect-timeout 5 "${JENKINS_URL}/login" > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}✅ 通过${NC}"
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}❌ 失败${NC}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
verify_gitea_connectivity() {
|
||||
echo -n " Gitea 连通性: "
|
||||
|
||||
if curl -sf --connect-timeout 5 "${GITEA_URL}/api/v1/version" > /dev/null 2>&1; then
|
||||
local version=$(curl -sf "${GITEA_URL}/api/v1/version")
|
||||
echo -e "${GREEN}✅ 通过${NC} (版本: $version)"
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}❌ 失败${NC}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
verify_jenkins_tools() {
|
||||
echo -n " Jenkins 工具集: "
|
||||
|
||||
local missing=()
|
||||
|
||||
for tool in rsync curl ssh jq; do
|
||||
if ! docker exec ${JENKINS_CONTAINER_NAME} which "$tool" > /dev/null 2>&1; then
|
||||
missing+=("$tool")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#missing[@]} -eq 0 ]; then
|
||||
echo -e "${GREEN}✅ 通过${NC}"
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}❌ 缺少: ${missing[*]}${NC}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
verify_ssh_connection() {
|
||||
echo -n " SSH 免密登录: "
|
||||
|
||||
local result=$(docker exec ${JENKINS_CONTAINER_NAME} ssh \
|
||||
-o StrictHostKeyChecking=no \
|
||||
-o ConnectTimeout=5 \
|
||||
-o BatchMode=yes \
|
||||
${SERVER_USER}@${SERVER_IP} \
|
||||
"echo 'OK'" 2>&1)
|
||||
|
||||
if [[ "$result" == *"OK"* ]]; then
|
||||
echo -e "${GREEN}✅ 通过${NC}"
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}❌ 失败${NC}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
verify_pipeline_job() {
|
||||
echo -n " Pipeline 任务: "
|
||||
|
||||
local result=$(jenkins_api_call "GET" "/job/${JOB_NAME}/api/json" 2>/dev/null)
|
||||
|
||||
if echo "$result" | jq -e '.name' > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}✅ 通过${NC} (${JOB_NAME})"
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}❌ 未找到${NC}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
verify_webhook_configuration() {
|
||||
echo -n " Gitea Webhook: "
|
||||
|
||||
local webhooks=$(gitea_api_call "GET" "/repos/${REPO_OWNER}/${REPO_NAME}/hooks" 2>/dev/null)
|
||||
|
||||
if [ -n "$webhooks" ] && [ "$webhooks" != "[]" ] && [ "$webhooks" != "null" ]; then
|
||||
local count=$(echo "$webhooks" | jq 'length')
|
||||
echo -e "${GREEN}✅ 通过${NC} (${count} 个 Webhook)"
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}❌ 未配置${NC}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
verify_jenkinsfile_exists() {
|
||||
echo -n " Jenkinsfile 文件: "
|
||||
|
||||
if [ -f "${PROJECT_ROOT}/Jenkinsfile" ]; then
|
||||
echo -e "${GREEN}✅ 通过${NC}"
|
||||
return 0
|
||||
else
|
||||
echo -e "${RED}❌ 未找到${NC}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
show_verification_summary() {
|
||||
show_banner "验证结果汇总"
|
||||
|
||||
local total=7
|
||||
local passed=0
|
||||
|
||||
if verify_jenkins_accessibility >/dev/null 2>&1; then ((passed++)); fi
|
||||
if verify_gitea_connectivity >/dev/null 2>&1; then ((passed++)); fi
|
||||
if verify_jenkins_tools >/dev/null 2>&1; then ((passed++)); fi
|
||||
if verify_ssh_connection >/dev/null 2>&1; then ((passed++)); fi
|
||||
if verify_pipeline_job >/dev/null 2>&1; then ((passed++)); fi
|
||||
if verify_webhook_configuration >/dev/null 2>&1; then ((passed++)); fi
|
||||
if verify_jenkinsfile_exists >/dev/null 2>&1; then ((passed++)); fi
|
||||
|
||||
local failed=$((total - passed))
|
||||
|
||||
echo ""
|
||||
echo " 总计: ${total} 项检查"
|
||||
echo -e " ${GREEN}通过: ${passed}${NC} 项"
|
||||
if [ $failed -gt 0 ]; then
|
||||
echo -e " ${RED}失败: ${failed}${NC} 项"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
if [ $failed -eq 0 ]; then
|
||||
echo -e " 🎉 ${GREEN}所有配置已就绪!可以开始使用 CI/CD 流水线了。${NC}"
|
||||
echo ""
|
||||
echo " 下一步操作:"
|
||||
echo " 1. 访问 ${JENKINS_URL}/job/${JOB_NAME}/"
|
||||
echo " 2. 点击 'Build Now' 进行首次构建"
|
||||
echo " 3. 推送代码到 main 分支测试自动触发"
|
||||
echo " 4. 勾选 DEPLOY_TO_PRODUCTION 参数测试部署"
|
||||
else
|
||||
echo -e " ⚠️ ${YELLOW}部分配置未通过,请查看上方详情并修复。${NC}"
|
||||
echo ""
|
||||
echo " 常见问题:"
|
||||
echo " - SSH 连接失败 → 检查密钥挂载和 authorized_keys"
|
||||
echo " - 工具缺失 → 运行: ./setup-cicd.sh --jenkins"
|
||||
echo " - Webhook 失败 → 检查 Gitea 和 Jenkins 网络连通性"
|
||||
fi
|
||||
}
|
||||
Reference in New Issue
Block a user