fix(jenkins): poll from Harbor API instead of k8s yaml, add FORCE_DEPLOY param

This commit is contained in:
wwweww
2026-05-04 02:55:19 +08:00
parent 590e5b0cd2
commit 4bdd040e91
+40 -23
View File
@@ -40,11 +40,15 @@ pipeline {
defaultValue: 'latest',
description: '要监听的镜像 Tag'
)
// 逗号分隔,留空则自动扫描所有服务
string(
name: 'TARGET_SERVICES',
defaultValue: '',
description: '指定要部署的服务(逗号分隔,如 user-api,user-rpc)。留空则部署所有有变化的服务'
description: '指定要部署的服务(逗号分隔,如 user-api,user-rpc)。留空则自动从 Harbor 查询实际存在的仓库'
)
booleanParam(
name: 'FORCE_DEPLOY',
defaultValue: false,
description: '强制部署所有服务(忽略 digest 对比,用于手动触发全量更新)'
)
}
@@ -81,22 +85,38 @@ pipeline {
// 构建要检查的服务列表
if (params.TARGET_SERVICES?.trim()) {
env.SERVICE_LIST = params.TARGET_SERVICES.trim()
echo "使用指定服务列表: ${env.SERVICE_LIST}"
} else {
// 自动从 deploy/k8s/service 目录扫描所有 Deployment 名称
// 命名规律:{service}-{api|rpc|mq}
// 直接查询 Harbor API,只监控实际存在的仓库
// 避免扫描 k8s yaml 导致检查大量不存在的镜像
withCredentials([
usernamePassword(
credentialsId: 'harbor-credentials',
usernameVariable: 'HARBOR_USER',
passwordVariable: 'HARBOR_PASS'
)
]) {
def services = sh(
script: '''
find deploy/k8s/service -name "*.yaml" \
| xargs grep -l "kind: Deployment" \
| xargs -I{} sh -c 'grep "^ name:" {} | head -1 | awk "{print \\$2}"' \
| sort -u \
| tr "\\n" ","
''',
script: """
curl -s -u "\${HARBOR_USER}:\${HARBOR_PASS}" \\
--connect-timeout 10 --max-time 30 \\
"${HARBOR_API}/projects/${params.HARBOR_PROJECT}/repositories?page_size=100" \\
| python3 -c "
import sys, json
repos = json.load(sys.stdin)
names = [r['name'].split('/')[-1] for r in repos if isinstance(repos, list)]
print(','.join(sorted(names)))
" 2>/dev/null || echo ""
""",
returnStdout: true
).trim().replaceAll(/,$/, '')
).trim()
if (!services) {
error("无法从 Harbor 获取仓库列表,请检查 harbor-credentials 凭据和 Harbor 地址")
}
env.SERVICE_LIST = services
}
echo "监控服务列表: ${env.SERVICE_LIST}"
echo "从 Harbor 自动发现服务列表: ${env.SERVICE_LIST}"
}
}
}
}
@@ -120,7 +140,6 @@ pipeline {
echo "检查镜像: ${svc}:${params.IMAGE_TAG}"
// 调用 Harbor API 获取最新 digest
def digestResult = sh(
script: """
curl -s -u "\${HARBOR_USER}:\${HARBOR_PASS}" \\
@@ -133,31 +152,29 @@ pipeline {
).trim()
if (!digestResult) {
echo " ⚠️ 无法获取 ${svc} 的 digest,跳过(服务可能尚未推送)"
echo " ⚠️ 无法获取 ${svc} 的 digest,跳过"
return
}
// 读取上次记录的 digest
def stateFile = "${DIGEST_STATE_DIR}/${svc}.digest"
def lastDigest = ""
if (fileExists(stateFile)) {
lastDigest = readFile(stateFile).trim()
}
def lastDigest = fileExists(stateFile) ? readFile(stateFile).trim() : ""
echo " 当前 digest: ${digestResult}"
echo " 上次 digest: ${lastDigest ?: '(首次检测)'}"
if (digestResult != lastDigest) {
if (params.FORCE_DEPLOY || digestResult != lastDigest) {
if (params.FORCE_DEPLOY) {
echo " 🔄 强制部署模式,加入部署队列"
} else {
echo " ✅ 检测到变化,加入部署队列"
}
changedServices << svc
// 立即更新 digest 记录,防止重复触发
writeFile file: stateFile, text: digestResult
} else {
echo " — 无变化,跳过"
}
}
// 将变化列表传递给下一个 Stage
env.CHANGED_SERVICES = changedServices.join(',')
echo "需要更新的服务: ${env.CHANGED_SERVICES ?: '(无变化)'}"
}