Files
awoooi/.gitea/workflows/code-review.yaml
Your Name 986d1a937d
All checks were successful
Code Review / ai-code-review (push) Successful in 12s
fix(ci): run secret surface guard with node
2026-05-18 09:41:09 +08:00

221 lines
9.9 KiB
YAML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Code Review
on:
push:
branches: [main]
paths:
- 'apps/**'
- 'k8s/**'
- '!k8s/awoooi-prod/kustomization.yaml'
- 'ops/**'
- 'scripts/**'
- '.gitea/workflows/**'
workflow_dispatch:
concurrency:
group: code-review-${{ github.ref }}
cancel-in-progress: true
env:
REPORT_URL: https://mo.wooo.work/code-review/
GITEA_ACTIONS_URL: http://192.168.0.110:3001/wooo/awoooi/actions
TELEGRAM_ALERT_CHAT_ID: "-1003711974679"
jobs:
ai-code-review:
runs-on: ubuntu-latest
timeout-minutes: 8
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 50
- name: Guard Workflow Secret Surfaces
run: node scripts/ci/check-gitea-step-env-secrets.js
- name: Skip Stale Main Push
id: stale
run: |
set -euo pipefail
BRANCH="${GITHUB_REF_NAME:-${GITHUB_REF#refs/heads/}}"
if [ "${GITHUB_EVENT_NAME:-}" != "push" ] || [ "$BRANCH" != "main" ]; then
echo "skip=false" >> "$GITHUB_OUTPUT"
exit 0
fi
LATEST="$(git ls-remote origin refs/heads/main | awk '{print $1}')"
if [ -n "$LATEST" ] && [ "$LATEST" != "$GITHUB_SHA" ]; then
echo "skip=true" >> "$GITHUB_OUTPUT"
echo "Skip stale code review: current=$GITHUB_SHA latest=$LATEST"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
- name: Prepare Review Context
id: ctx
if: steps.stale.outputs.skip != 'true'
env:
BASE_SHA: ${{ github.event.before }}
run: |
set -euo pipefail
SHORT_SHA="${GITHUB_SHA::7}"
BRANCH="${GITHUB_REF_NAME:-${GITHUB_REF#refs/heads/}}"
if [ -z "$BRANCH" ] || [ "$BRANCH" = "$GITHUB_REF" ]; then
BRANCH="main"
fi
COMMIT_MSG="$(git log -1 --pretty=%s)"
COMMIT_MSG="${COMMIT_MSG:0:120}"
BASE="${BASE_SHA:-}"
if [ -n "$BASE" ] && [ "$BASE" != "0000000000000000000000000000000000000000" ]; then
git rev-parse --verify "${BASE}^{commit}" >/dev/null 2>&1 || git fetch --no-tags origin "$BASE" --depth=1 || true
fi
if [ -n "$BASE" ] && git rev-parse --verify "${BASE}^{commit}" >/dev/null 2>&1; then
RANGE="$BASE..$GITHUB_SHA"
elif git rev-parse --verify "${GITHUB_SHA}^" >/dev/null 2>&1; then
BASE="${GITHUB_SHA}^"
RANGE="${GITHUB_SHA}^..$GITHUB_SHA"
else
BASE=""
RANGE="$GITHUB_SHA"
fi
FILES="$(git diff --name-only "$RANGE" || git show --pretty= --name-only "$GITHUB_SHA")"
if [ -z "$FILES" ]; then
FILES="(no files reported)"
fi
FILE_COUNT="$(printf '%s\n' "$FILES" | grep -c . || true)"
FILES_DISPLAY="$(printf '%s\n' "$FILES" | sed -n '1,6s/^/• /p')"
if [ "$FILE_COUNT" -gt 6 ]; then
FILES_DISPLAY="$(printf '%s\n• ... and %s more' "$FILES_DISPLAY" "$((FILE_COUNT - 6))")"
fi
{
echo "short_sha=$SHORT_SHA"
echo "branch=$BRANCH"
echo "base_sha=$BASE"
echo "file_count=$FILE_COUNT"
echo "commit_msg<<EOF"
printf '%s\n' "$COMMIT_MSG"
echo "EOF"
echo "files_display<<EOF"
printf '%s\n' "$FILES_DISPLAY"
echo "EOF"
} >> "$GITHUB_OUTPUT"
- name: Notify Code Review Start
if: steps.stale.outputs.skip != 'true'
env:
TG_CHAT_ID: ${{ env.TELEGRAM_ALERT_CHAT_ID }}
SHORT_SHA: ${{ steps.ctx.outputs.short_sha }}
BRANCH: ${{ steps.ctx.outputs.branch }}
COMMIT_MSG: ${{ steps.ctx.outputs.commit_msg }}
FILES_DISPLAY: ${{ steps.ctx.outputs.files_display }}
run: |
set -euo pipefail
TG_BOT_TOKEN="$(cat <<'AWOOOI_SECRET_TG_BOT_TOKEN'
${{ secrets.TELEGRAM_BOT_TOKEN }}
AWOOOI_SECRET_TG_BOT_TOKEN
)"
html_escape() { sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g'; }
COMMIT_ESC="$(printf '%s' "$COMMIT_MSG" | html_escape)"
FILES_ESC="$(printf '%s\n' "$FILES_DISPLAY" | html_escape)"
MSG="$(printf '🔍 <b>Code Review 啟動</b>\n──────────────────────\n📦 Commit <code>%s</code> 🌿 <code>%s</code>\n📝 <code>%s</code>\n📁 <b>變更檔案:</b>\n%s\n──────────────────────\n🤖 <b>Hermes → OpenClaw → Elephant Alpha → NemoTron</b>\n📊 即時進度:<a href=\"%s\">%s</a>' "$SHORT_SHA" "$BRANCH" "$COMMIT_ESC" "$FILES_ESC" "$REPORT_URL" "$REPORT_URL")"
if AWOOI_CICD_STATUS=running \
AWOOI_CICD_STAGE=code-review \
AWOOI_CICD_JOB_NAME="Code Review 啟動" \
AWOOI_CICD_COMMIT_SHA="${GITHUB_SHA}" \
AWOOI_CICD_TRIGGERED_BY="${GITHUB_ACTOR:-CI}" \
AWOOI_CICD_SUMMARY="${COMMIT_MSG}" \
AWOOI_CICD_WORKFLOW_URL="${REPORT_URL}" \
scripts/ci/notify-awoooi-cicd.sh; then
echo "Code review start notification mirrored through AWOOI API"
else
if [ -z "${TG_BOT_TOKEN:-}" ] || [ -z "${TG_CHAT_ID:-}" ]; then
echo "Telegram secret missing and AWOOI API notify failed; skip start notification"
exit 0
fi
curl -fsS -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg c "$TG_CHAT_ID" --arg t "$MSG" '{chat_id:$c,text:$t,parse_mode:"HTML",disable_web_page_preview:true}')" \
>/dev/null
fi
- name: Run Deterministic Review
if: steps.stale.outputs.skip != 'true'
env:
BASE_SHA: ${{ steps.ctx.outputs.base_sha }}
run: |
set -euo pipefail
python3 scripts/ci_code_review.py \
--base "${BASE_SHA:-}" \
--head "$GITHUB_SHA" \
--repo "." \
--output /tmp/code-review-report.json
jq . /tmp/code-review-report.json
- name: Notify Code Review Completion
if: always() && steps.stale.outputs.skip != 'true'
env:
TG_CHAT_ID: ${{ env.TELEGRAM_ALERT_CHAT_ID }}
SHORT_SHA: ${{ steps.ctx.outputs.short_sha }}
run: |
set -euo pipefail
TG_BOT_TOKEN="$(cat <<'AWOOOI_SECRET_TG_BOT_TOKEN'
${{ secrets.TELEGRAM_BOT_TOKEN }}
AWOOOI_SECRET_TG_BOT_TOKEN
)"
REPORT=/tmp/code-review-report.json
if [ ! -s "$REPORT" ]; then
cat > "$REPORT" <<'JSON'
{"counts":{"critical":0,"high":0,"medium":1,"low":0},"risk":"MEDIUM","summary":"Code Review workflow 未產生報告,需查看 Gitea Actions 日誌。","action":"查看 workflow logs","top_issue":"報告產生失敗","agents":["Hermes","OpenClaw","ElephantAlpha","NemoTron"]}
JSON
fi
CRITICAL="$(jq -r '.counts.critical' "$REPORT")"
HIGH="$(jq -r '.counts.high' "$REPORT")"
MEDIUM="$(jq -r '.counts.medium' "$REPORT")"
LOW="$(jq -r '.counts.low' "$REPORT")"
RISK="$(jq -r '.risk' "$REPORT")"
SUMMARY="$(jq -r '.summary' "$REPORT")"
ACTION="$(jq -r '.action' "$REPORT")"
TOP_ISSUE="$(jq -r '.top_issue' "$REPORT")"
if [ "$RISK" = "LOW" ]; then
STATUS="🟢"
ISSUE_LINE="✅ 無高風險問題"
elif [ "$RISK" = "MEDIUM" ]; then
STATUS="🟡"
ISSUE_LINE="⚠️ 有中風險註記"
else
STATUS="🔴"
ISSUE_LINE="🚨 需人工複核"
fi
html_escape() { sed 's/&/\&amp;/g; s/</\&lt;/g; s/>/\&gt;/g'; }
SUMMARY_ESC="$(printf '%s' "$SUMMARY" | html_escape)"
ACTION_ESC="$(printf '%s' "$ACTION" | html_escape)"
TOP_ESC="$(printf '%s' "$TOP_ISSUE" | html_escape)"
MSG="$(printf '%s <b>Code Review 完成・%s</b>\n──────────────────────\n🔴 CRITICAL <code>%s</code> 🟠 HIGH <code>%s</code> 🟡 MEDIUM <code>%s</code> 🟢 LOW <code>%s</code>\n──────────────────────\n⚠ <b>主要問題</b>\n%s\n\n🔍 <b>整體風險等級</b>\n%s%s\n\n⚠ <b>最高關注問題</b>\n1. %s\n──────────────────────\n🤖 Elephant Alpha<b>%s</b> ✅ %s\n📊 完整報告:<a href=\"%s\">%s</a>' "$STATUS" "$SHORT_SHA" "$CRITICAL" "$HIGH" "$MEDIUM" "$LOW" "$ISSUE_LINE" "$RISK" "$SUMMARY_ESC" "$TOP_ESC" "$RISK" "$ACTION_ESC" "$REPORT_URL" "$REPORT_URL")"
CICD_STATUS=success
if [ "$RISK" = "MEDIUM" ]; then CICD_STATUS=pending; fi
if [ "$RISK" = "HIGH" ] || [ "$RISK" = "CRITICAL" ]; then CICD_STATUS=failed; fi
if AWOOI_CICD_STATUS="${CICD_STATUS}" \
AWOOI_CICD_STAGE=code-review \
AWOOI_CICD_JOB_NAME="Code Review 完成・${RISK}" \
AWOOI_CICD_COMMIT_SHA="${GITHUB_SHA}" \
AWOOI_CICD_TRIGGERED_BY="${GITHUB_ACTOR:-CI}" \
AWOOI_CICD_SUMMARY="CRITICAL=${CRITICAL}; HIGH=${HIGH}; MEDIUM=${MEDIUM}; LOW=${LOW}; ${SUMMARY}" \
AWOOI_CICD_WORKFLOW_URL="${REPORT_URL}" \
scripts/ci/notify-awoooi-cicd.sh; then
echo "Code review completion notification mirrored through AWOOI API"
else
if [ -z "${TG_BOT_TOKEN:-}" ] || [ -z "${TG_CHAT_ID:-}" ]; then
echo "Telegram secret missing and AWOOI API notify failed; skip completion notification"
exit 0
fi
curl -fsS -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg c "$TG_CHAT_ID" --arg t "$MSG" '{chat_id:$c,text:$t,parse_mode:"HTML",disable_web_page_preview:true}')" \
>/dev/null
fi