[CI Monitor] Fix ci_monitor perf analyzer bug (#12281)
This commit is contained in:
@@ -2,7 +2,7 @@ name: CI Monitor
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 */12 * * *' # Every 12 hours for main analysis
|
- cron: '0 */12 * * *' # Every 12 hours for main analysis
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
limit:
|
limit:
|
||||||
@@ -65,6 +65,7 @@ jobs:
|
|||||||
retention-days: 30
|
retention-days: 30
|
||||||
|
|
||||||
ci-monitor-balance:
|
ci-monitor-balance:
|
||||||
|
needs: ci-monitor
|
||||||
if: github.repository == 'sgl-project/sglang' || github.event_name == 'pull_request'
|
if: github.repository == 'sgl-project/sglang' || github.event_name == 'pull_request'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -382,15 +382,13 @@ class SGLangCIAnalyzer:
|
|||||||
try:
|
try:
|
||||||
github_step_summary = os.environ.get("GITHUB_STEP_SUMMARY")
|
github_step_summary = os.environ.get("GITHUB_STEP_SUMMARY")
|
||||||
if not github_step_summary:
|
if not github_step_summary:
|
||||||
print("ℹ️ Not running in GitHub Actions, skipping summary generation")
|
print("Not running in GitHub Actions, skipping summary generation")
|
||||||
return
|
return
|
||||||
|
|
||||||
print("📊 Generating GitHub Actions summary for CI Analysis...")
|
print("Generating GitHub Actions summary for CI Analysis...")
|
||||||
|
|
||||||
summary_lines = []
|
summary_lines = []
|
||||||
summary_lines.append(
|
summary_lines.append("# SGLang CI Analysis Report (Target Workflows Only)")
|
||||||
"# 🔍 SGLang CI Analysis Report (Target Workflows Only)"
|
|
||||||
)
|
|
||||||
summary_lines.append("")
|
summary_lines.append("")
|
||||||
|
|
||||||
total = stats["total_runs"]
|
total = stats["total_runs"]
|
||||||
@@ -400,26 +398,24 @@ class SGLangCIAnalyzer:
|
|||||||
skipped = stats["skipped_runs"]
|
skipped = stats["skipped_runs"]
|
||||||
success_rate = (success / total * 100) if total > 0 else 0
|
success_rate = (success / total * 100) if total > 0 else 0
|
||||||
|
|
||||||
summary_lines.append("## 📊 Overall Statistics")
|
summary_lines.append("## Overall Statistics")
|
||||||
summary_lines.append("")
|
summary_lines.append("")
|
||||||
summary_lines.append("| Metric | Count | Percentage |")
|
summary_lines.append("| Metric | Count | Percentage |")
|
||||||
summary_lines.append("|--------|-------|------------|")
|
summary_lines.append("|--------|-------|------------|")
|
||||||
summary_lines.append(f"| Total Runs | {total} | 100% |")
|
summary_lines.append(f"| Total Runs | {total} | 100% |")
|
||||||
summary_lines.append(
|
summary_lines.append(
|
||||||
f"| ✅ Successful | {success} | {success/total*100:.1f}% |"
|
f"| Successful | {success} | {success/total*100:.1f}% |"
|
||||||
)
|
)
|
||||||
summary_lines.append(f"| ❌ Failed | {failed} | {failed/total*100:.1f}% |")
|
summary_lines.append(f"| Failed | {failed} | {failed/total*100:.1f}% |")
|
||||||
summary_lines.append(
|
summary_lines.append(
|
||||||
f"| 🚫 Cancelled | {cancelled} | {cancelled/total*100:.1f}% |"
|
f"| Cancelled | {cancelled} | {cancelled/total*100:.1f}% |"
|
||||||
)
|
|
||||||
summary_lines.append(
|
|
||||||
f"| ⏭️ Skipped | {skipped} | {skipped/total*100:.1f}% |"
|
|
||||||
)
|
)
|
||||||
|
summary_lines.append(f"| Skipped | {skipped} | {skipped/total*100:.1f}% |")
|
||||||
summary_lines.append(f"| **Success Rate** | **{success_rate:.1f}%** | - |")
|
summary_lines.append(f"| **Success Rate** | **{success_rate:.1f}%** | - |")
|
||||||
summary_lines.append("")
|
summary_lines.append("")
|
||||||
|
|
||||||
if stats["category_failures"]:
|
if stats["category_failures"]:
|
||||||
summary_lines.append("## 📁 Category Failure Statistics")
|
summary_lines.append("## Category Failure Statistics")
|
||||||
summary_lines.append("")
|
summary_lines.append("")
|
||||||
summary_lines.append("| Category | Failures |")
|
summary_lines.append("| Category | Failures |")
|
||||||
summary_lines.append("|----------|----------|")
|
summary_lines.append("|----------|----------|")
|
||||||
@@ -430,7 +426,7 @@ class SGLangCIAnalyzer:
|
|||||||
summary_lines.append("")
|
summary_lines.append("")
|
||||||
|
|
||||||
if stats["job_failures"]:
|
if stats["job_failures"]:
|
||||||
summary_lines.append("## 🔴 Most Frequently Failed Jobs (Top 20)")
|
summary_lines.append("## Most Frequently Failed Jobs (Top 20)")
|
||||||
summary_lines.append("")
|
summary_lines.append("")
|
||||||
|
|
||||||
top_failures = sorted(
|
top_failures = sorted(
|
||||||
@@ -457,7 +453,7 @@ class SGLangCIAnalyzer:
|
|||||||
pr_text = f" by {pr_info['author']}"
|
pr_text = f" by {pr_info['author']}"
|
||||||
|
|
||||||
summary_lines.append(
|
summary_lines.append(
|
||||||
f"✅ **Last Success:** [Run #{last_success['run_number']}]({last_success['url']}) ({success_date.strftime('%Y-%m-%d %H:%M')}){pr_text}"
|
f"**Last Success:** [Run #{last_success['run_number']}]({last_success['url']}) ({success_date.strftime('%Y-%m-%d %H:%M')}){pr_text}"
|
||||||
)
|
)
|
||||||
summary_lines.append("")
|
summary_lines.append("")
|
||||||
|
|
||||||
@@ -465,7 +461,7 @@ class SGLangCIAnalyzer:
|
|||||||
job in stats["job_failure_links"]
|
job in stats["job_failure_links"]
|
||||||
and stats["job_failure_links"][job]
|
and stats["job_failure_links"][job]
|
||||||
):
|
):
|
||||||
summary_lines.append("❌ **Recent Failures:**")
|
summary_lines.append("**Recent Failures:**")
|
||||||
for link_info in stats["job_failure_links"][job]:
|
for link_info in stats["job_failure_links"][job]:
|
||||||
created_at = datetime.fromisoformat(
|
created_at = datetime.fromisoformat(
|
||||||
link_info["created_at"].replace("Z", "+00:00")
|
link_info["created_at"].replace("Z", "+00:00")
|
||||||
@@ -484,7 +480,7 @@ class SGLangCIAnalyzer:
|
|||||||
summary_lines.append("")
|
summary_lines.append("")
|
||||||
|
|
||||||
if stats["failure_patterns"]:
|
if stats["failure_patterns"]:
|
||||||
summary_lines.append("## 🔬 Failure Pattern Analysis")
|
summary_lines.append("## Failure Pattern Analysis")
|
||||||
summary_lines.append("")
|
summary_lines.append("")
|
||||||
summary_lines.append("| Pattern | Count |")
|
summary_lines.append("| Pattern | Count |")
|
||||||
summary_lines.append("|---------|-------|")
|
summary_lines.append("|---------|-------|")
|
||||||
@@ -498,10 +494,10 @@ class SGLangCIAnalyzer:
|
|||||||
f.write("\n".join(summary_lines))
|
f.write("\n".join(summary_lines))
|
||||||
f.write("\n\n---\n\n")
|
f.write("\n\n---\n\n")
|
||||||
|
|
||||||
print("✅ GitHub Actions summary generated successfully")
|
print("GitHub Actions summary generated successfully")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"❌ Failed to generate GitHub Actions summary: {e}")
|
print(f"Failed to generate GitHub Actions summary: {e}")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|||||||
@@ -612,18 +612,23 @@ class SGLangPerfAnalyzer:
|
|||||||
|
|
||||||
total_runs = len(runs)
|
total_runs = len(runs)
|
||||||
for i, run in enumerate(runs, 1):
|
for i, run in enumerate(runs, 1):
|
||||||
print(f"Processing run {i}/{total_runs}: #{run.get('run_number')}")
|
if not isinstance(run, dict):
|
||||||
|
print(f" Warning: run #{i} is not a dict, skipping.")
|
||||||
|
continue
|
||||||
|
|
||||||
run_info = {
|
run_info = {
|
||||||
"run_number": run.get("run_number"),
|
"run_number": run.get("run_number"),
|
||||||
"created_at": run.get("created_at"),
|
"created_at": run.get("created_at"),
|
||||||
"head_sha": run.get("head_sha", "")[:8],
|
"head_sha": (run.get("head_sha") or "")[:8],
|
||||||
"author": run.get("head_commit", {})
|
"author": "Unknown",
|
||||||
.get("author", {})
|
|
||||||
.get("name", "Unknown"),
|
|
||||||
"pr_number": None,
|
"pr_number": None,
|
||||||
"url": f"https://github.com/{self.repo}/actions/runs/{run.get('id')}",
|
"url": f"https://github.com/{self.repo}/actions/runs/{run.get('id')}",
|
||||||
}
|
}
|
||||||
|
head_commit = run.get("head_commit", {})
|
||||||
|
if isinstance(head_commit, dict):
|
||||||
|
run_info["author"] = head_commit.get("author", {}).get(
|
||||||
|
"name", "Unknown"
|
||||||
|
)
|
||||||
|
|
||||||
# Extract PR number
|
# Extract PR number
|
||||||
pull_requests = run.get("pull_requests", [])
|
pull_requests = run.get("pull_requests", [])
|
||||||
|
|||||||
Reference in New Issue
Block a user