Files
xiaoxia-saas/scripts/ci/chatops/ci_trigger.py
T
xiaoxia 6eac0b2cf2
Worker Base Image Build / Build Worker Base Images (worker-base-builder-cache, infra/docker/worker-base-builder.Dockerfile, worker-base-builder, builder) (push) Failing after 1m54s
Worker Base Image Build / Build Worker Base Images (worker-base-runtime-cache, infra/docker/worker-base-runtime.Dockerfile, worker-base-runtime, runtime) (push) Failing after 1m36s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Has been skipped
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / Validate - Code Quality (push) Failing after 1m29s
CI/CD Pipeline / Validate - Type Check (mypy) (push) Successful in 1m4s
CI/CD Pipeline / Validate - Migration (alembic) (push) Successful in 1m2s
CI/CD Pipeline / Unit Tests (push) Successful in 3m38s
CI/CD Pipeline / Integration Tests (push) Successful in 2m0s
CI/CD Pipeline / Frontend Lint (push) Successful in 28s
CI/CD Pipeline / Frontend Unit Tests (push) Failing after 44s
CI/CD Pipeline / PR Build API Image (push) Has been skipped
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / PR Build Worker Image (push) Has been skipped
CI/CD Pipeline / Build Staging API Image (push) Failing after 2m16s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 8m14s
CI/CD Pipeline / Build Staging Worker Image (push) Failing after 2m0s
CI/CD Pipeline / Build Production API Image (push) Has been skipped
CI/CD Pipeline / Build Production Web Image (push) Has been skipped
CI/CD Pipeline / Build Production Worker Image (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Staging E2E Tests (push) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (push) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (push) Has been skipped
chore(ci): 同步main分支CI配置与scripts/ci脚本 - 与develop对齐
同步内容:
1. CI流水线配置(ci-pipeline.yml)与develop对齐
2. PR构建脚本docker_build_only.sh增加buildx→docker build回退
3. pre-build步骤worker基础镜像构建增加buildx回退
4. 单元测试脚本全量覆盖率改为仅报告不阻塞
5. diff-cover依赖加入requirements-dev.txt
6. worker base builder/runtime Dockerfile同步
7. test_config_oss.py clear=False→clear=True修复OSS污染
8. Frontend Lint增加prettier依赖
2026-07-24 10:36:29 +08:00

170 lines
5.1 KiB
Python
Executable File

#!/usr/bin/env python3
"""
CI 触发模块 - 重新运行失败 job、重跑整个 workflow、取消 run
支持操作:
- rerun_failed: 重跑失败的 jobs
- rerun_all: 重跑整个 workflow
- cancel: 取消运行中的 run
用法:
python3 scripts/ci/chatops/ci_trigger.py --run-id 456 --action rerun_failed
python3 scripts/ci/chatops/ci_trigger.py --run-id 456 --action rerun_all
python3 scripts/ci/chatops/ci_trigger.py --run-id 456 --action cancel
设计:
- 与飞书机器人 /ci rerun 命令对接
- 操作前自动校验 run 状态,避免无效操作
"""
import argparse
import sys
from . import config
from .gitea_client import GiteaClient
class CITrigger:
"""CI 操作触发器"""
def __init__(self, gitea_client=None):
self.gitea = gitea_client or GiteaClient()
# ── 触发操作 ─────────────────────────────────────
def rerun_failed(self, run_id):
"""重跑失败的 jobs
Returns:
dict: {success, message, new_run_id?}
"""
run = self.gitea.get_run(run_id)
if not run:
return {"success": False, "message": f"Run {run_id} 不存在"}
status = run.get("status", "")
if status != "completed":
return {
"success": False,
"message": f"Run {run_id} 当前状态为 {status},仅 completed 状态才能重跑",
}
result = self.gitea.rerun_failed_jobs(run_id)
if result is None:
return {"success": False, "message": "重跑请求失败"}
# Gitea rerun 后返回的 run id 通常不变(复用原 run)
return {
"success": True,
"message": f"已触发重跑失败 jobs: Run #{run_id}",
"run_id": run_id,
"run_url": f"{config.GITEA_URL}/{config.GITEA_REPO}/actions/runs/{run_id}",
}
def rerun_all(self, run_id):
"""重跑整个 workflow run
Returns:
dict: {success, message, run_id, run_url}
"""
run = self.gitea.get_run(run_id)
if not run:
return {"success": False, "message": f"Run {run_id} 不存在"}
status = run.get("status", "")
if status == "running" or status == "pending":
return {
"success": False,
"message": f"Run {run_id} 正在运行中,无需重跑",
}
result = self.gitea.rerun_run(run_id)
if result is None:
return {"success": False, "message": "重跑请求失败"}
return {
"success": True,
"message": f"已触发完整重跑: Run #{run_id}",
"run_id": run_id,
"run_url": f"{config.GITEA_URL}/{config.GITEA_REPO}/actions/runs/{run_id}",
}
def cancel_run(self, run_id):
"""取消运行中的 run
Returns:
dict: {success, message}
"""
run = self.gitea.get_run(run_id)
if not run:
return {"success": False, "message": f"Run {run_id} 不存在"}
status = run.get("status", "")
if status == "completed":
return {
"success": False,
"message": f"Run {run_id} 已完成,无需取消",
}
result = self.gitea.cancel_run(run_id)
if result is None:
return {"success": False, "message": "取消请求失败"}
return {
"success": True,
"message": f"已取消 Run #{run_id}",
"run_id": run_id,
}
def rerun_latest_failed(self, branch="develop", workflow_id=None):
"""重跑指定分支最近一次失败的 run
用于快速恢复场景,不需要先查 run_id
"""
runs, _ = self.gitea.list_runs(branch=branch, workflow_id=workflow_id, status="failure", limit=5)
if not runs:
return {"success": False, "message": f"{branch} 分支没有失败的 run"}
latest = runs[0]
run_id = latest.get("id")
return self.rerun_failed(run_id)
# ── CLI 入口 ──────────────────────────────────────────
def main():
parser = argparse.ArgumentParser(description="CI 触发操作")
parser.add_argument("--run-id", required=True, help="Workflow Run ID")
parser.add_argument(
"--action",
required=True,
choices=["rerun_failed", "rerun_all", "cancel"],
help="操作类型",
)
args = parser.parse_args()
trigger = CITrigger()
if args.action == "rerun_failed":
result = trigger.rerun_failed(args.run_id)
elif args.action == "rerun_all":
result = trigger.rerun_all(args.run_id)
elif args.action == "cancel":
result = trigger.cancel_run(args.run_id)
else:
print(f"未知操作: {args.action}")
return 1
status = "✅" if result["success"] else "❌"
print(f"{status} {result['message']}")
if result.get("run_url"):
print(f" {result['run_url']}")
return 0 if result["success"] else 1
if __name__ == "__main__":
sys.exit(main())