24f3001764/llm_code_deployment-1
0
1import os2import time3from pathlib import Path4from github import Github, GithubException5from src.config import config6from src.utils import sanitize_repo_name, get_mit_license7from src.security_scanner import SecurityScanner8import logging9 10logger = logging.getLogger(__name__)11 12 13class GitHubManager:14 """Manage GitHub repository creation and Pages deployment"""15 16 def __init__(self):17 self.github = Github(config.GITHUB_TOKEN)18 self.user = self.github.get_user()19 self.scanner = SecurityScanner()20 21 async def create_and_deploy(self, app_dir: Path, task_id: str) -> tuple[str, str, str]:22 """23 Create repo, push code, enable Pages24 Returns: (repo_url, commit_sha, pages_url)25 """26 repo_name = sanitize_repo_name(task_id)27 28 # Scan for secrets before deploying29 logger.info("Running security scan on generated code...")30 if not self.scanner.scan_and_report(app_dir):31 logger.warning("Secrets detected in code - deployment may contain sensitive information")32 # Note: We continue deployment but log the warning33 # In production, you might want to fail here or sanitize automatically34 35 # Check if repo exists, delete if it does (for testing/re-runs)36 try:37 existing_repo = self.user.get_repo(repo_name)38 logger.warning(f"Repo {repo_name} already exists, deleting...")39 existing_repo.delete()40 time.sleep(2) # Wait for deletion to propagate41 except GithubException:42 pass # Repo doesn't exist, which is what we want43 44 # Create new repository45 repo = self.user.create_repo(46 name=repo_name,47 description=f"Auto-generated app for task {task_id}",48 private=False,49 auto_init=False50 )51 52 logger.info(f"Created repo: {repo.html_url}")53 54 # Add LICENSE55 license_content = get_mit_license()56 repo.create_file(57 path="LICENSE",58 message="Add MIT License",59 content=license_content60 )61 62 # Add README.md63 readme_path = app_dir / "README.md"64 with open(readme_path, 'r', encoding='utf-8') as f:65 readme_content = f.read()66 67 repo.create_file(68 path="README.md",69 message="Add README",70 content=readme_content71 )72 73 # Add index.html74 index_path = app_dir / "index.html"75 with open(index_path, 'r', encoding='utf-8') as f:76 index_content = f.read()77 78 file_obj = repo.create_file(79 path="index.html",80 message="Add application",81 content=index_content82 )83 84 commit_sha = file_obj['commit'].sha85 86 # Enable GitHub Pages87 try:88 repo.create_pages_site(source={"branch": "main", "path": "/"})89 logger.info("GitHub Pages enabled")90 except GithubException as e:91 if "already exists" in str(e):92 logger.info("GitHub Pages already enabled")93 else:94 raise95 96 # Wait for Pages to be ready97 pages_url = f"https://{config.GITHUB_USERNAME}.github.io/{repo_name}/"98 99 # Give Pages time to deploy100 logger.info("Waiting for GitHub Pages to deploy...")101 time.sleep(10)102 103 return repo.html_url, commit_sha, pages_url104 105 async def update_repo(self, repo_name: str, app_dir: Path, update_message: str) -> tuple[str, str]:106 """107 Update existing repo with new code108 Returns: (commit_sha, pages_url)109 """110 # Scan for secrets before updating111 logger.info("Running security scan on updated code...")112 if not self.scanner.scan_and_report(app_dir):113 logger.warning("Secrets detected in updated code - deployment may contain sensitive information")114 115 repo = self.user.get_repo(repo_name)116 117 # Update README.md118 readme_path = app_dir / "README.md"119 with open(readme_path, 'r', encoding='utf-8') as f:120 readme_content = f.read()121 122 try:123 readme_file = repo.get_contents("README.md")124 repo.update_file(125 path="README.md",126 message=f"Update README: {update_message}",127 content=readme_content,128 sha=readme_file.sha129 )130 except GithubException:131 # File doesn't exist, create it132 repo.create_file(133 path="README.md",134 message="Add README",135 content=readme_content136 )137 138 # Update index.html139 index_path = app_dir / "index.html"140 with open(index_path, 'r', encoding='utf-8') as f:141 index_content = f.read()142 143 index_file = repo.get_contents("index.html")144 file_obj = repo.update_file(145 path="index.html",146 message=f"Update application: {update_message}",147 content=index_content,148 sha=index_file.sha149 )150 151 commit_sha = file_obj['commit'].sha152 pages_url = f"https://{config.GITHUB_USERNAME}.github.io/{repo_name}/"153 154 # Wait for Pages to redeploy155 logger.info("Waiting for GitHub Pages to redeploy...")156 time.sleep(10)157 158 return commit_sha, pages_url159 