forked from Gitlink/gitlink-cli
feat: CI 检查改用本地编译验证,无需外部流水线
- 新增 03-local-ci-check.sh:运行 go build 验证代码可编译 - 质量门禁恢复为 4 阶段:PR采集 → 审查 → 本地CI → 决策 - 评分模型:CodeReview×40% + 本地CI×30% + 设计一致性×30% Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
3f4809bffb
commit
20f7f1fa43
|
|
@ -0,0 +1,72 @@
|
|||
#!/bin/bash
|
||||
# ================================================================
|
||||
# Phase 3: 本地 CI 检查
|
||||
# 功能:在本地验证 PR 的代码能否编译通过
|
||||
# 使用:bash 03-local-ci-check.sh <owner> <repo> <pr_id>
|
||||
# 无需外部流水线,直接运行 go build 验证
|
||||
# ================================================================
|
||||
set -e
|
||||
|
||||
OWNER=${1:?"Usage: $0 <owner> <repo> <pr_id>"}
|
||||
REPO=${2}
|
||||
PR_ID=${3}
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
OUTPUT_DIR="$SCRIPT_DIR/_output"
|
||||
mkdir -p "$OUTPUT_DIR"
|
||||
|
||||
echo "[========================================]"
|
||||
echo "[ Phase 3: 本地 CI 检查 ]"
|
||||
echo "[ PR #$PR_ID ($OWNER/$REPO) ]"
|
||||
echo "[========================================]"
|
||||
|
||||
CI_PASSING=false
|
||||
CI_DETAIL=""
|
||||
|
||||
# Step 1: 检查 Go 环境
|
||||
if ! command -v go &> /dev/null; then
|
||||
echo "[WARN] 未安装 Go,跳过本地编译检查"
|
||||
CI_DETAIL="未安装 Go,跳过"
|
||||
echo "unknown" > "$OUTPUT_DIR/ci-status-$PR_ID.txt"
|
||||
echo "$CI_DETAIL" > "$OUTPUT_DIR/ci-detail-$PR_ID.txt"
|
||||
echo "[INFO] CI 状态: unknown(Go 未安装)"
|
||||
echo ""
|
||||
echo "[========================================]"
|
||||
echo "[ Phase 3 完成 ]"
|
||||
echo "[========================================]"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Step 2: 本地编译验证
|
||||
echo "[INFO] 运行本地编译验证..."
|
||||
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
|
||||
|
||||
if [ -d "$PROJECT_ROOT" ] && [ -f "$PROJECT_ROOT/go.mod" ]; then
|
||||
BUILD_OUTPUT=$(cd "$PROJECT_ROOT" && go build -o /dev/null . 2>&1) || {
|
||||
echo "[WARN] ❌ 编译失败"
|
||||
echo "$BUILD_OUTPUT"
|
||||
CI_DETAIL="编译失败: $(echo "$BUILD_OUTPUT" | head -1)"
|
||||
echo "failing" > "$OUTPUT_DIR/ci-status-$PR_ID.txt"
|
||||
echo "$CI_DETAIL" > "$OUTPUT_DIR/ci-detail-$PR_ID.txt"
|
||||
echo "[INFO] CI 状态: failing"
|
||||
echo ""
|
||||
echo "[========================================]"
|
||||
echo "[ Phase 3 完成 ]"
|
||||
echo "[========================================]"
|
||||
exit 0
|
||||
}
|
||||
echo "[INFO] ✅ 编译成功"
|
||||
CI_PASSING=true
|
||||
CI_DETAIL="本地编译验证通过"
|
||||
echo "passing" > "$OUTPUT_DIR/ci-status-$PR_ID.txt"
|
||||
else
|
||||
echo "[WARN] 未找到 Go 项目,跳过本地编译检查"
|
||||
CI_DETAIL="未找到 Go 项目"
|
||||
echo "unknown" > "$OUTPUT_DIR/ci-status-$PR_ID.txt"
|
||||
fi
|
||||
|
||||
echo "$CI_DETAIL" > "$OUTPUT_DIR/ci-detail-$PR_ID.txt"
|
||||
echo "[INFO] CI 状态: $(cat "$OUTPUT_DIR/ci-status-$PR_ID.txt" 2>/dev/null || echo unknown)"
|
||||
echo ""
|
||||
echo "[========================================]"
|
||||
echo "[ Phase 3 完成 ]"
|
||||
echo "[========================================]"
|
||||
|
|
@ -22,30 +22,44 @@ echo "[ DRY_RUN: $DRY_RUN ]"
|
|||
echo "[========================================]"
|
||||
|
||||
# ---- 质量评分模型 ----
|
||||
# 评分 = CodeReview_Score × 60% + Design_Score × 40%
|
||||
# CodeReview_Score (0-100): 从 Phase 2 的审查结果获取
|
||||
# Design_Score (0-100): AI 评估 PR 描述与代码变更的匹配度
|
||||
#
|
||||
# 门槛:≥ 70 分 → 通过门禁
|
||||
# 评分 = CodeReview_Score × 40% + CI_Status × 30% + Design_Score × 30%
|
||||
# CI 来自本地编译验证(03-local-ci-check.sh),无需外部流水线
|
||||
|
||||
echo "[INFO] 评分计算中..."
|
||||
echo " 评分模型: 总分 = CodeReview×60% + 设计一致性×40%"
|
||||
echo " 门槛: ≥ 70 分"
|
||||
echo " 评分模型: 总分 = CodeReview×40% + CI×30% + 设计一致性×30%"
|
||||
echo " CI 来源: 本地编译验证(无需外部流水线)"
|
||||
echo " 门槛: ≥ 70 分且 CI 通过"
|
||||
echo ""
|
||||
|
||||
# 读取本地 CI 检查状态
|
||||
CI_FILE="$OUTPUT_DIR/ci-status-$PR_ID.txt"
|
||||
CI_STATUS_TEXT="unknown"
|
||||
if [ -f "$CI_FILE" ]; then
|
||||
CI_STATUS_TEXT=$(cat "$CI_FILE")
|
||||
fi
|
||||
|
||||
# 占位评分(AI 在实际运行时根据 Phase 2 数据计算)
|
||||
CODE_REVIEW_SCORE=85
|
||||
DESIGN_SCORE=80
|
||||
QUALITY_SCORE=$(( CODE_REVIEW_SCORE * 60 / 100 + DESIGN_SCORE * 40 / 100 ))
|
||||
|
||||
# CI 状态映射
|
||||
case "$CI_STATUS_TEXT" in
|
||||
passing) CI_STATUS=100; CI_PASSING=true; CI_LABEL="✅ 本地编译通过" ;;
|
||||
failing) CI_STATUS=0; CI_PASSING=false; CI_LABEL="❌ 编译失败" ;;
|
||||
*) CI_STATUS=0; CI_PASSING=true; CI_LABEL="⏭️ 跳过(无法编译)" ;;
|
||||
esac
|
||||
|
||||
QUALITY_SCORE=$(( CODE_REVIEW_SCORE * 40 / 100 + CI_STATUS * 30 / 100 + DESIGN_SCORE * 30 / 100 ))
|
||||
THRESHOLD=70
|
||||
|
||||
echo " CodeReview 评分: $CODE_REVIEW_SCORE/100"
|
||||
echo " CI 状态: $CI_STATUS_TEXT ($CI_LABEL)"
|
||||
echo " 设计一致性: $DESIGN_SCORE/100"
|
||||
echo " 质量总分: $QUALITY_SCORE/100"
|
||||
echo ""
|
||||
|
||||
# ---- 门禁判定 ----
|
||||
if [ "$QUALITY_SCORE" -ge "$THRESHOLD" ]; then
|
||||
if [ "$QUALITY_SCORE" -ge "$THRESHOLD" ] && [ "$CI_PASSING" = "true" ]; then
|
||||
echo "✅ 门禁判定:通过"
|
||||
echo " 评分 $QUALITY_SCORE ≥ $THRESHOLD"
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ echo "============================================"
|
|||
echo ""
|
||||
|
||||
# Phase 1: 采集待审 PR
|
||||
echo "▸ Phase 1/3: PR 采集"
|
||||
echo "▸ Phase 1/4: PR 采集"
|
||||
bash "$SCRIPT_DIR/01-collect-prs.sh" "$OWNER" "$REPO"
|
||||
echo ""
|
||||
|
||||
|
|
@ -57,12 +57,17 @@ for i in $(seq 0 $((PR_COUNT - 1))); do
|
|||
echo "--------------------------------------------"
|
||||
|
||||
# Phase 2: 深度审查
|
||||
echo "▸ Phase 2/3: 深度审查"
|
||||
echo "▸ Phase 2/4: 深度审查"
|
||||
bash "$SCRIPT_DIR/02-deep-review.sh" "$OWNER" "$REPO" "$PR_ID"
|
||||
echo ""
|
||||
|
||||
# Phase 3: 门禁决策
|
||||
echo "▸ Phase 3/3: 门禁决策"
|
||||
# Phase 3: 本地 CI 检查(编译验证)
|
||||
echo "▸ Phase 3/4: 本地 CI 检查"
|
||||
bash "$SCRIPT_DIR/03-local-ci-check.sh" "$OWNER" "$REPO" "$PR_ID"
|
||||
echo ""
|
||||
|
||||
# Phase 4: 门禁决策
|
||||
echo "▸ Phase 4/4: 门禁决策"
|
||||
bash "$SCRIPT_DIR/04-quality-gate-decision.sh" "$OWNER" "$REPO" "$PR_ID"
|
||||
echo ""
|
||||
done
|
||||
|
|
|
|||
Loading…
Reference in New Issue