theavinash02/llm-code-deployer
1
1import os2import time3from github import Github, GithubException, BadCredentialsException, InputGitTreeElement4 5# Initialize the GitHub client using the token from environment variables6g = Github(os.getenv("GITHUB_TOKEN"))7github_user = g.get_user()8 9MIT_LICENSE = """10MIT License11 12Copyright (c) 2025 Your Name13 14Permission is hereby granted, free of charge, to any person obtaining a copy15of this software and associated documentation files (the "Software"), to deal16in the Software without restriction, including without limitation the rights17to use, copy, modify, merge, publish, distribute, sublicense, and/or sell18copies of the Software, and to permit persons to whom the Software is19furnished to do so, subject to the following conditions:20 21The foregoing copyright notice and this permission notice shall be included in all22copies or substantial portions of the Software.23 24THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR25IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,26FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE27AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER28LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,29OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE30SOFTWARE.31"""32 33def create_or_get_repo(repo_name):34 """Creates a new public GitHub repo or gets it if it already exists for Round 2."""35 try:36 print(f"Creating new repository: {repo_name}")37 repo = github_user.create_repo(repo_name, private=False)38 time.sleep(2) # Brief pause to ensure repo is ready39 return repo40 except GithubException as e:41 if e.status == 422: # Repository already exists42 print(f"Repository {repo_name} already exists. Fetching it.")43 return g.get_repo(f"{github_user.login}/{repo_name}")44 else:45 raise e46 47def get_file_content(repo, file_path):48 """Gets the content of a file from a repo, used for Round 2 revisions."""49 try:50 file_content = repo.get_contents(file_path, ref=repo.default_branch)51 return file_content.decoded_content.decode('utf-8')52 except GithubException:53 return None # File not found54 55def update_repo_files(repo, files_to_commit, round_num):56 """Creates or updates files in the repo and returns the commit SHA."""57 commit_message = f"feat: Round {round_num} project setup"58 if round_num > 1:59 commit_message = f"feat: Round {round_num} revision based on new brief"60 61 # For Round 2+, update files using the Git Trees API62 try:63 # Check if repo is not empty to get the latest commit64 repo.get_contents("/")65 66 main_ref = repo.get_git_ref(f'heads/{repo.default_branch}')67 latest_commit = repo.get_git_commit(main_ref.object.sha)68 base_tree = repo.get_git_tree(latest_commit.sha)69 70 # *** THIS IS THE CORRECTED PART ***71 # Create a list of InputGitTreeElement objects72 element_list = [73 InputGitTreeElement(path, '100644', 'blob', content=content)74 for path, content in files_to_commit.items()75 ]76 77 # Create the new tree78 tree = repo.create_git_tree(element_list, base_tree)79 parent = latest_commit80 commit = repo.create_git_commit(commit_message, tree, [parent])81 main_ref.edit(commit.sha)82 83 final_commit_sha = commit.sha84 85 except GithubException: # Repo is empty (Round 1)86 for path, content in files_to_commit.items():87 repo.create_file(path, f"init: create {path}", content)88 commit = repo.get_commits().get_page(0)[0]89 final_commit_sha = commit.sha90 91 print(f"Successfully committed changes. SHA: {final_commit_sha}")92 return final_commit_sha93 94def enable_github_pages(repo):95 """Enables GitHub Pages for the repository and returns the URL."""96 try:97 source = {"source": {"branch": repo.default_branch, "path": "/"}}98 headers = {'Accept': 'application/vnd.github.v3+json'}99 repo._requester.requestJsonAndCheck("POST", repo.url + "/pages", input=source, headers=headers)100 print("GitHub Pages site created. It may take a minute to deploy.")101 except GithubException as e:102 if e.status == 409:103 print("GitHub Pages is already enabled.")104 else:105 print(f"An unexpected error occurred while enabling GitHub Pages: {e}")106 raise e107 108 pages_url = f"https://{github_user.login}.github.io/{repo.name}/"109 return pages_url110 111def deploy_project(task_id, files, round_num):112 """Full workflow: create repo, push files, enable pages, and return details."""113 repo = create_or_get_repo(task_id)114 115 files['LICENSE'] = MIT_LICENSE.replace("Your Name", github_user.name or github_user.login)116 117 commit_sha = update_repo_files(repo, files, round_num)118 pages_url = enable_github_pages(repo)119 120 print("Waiting 30 seconds for GitHub Pages to build...")121 time.sleep(30) 122 123 return {124 "repo_url": repo.html_url,125 "commit_sha": commit_sha,126 "pages_url": pages_url127 }