Compare commits

...

1 Commits

Author SHA1 Message Date
xiaoxia 1abab50582 fix: auto-format runs on merge commit to match Frontend Lint scope
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 15s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Unit Tests (pull_request) Failing after 2m2s
Preview Deploy / Deploy Preview Environment (pull_request) Failing after 3m24s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 4m5s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 4m7s
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Successful in 4m6s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 4m30s
AI Code Review / AI Code Review (pull_request) Successful in 6m43s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m22s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 42s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 16s
- ensure_git_repo() no longer checks out PR source branch
- stays on merge commit so prettier sees all files including develop's
- after formatting, cherry-picks the fix commit to source branch before push
- ensures auto-fix and Frontend Lint check the same file set
2026-08-14 16:52:23 +08:00
+34 -25
View File
@@ -25,51 +25,47 @@ def run(cmd, check=True, capture=True, cwd=None):
def ensure_git_repo(api_url, repo, token, pr_number):
"""确保当前目录是git仓库,并切换到PR源分支
"""确保当前目录是git仓库,保持在 merge commit 状态
checkout脚本用tarball方式下载代码(PR merge后的commit),没有.git目录。
这里自动初始化git仓库,fetch PR源分支并强制checkout
使工作区变为PR源分支的代码,确保后续格式化修复基于源分支
这里自动初始化git仓库,但不切换分支,保持在merge commit状态
使格式化检查与 Frontend Lint 的范围完全一致
"""
if os.path.exists(".git"):
return
print("检测到tarball checkout(无.git目录),自动初始化git仓库...")
print("保持在 merge commit 状态(与 Frontend Lint 一致)")
# 构造带认证的远端URL
server_url = api_url.rsplit("/api/v1", 1)[0]
remote_url = f"{server_url.replace('https://', f'https://x-access-token:{token}@')}/{repo}.git"
# 获取PR的源分支
# 获取PR的源分支(仅用于后续推送,不checkout
pr_api_url = f"{api_url}/repos/{repo}/pulls/{pr_number}"
req_obj = urllib.request.Request(pr_api_url, headers={"Authorization": f"token {token}"})
with urllib.request.urlopen(req_obj) as resp:
pr = json.loads(resp.read())
head_branch = pr["head"]["ref"]
print(f"PR源分支: {head_branch}")
print(f"PR源分支: {head_branch}(仅用于推送,不切换)")
# 初始化git
# 初始化git(不fetch/checkout,保持tarball内容即merge commit状态)
run("git init -q")
run(f"git remote add origin {remote_url}")
run('git config user.name "CI Bot"')
run('git config user.email "ci-bot@xiaoxiajianji.com"')
# fetch源分支(浅克隆,只要最新commit
print("fetch源分支...")
run(f"git fetch --depth=1 origin {head_branch}")
# 强制checkout到源分支(覆盖tarball内容)
# tarball是merge后的commit,源分支才是我们要修改并推送的目标
print("切换到源分支...")
run(f"git checkout -f -B {head_branch} FETCH_HEAD")
# 将当前目录(tarball解压的merge commit)作为初始commit
run("git add -A")
run('git commit -q -m "CI merge commit snapshot"')
result = run("git status --porcelain")
if result.stdout.strip():
n = len(result.stdout.strip().splitlines())
print(f"⚠️ 工作区有 {n} 个未追踪文件")
print(f"⚠️ 工作区有 {n} 个未追踪文件")
else:
print("✅ git仓库就绪,工作区clean")
print("✅ git仓库就绪merge commit 状态)")
return head_branch
@@ -236,24 +232,39 @@ def main():
for line in result.stdout.strip().split("\n"):
print(f" {line}")
# 提交修复
# 提交修复(在 merge commit 状态)
run("git add -A")
run('git commit -m "style: auto-format with black + isort + prettier [ci skip]"')
run('git commit -m "style: auto-format with black + isort + prettier"')
# 推送(head_branch已从ensure_git_repo获取)
# 记录格式修复的 commit hash
format_commit = run("git rev-parse HEAD").stdout.strip()
# 推送:将格式化变更推回 PR 源分支
print(f"\nPR来源分支: {head_branch}")
# 切换到源分支,cherry-pick 格式化修复
print(f"fetch 源分支 {head_branch}...")
run(f"git fetch --depth=1 origin {head_branch}")
run(f"git checkout -f -B {head_branch} FETCH_HEAD")
print(f"cherry-pick 格式化修复到源分支...")
cherry_result = run(f"git cherry-pick {format_commit}", check=False)
if cherry_result.returncode != 0:
print(f"cherry-pick 冲突(源分支可能已有不同格式),中止cherry-pick")
run("git cherry-pick --abort", check=False)
print("没有需要推送的格式化改动")
return
# 推送(保留原有的重试逻辑)
print("推送格式修复到远端...")
# 推送前先 rebase 拉取远端最新,避免快进冲突
# 最多重试 3 次:rebase → push,失败则重新拉取再试
max_retries = 3
push_success = False
last_error = ""
for attempt in range(1, max_retries + 1):
print(f" 尝试 {attempt}/{max_retries}: 拉取最新代码并推送...")
print(f" 尝试 {attempt}/{max_retries}: 推送...")
# 先拉取远端最新 commit 并 rebase
fetch_result = run(f"git fetch origin {head_branch}", check=False)
if fetch_result.returncode != 0:
last_error = f"git fetch 失败: {fetch_result.stderr.strip()}"
@@ -266,10 +277,8 @@ def main():
last_error = f"git rebase 失败,中止并重置: {rebase_result.stderr.strip()[:200]}"
print(f" {last_error}")
run("git rebase --abort", check=False)
# rebase 失败通常是冲突,重试没用,直接跳出
break
# 推送
push_result = run(f'git push origin "HEAD:{head_branch}"', check=False)
if push_result.returncode == 0:
push_success = True