#!/bin/bash # CI 公共步骤:检测 push(develop/main) 事件的改动范围 # 输出 skip_backend / skip_frontend(复用 PR check 的语义) # - 纯前端改动(仅 apps/web/): skip_backend=true # - 纯后端改动(不含 apps/web/): skip_frontend=true # - 全栈 / 无法判断: 两者都 false(走全量,安全兜底) # 需要环境变量: GITHUB_TOKEN, GITHUB_API_URL, GITHUB_REPOSITORY, GITHUB_SHA set -eu OUTPUT="${GITHUB_OUTPUT:-/dev/stdout}" before="${GITHUB_EVENT_BEFORE:-}" after="${GITHUB_SHA:-}" repo="${GITHUB_REPOSITORY:-}" base="${GITHUB_API_URL:-}" # Gitea Actions 中 push 事件的前一个 SHA 在 event payload 的 before 字段 if [ -z "$before" ] && [ -n "${GITHUB_EVENT_PATH:-}" ] && [ -f "$GITHUB_EVENT_PATH" ]; then before=$(python3 -c " import json,sys try: d=json.load(open('${GITHUB_EVENT_PATH}')) print(d.get('before','') or '') except Exception: print('') ") fi echo "改动范围检测: before=${before:-} after=${after}" FILES="" if [ -n "$before" ] && [ "$before" != "0000000000000000000000000000000000000000" ]; then # Gitea 1.26.x compare API 的顶层 files 字段不填充(始终为空), # 但响应里每个 commit 条目自带的 files 完整可用;聚合区间内所有提交的 files 即可。 API_URL="${base}/repos/${repo}/compare/${before}...${after}?per_page=300" for attempt in 1 2 3; do FILES=$(curl -s --max-time 30 -H "Authorization: token ${GITHUB_TOKEN}" "$API_URL" \ | python3 -c " import json,sys try: d=json.load(sys.stdin) files=set() for c in d.get('commits', []) or []: for f in (c.get('files') or []): n = f.get('filename') or '' if n: files.add(n) print('\n'.join(sorted(files))) except Exception: pass ") [ -n "$FILES" ] && break echo "compare API 无返回,重试 $attempt/3..." sleep 3 done fi if [ -z "$FILES" ]; then echo "⚠️ 无法获取改动文件列表(新分支/API异常),保守起见走全量构建" echo "skip_backend=false" >> "$OUTPUT" echo "skip_frontend=false" >> "$OUTPUT" exit 0 fi TOTAL=$(printf '%s\n' "$FILES" | grep -c . || true) FRONTEND_COUNT=$(printf '%s\n' "$FILES" | grep -c '^apps/web/' || true) BACKEND_COUNT=$(python3 -c "print($TOTAL - $FRONTEND_COUNT)") echo "变更文件: ${TOTAL} 个 (前端: ${FRONTEND_COUNT}, 后端/公共: ${BACKEND_COUNT})" if [ "$BACKEND_COUNT" = "0" ] && [ "$FRONTEND_COUNT" -gt 0 ]; then echo "skip_backend=true" >> "$OUTPUT" echo "skip_frontend=false" >> "$OUTPUT" echo "✅ 纯前端改动,跳过后端镜像构建" elif [ "$FRONTEND_COUNT" = "0" ] && [ "$BACKEND_COUNT" -gt 0 ]; then echo "skip_backend=false" >> "$OUTPUT" echo "skip_frontend=true" >> "$OUTPUT" echo "🔧 纯后端改动,跳过 Web 镜像构建" else echo "skip_backend=false" >> "$OUTPUT" echo "skip_frontend=false" >> "$OUTPUT" echo "🔧 包含全栈/公共变更,三个镜像全部构建" fi