[Auto Sync] Update grpc_request_manager.py, tokenizer_manag... (20260214) (#18838)

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Lianmin Zheng
2026-02-14 18:12:32 -08:00
committed by GitHub
parent 190fa8246f
commit b33769786f
7 changed files with 544 additions and 191 deletions

View File

@@ -29,44 +29,20 @@ python3 scripts/copy_to_oss.py --commit <commit_hash> --dry-run
import argparse
import datetime
import os
import re
import shutil
import subprocess
import sys
import tempfile
# --- Configuration Begin ---
# List of folders and files to copy to the OSS repo.
# Changes outside these paths will be ignored.
folder_names = [
"3rdparty",
"assets",
"benchmark",
"docker",
"docs",
"examples",
"python/sglang/lang",
"python/sglang/jit_kernel",
"python/sglang/srt",
"python/sglang/test",
"python/sglang/utils.py",
"python/sglang/README.md",
"sgl-kernel",
"test/manual",
"test/registered",
"test/srt",
"test/README.md",
"test/run_suite.py",
"README.md",
]
# Allow sibling imports regardless of the working directory.
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
# --- Configuration End ---
def write_github_step_summary(content):
if not os.environ.get("GITHUB_STEP_SUMMARY"):
return
with open(os.environ["GITHUB_STEP_SUMMARY"], "a") as f:
f.write(content)
from utils import ( # noqa: E402
FOLDER_NAMES,
find_latest_oss_sync_commit,
write_github_step_summary,
)
def get_commit_info(commit_ref):
@@ -131,7 +107,7 @@ def create_filtered_patch(commit_hash, dry_run):
# Filter the list of files
relevant_files = [
f for f in changed_files if any(f.startswith(path) for path in folder_names)
f for f in changed_files if any(f.startswith(path) for path in FOLDER_NAMES)
]
if not relevant_files:
@@ -190,7 +166,7 @@ def get_oss_repo(dry_run):
print(f"\nCreated temporary directory for OSS repo: {temp_dir}")
repo_url = f"https://{gh_token}@github.com/sgl-project/sglang.git"
command = ["git", "clone", "--branch", "main", repo_url, oss_root]
command = ["git", "clone", repo_url, oss_root]
print(f"Run: {' '.join(command)}")
if not dry_run:
@@ -209,8 +185,9 @@ def _apply_patch(patch_file, dry_run):
"""
Try to apply a patch, falling back to --3way merge if a clean apply fails.
Returns True if the patch was applied successfully (clean or via --3way),
or raises an exception with full diagnostics if both methods fail.
Returns True if the patch was applied cleanly.
Returns False if conflicts were encountered (changes are still staged
with conflict markers so a PR can be created for manual resolution).
"""
# --- Attempt 1: clean git apply ---
apply_cmd = ["git", "apply", patch_file]
@@ -235,8 +212,8 @@ def _apply_patch(patch_file, dry_run):
print("✅ Patch applied via --3way merge (no conflicts).")
return True
# --- Both attempts failed — gather diagnostics ---
print(f" --3way merge also failed:\n{result_3way.stderr.strip()}\n")
# --- --3way left conflict markers in the working tree ---
print(f"⚠️ --3way merge had conflicts:\n{result_3way.stderr.strip()}\n")
# Show which hunks conflict
check_cmd = ["git", "apply", "--check", "--verbose", patch_file]
@@ -272,7 +249,7 @@ def _apply_patch(patch_file, dry_run):
# Write a rich summary to the GitHub Actions step summary
summary_lines = [
"\n## Patch could not be applied automatically\n",
"\n## ⚠️ Patch had conflicts — PR created for manual resolution\n",
"### Conflict details\n",
f"```\n{conflict_details}\n```\n",
]
@@ -287,18 +264,22 @@ def _apply_patch(patch_file, dry_run):
)
write_github_step_summary("".join(summary_lines))
# Reset the working tree so the finally-block cleanup is safe
subprocess.run(["git", "checkout", "."], capture_output=True, text=True)
raise RuntimeError(
"Patch could not be applied. See the CI log and GitHub Actions "
"step summary for the full patch and conflict details."
)
return False
def apply_patch_and_push(oss_root, patch_file, branch_name, commit_message, dry_run):
def apply_patch_and_push(
oss_root, patch_file, branch_name, commit_message, base_oss_commit, dry_run
):
"""
In the OSS repo, create a branch, apply the patch, commit, and push.
In the OSS repo, create a branch from base_oss_commit, apply the patch,
commit, and push.
Args:
base_oss_commit: The OSS commit hash to branch from (the last sync
point). If None, the current HEAD (main) is used.
Returns True if the patch applied cleanly, False if there were conflicts
(the conflicted state is still committed and pushed so a PR can be opened).
"""
print("\nApplying patch and pushing to OSS repo...")
@@ -306,15 +287,19 @@ def apply_patch_and_push(oss_root, patch_file, branch_name, commit_message, dry_
if not dry_run:
os.chdir(oss_root)
applied_cleanly = True
try:
# Create a new branch
checkout_cmd = ["git", "checkout", "-b", branch_name]
# Check out a new branch from the base OSS commit
if base_oss_commit:
checkout_cmd = ["git", "checkout", "-b", branch_name, base_oss_commit]
else:
checkout_cmd = ["git", "checkout", "-b", branch_name]
print(f"Run: {' '.join(checkout_cmd)}")
if not dry_run:
subprocess.run(checkout_cmd, check=True, capture_output=True, text=True)
# Apply the patch (with --3way fallback and diagnostics)
_apply_patch(patch_file, dry_run)
applied_cleanly = _apply_patch(patch_file, dry_run)
# Configure git user and stage changes
post_apply_commands = [
@@ -359,7 +344,15 @@ def apply_patch_and_push(oss_root, patch_file, branch_name, commit_message, dry_
if not dry_run:
os.chdir(original_cwd)
print("✅ Branch created, patch applied, and pushed successfully.")
if applied_cleanly:
print("✅ Branch created, patch applied cleanly, and pushed successfully.")
else:
print(
"⚠️ Branch created and pushed with conflict markers. "
"A PR will be opened for manual resolution."
)
return applied_cleanly
def create_pull_request(oss_root, branch_name, title, body, dry_run):
@@ -433,6 +426,36 @@ def get_commit_author(commit_hash):
raise
def get_all_co_author_lines(commit_hash, commit_message):
"""
Build a deduplicated list of Co-authored-by lines that includes both
the primary commit author and any Co-authored-by trailers already
present in the commit message.
Returns a list of unique "Co-authored-by: Name <email>" strings.
"""
seen = set()
co_author_lines = []
def _add(name, email):
key = (name.strip(), email.strip().lower())
if key not in seen:
seen.add(key)
co_author_lines.append(f"Co-authored-by: {name.strip()} <{email.strip()}>")
# 1. Primary author of the commit
author_name, author_email = get_commit_author(commit_hash)
_add(author_name, author_email)
# 2. Existing Co-authored-by trailers in the commit message
for line in commit_message.splitlines():
m = re.match(r"^\s*Co-authored-by:\s*(.+?)\s*<([^>]+)>", line, re.IGNORECASE)
if m:
_add(m.group(1), m.group(2))
return co_author_lines
def main():
parser = argparse.ArgumentParser(
description="Copy a commit from the private repo to OSS and open a PR."
@@ -487,33 +510,67 @@ def main():
# 2. Get the OSS repo
oss_root, temp_dir = get_oss_repo(args.dry_run)
# 3. Get original commit author for the co-author line
author_name, author_email = get_commit_author(commit_hash)
# 3. Find the latest OSS commit that was synced into sglang-private.
# This is the correct base for our patch, since the private repo's
# code is based on this sync point.
base_oss_commit = find_latest_oss_sync_commit()
if base_oss_commit:
print(f" Will branch from OSS commit {base_oss_commit}")
else:
print(
"⚠️ Could not determine latest OSS sync commit. "
"Falling back to OSS main HEAD."
)
# 4. Prepare content for the commit and PR based on changed files
# 4. Get all co-author lines (primary author + trailers from commit message)
co_author_lines = get_all_co_author_lines(commit_hash, original_commit_message)
authors_display = "\n".join(co_author_lines)
# 5. Prepare content for the commit and PR based on changed files
file_list_str = "\n".join([f"- {f}" for f in relevant_files])
filename_list_str = ", ".join([f.split("/")[-1] for f in relevant_files])
if len(filename_list_str) > 40:
filename_list_str = filename_list_str[:40] + "..."
current_date = datetime.datetime.now().strftime("%Y%m%d")
pr_title = f"[Auto Sync] Update {filename_list_str} ({current_date})"
pr_body = (
f"Sync changes from commit `{short_hash}`.\n\n"
f"**Files Changed:**\n{file_list_str}\n\n"
f"Author: {author_name} <{author_email}>"
f"\n\n---\n\n"
f"*This is an automated PR created by scripts/copy_from_oss.py.*"
)
# 5. Create branch, apply patch, and push
# 6. Create branch from the last synced OSS commit, apply patch, and push
branch_name = f"sync-{short_hash}-{current_date}"
co_author_line = f"Co-authored-by: {author_name} <{author_email}>"
commit_message = f"{pr_title}\n\n{co_author_line}"
apply_patch_and_push(
oss_root, patch_file, branch_name, commit_message, args.dry_run
co_authors_block = "\n".join(co_author_lines)
commit_message = f"{pr_title}\n\n{co_authors_block}"
applied_cleanly = apply_patch_and_push(
oss_root,
patch_file,
branch_name,
commit_message,
base_oss_commit,
args.dry_run,
)
# 6. Create Pull Request
# 7. Adjust PR title and body when there are conflicts
if not applied_cleanly:
pr_title = (
f"[Auto Sync][⚠️ Conflicts] Update {filename_list_str} ({current_date})"
)
pr_body_parts = [
f"Sync changes from commit `{short_hash}`.\n",
f"**Files Changed:**\n{file_list_str}\n",
f"**Authors:**\n{authors_display}",
]
if not applied_cleanly:
pr_body_parts.append(
"\n\n⚠️ **This patch had merge conflicts.** "
"The branch contains conflict markers that must be resolved manually. "
"Please check the CI logs for the full patch and conflict details."
)
pr_body_parts.append(
f"\n\n---\n\n"
f"*This is an automated PR created by scripts/copy_to_oss.py.*"
)
pr_body = "\n".join(pr_body_parts)
# 8. Create Pull Request
create_pull_request(oss_root, branch_name, pr_title, pr_body, args.dry_run)
finally: