-
Notifications
You must be signed in to change notification settings - Fork 5k
Update code sync scripts #17319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Update code sync scripts #17319
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,282 @@ | ||
| """ | ||
| List commits in the private repo that need to be synced to the OSS repo. | ||
|
|
||
| NOTE: | ||
| 1. You need to execute this script in the git root folder. | ||
|
|
||
| This script will: | ||
| 1. Find the most recent sync commit (message starts with | ||
| "[Automated PR] Copy OSS code from commit"). | ||
| 2. Scan commits after that point and keep those that touch the configured paths. | ||
| 3. Print a markdown summary with commit links and write it to GitHub Step Summary. | ||
|
|
||
| Usage: | ||
| python3 scripts/code_sync/check_commits.py | ||
| """ | ||
|
|
||
| import argparse | ||
| import os | ||
| import shutil | ||
| import subprocess | ||
| from typing import List, Optional, Tuple | ||
|
|
||
| # --- 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", | ||
| ] | ||
|
|
||
| private_repo = "your-org/sglang-private-repo" | ||
| sync_commit_prefix = r"\[Automated PR\] Copy OSS code from commit" | ||
merrymercy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| # --- Configuration End --- | ||
|
|
||
|
|
||
| def write_github_step_summary(content: str) -> None: | ||
| with open(os.environ["GITHUB_STEP_SUMMARY"], "a") as f: | ||
| f.write(content) | ||
merrymercy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| def check_dependencies() -> None: | ||
| """Check for required command-line tools.""" | ||
| if not shutil.which("git"): | ||
| raise EnvironmentError("git is not installed or not in PATH.") | ||
|
|
||
|
|
||
| def get_repo_from_origin() -> str: | ||
| """Try to infer the repo slug (owner/name) from git remote.origin.url.""" | ||
| try: | ||
| url = subprocess.run( | ||
| ["git", "config", "--get", "remote.origin.url"], | ||
| capture_output=True, | ||
| text=True, | ||
| check=True, | ||
| ).stdout.strip() | ||
| except subprocess.CalledProcessError: | ||
| return private_repo | ||
|
|
||
| if url.startswith("git@github.com:"): | ||
| repo = url.split("git@github.com:", 1)[1] | ||
| elif url.startswith("https://github.com/"): | ||
| repo = url.split("https://github.com/", 1)[1] | ||
| else: | ||
| return private_repo | ||
|
|
||
| if repo.endswith(".git"): | ||
| repo = repo[: -len(".git")] | ||
| return repo or private_repo | ||
|
|
||
|
|
||
| def get_last_sync_commit() -> Optional[str]: | ||
| """Find the most recent sync commit that copied from OSS.""" | ||
| try: | ||
| result = subprocess.run( | ||
| [ | ||
| "git", | ||
| "log", | ||
| "-1", | ||
| "--grep", | ||
| sync_commit_prefix, | ||
| "--format=%H", | ||
| ], | ||
| capture_output=True, | ||
| text=True, | ||
| check=True, | ||
| ).stdout.strip() | ||
| return result or None | ||
| except subprocess.CalledProcessError as e: | ||
| print(f"Error finding last sync commit: {e.stderr}") | ||
| return None | ||
|
|
||
|
|
||
| def get_commits_since(last_sync_hash: Optional[str]) -> List[str]: | ||
| """Get commit hashes from last sync commit (exclusive) to HEAD.""" | ||
| try: | ||
| if last_sync_hash: | ||
| command = ["git", "rev-list", f"{last_sync_hash}..HEAD"] | ||
| else: | ||
| command = ["git", "rev-list", "HEAD"] | ||
| result = subprocess.run( | ||
| command, capture_output=True, text=True, check=True | ||
| ).stdout.strip() | ||
| return [line for line in result.split("\n") if line] | ||
| except subprocess.CalledProcessError as e: | ||
| print(f"Error getting commit list: {e.stderr}") | ||
| return [] | ||
|
|
||
|
|
||
| def get_changed_files(commit_hash: str) -> List[str]: | ||
| try: | ||
| output = subprocess.run( | ||
| ["git", "diff-tree", "--no-commit-id", "--name-only", "-r", commit_hash], | ||
| capture_output=True, | ||
| text=True, | ||
| check=True, | ||
| ).stdout.strip() | ||
| return [line for line in output.split("\n") if line] | ||
| except subprocess.CalledProcessError as e: | ||
| print(f"Error getting changed files for {commit_hash}: {e.stderr}") | ||
| return [] | ||
|
|
||
|
|
||
| def is_relevant_path(changed_file: str, path_prefix: str) -> bool: | ||
| if changed_file == path_prefix: | ||
| return True | ||
| return changed_file.startswith(f"{path_prefix}/") | ||
|
|
||
|
|
||
| def get_relevant_files(changed_files: List[str]) -> List[str]: | ||
| return [ | ||
| changed_file | ||
| for changed_file in changed_files | ||
| if any(is_relevant_path(changed_file, path) for path in folder_names) | ||
| ] | ||
|
|
||
|
|
||
| def get_commit_summary(commit_hash: str) -> Tuple[str, str]: | ||
| """Return (subject, date) for a commit.""" | ||
| try: | ||
| output = subprocess.run( | ||
| ["git", "show", "-s", "--format=%s%x00%ad", "--date=short", commit_hash], | ||
| capture_output=True, | ||
| text=True, | ||
| check=True, | ||
| ).stdout.strip() | ||
| subject, commit_date = output.split("\x00", 1) | ||
| except subprocess.CalledProcessError as e: | ||
| print(f"Error getting commit subject for {commit_hash}: {e.stderr}") | ||
| subject = "(unknown subject)" | ||
| commit_date = "(unknown date)" | ||
| return subject, commit_date | ||
|
|
||
|
|
||
| def format_files_list(relevant_files: List[str]) -> str: | ||
| return "\n".join([f"- {file_path}" for file_path in relevant_files]) | ||
|
|
||
|
|
||
| def format_last_sync_block( | ||
| repo: str, subject: str, commit_hash: str, commit_date: str | ||
| ) -> str: | ||
| short_hash = commit_hash[:9] | ||
| commit_url = f"https://github.com/{repo}/commit/{commit_hash}" | ||
| return "\n".join( | ||
| [ | ||
| "## Last sync", | ||
| "", | ||
| f"#### {subject}", | ||
| f"date: {commit_date}", | ||
| f"commit: [{short_hash}]({commit_url})", | ||
| "", | ||
| ] | ||
| ) | ||
|
|
||
|
|
||
| def format_commit_block( | ||
| repo: str, | ||
| subject: str, | ||
| commit_hash: str, | ||
| commit_date: str, | ||
| relevant_files: List[str], | ||
| ) -> str: | ||
| short_hash = commit_hash[:9] | ||
| commit_url = f"https://github.com/{repo}/commit/{commit_hash}" | ||
| files_str = format_files_list(relevant_files) if relevant_files else "- None" | ||
| return "\n".join( | ||
| [ | ||
| f"#### {subject}", | ||
| f"date: {commit_date}", | ||
| "files to sync:", | ||
| files_str, | ||
| "", | ||
| f"commit: [{short_hash}]({commit_url})", | ||
| "", | ||
| ] | ||
| ) | ||
|
|
||
|
|
||
| def format_output( | ||
| repo: str, | ||
| last_sync: Optional[Tuple[str, str, str]], | ||
| commits: List[Tuple[str, str, str, List[str]]], | ||
| ) -> str: | ||
| lines: List[str] = [] | ||
| if last_sync: | ||
| subject, commit_hash, commit_date = last_sync | ||
| lines.append(format_last_sync_block(repo, subject, commit_hash, commit_date)) | ||
| else: | ||
| lines.extend(["## Last sync", "", "No sync commit found.", ""]) | ||
|
|
||
| lines.extend(["## Commits to sync", ""]) | ||
| if not commits: | ||
| lines.append("No commits need to be synced.") | ||
| return "\n".join(lines) + "\n" | ||
|
|
||
| for commit_hash, subject, commit_date, relevant_files in commits: | ||
| lines.append( | ||
| format_commit_block(repo, subject, commit_hash, commit_date, relevant_files) | ||
| ) | ||
|
|
||
| return "\n".join(lines) | ||
|
|
||
|
|
||
| def main() -> None: | ||
| parser = argparse.ArgumentParser( | ||
| description="List commits in the private repo that need to be synced to OSS." | ||
| ) | ||
| parser.add_argument( | ||
| "--limit", | ||
| type=int, | ||
| default=0, | ||
| help="Limit number of commits printed (0 means no limit).", | ||
| ) | ||
| args = parser.parse_args() | ||
|
|
||
| check_dependencies() | ||
|
|
||
| repo = get_repo_from_origin() | ||
| last_sync_hash = get_last_sync_commit() | ||
| last_sync_block = None | ||
| if last_sync_hash: | ||
| last_sync_subject, last_sync_date = get_commit_summary(last_sync_hash) | ||
| last_sync_block = (last_sync_subject, last_sync_hash, last_sync_date) | ||
|
|
||
| commits = get_commits_since(last_sync_hash) | ||
| if args.limit > 0: | ||
| commits = commits[: args.limit] | ||
|
|
||
| relevant_commits: List[Tuple[str, str, str, List[str]]] = [] | ||
| for commit_hash in commits: | ||
| changed_files = get_changed_files(commit_hash) | ||
| if not changed_files: | ||
| continue | ||
| relevant_files = get_relevant_files(changed_files) | ||
| if relevant_files: | ||
| subject, commit_date = get_commit_summary(commit_hash) | ||
| relevant_commits.append((commit_hash, subject, commit_date, relevant_files)) | ||
merrymercy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| output = format_output(repo, last_sync_block, relevant_commits) | ||
| print(output) | ||
| if os.environ.get("GITHUB_STEP_SUMMARY"): | ||
| write_github_step_summary(output) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.