|
| 1 | +"""Netcode configuration for the release process automation.""" |
| 2 | + |
| 3 | +import datetime |
| 4 | +import sys |
| 5 | +import os |
| 6 | +from github import Github |
| 7 | +from github import GithubException |
| 8 | + |
| 9 | +PARENT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '../')) |
| 10 | +sys.path.insert(0, PARENT_DIR) |
| 11 | + |
| 12 | +from Utils.general_utils import get_package_version_from_manifest |
| 13 | +from release import make_package_release_ready |
| 14 | + |
| 15 | +class GithubUtils: |
| 16 | + def __init__(self, access_token, repo): |
| 17 | + self.github = Github(base_url="https://api.github.com", |
| 18 | + login_or_token=access_token) |
| 19 | + self.repo = self.github.get_repo(repo) |
| 20 | + |
| 21 | + def is_branch_present(self, branch_name): |
| 22 | + try: |
| 23 | + self.repo.get_branch(branch_name) |
| 24 | + return True # Branch exists |
| 25 | + |
| 26 | + except GithubException as ghe: |
| 27 | + if ghe.status == 404: |
| 28 | + return False # Branch does not exist |
| 29 | + raise Exception(f"An error occurred with the GitHub API: {ghe.status}", data=ghe.data) |
| 30 | + |
| 31 | +class ReleaseConfig: |
| 32 | + """A simple class to hold all shared configuration.""" |
| 33 | + def __init__(self): |
| 34 | + self.manifest_path = 'com.unity.netcode.gameobjects/package.json' |
| 35 | + self.changelog_path = 'com.unity.netcode.gameobjects/CHANGELOG.md' |
| 36 | + self.validation_exceptions_path = './ValidationExceptions.json' |
| 37 | + self.github_repo = 'Unity-Technologies/com.unity.netcode.gameobjects' |
| 38 | + self.default_repo_branch = 'develop-2.0.0' # Changelog and package version change will be pushed to this branch |
| 39 | + self.yamato_project_id = '1201' |
| 40 | + self.command_to_run_on_release_branch = make_package_release_ready |
| 41 | + |
| 42 | + self.release_weekday = 5 # Saturday |
| 43 | + self.release_week_cycle = 4 # Release every 4 weeks |
| 44 | + self.anchor_date = datetime.date(2025, 7, 19) # Anchor date for the release cycle (previous release Saturday) |
| 45 | + |
| 46 | + self.package_version = get_package_version_from_manifest(self.manifest_path) |
| 47 | + self.release_branch_name = f"release/{self.package_version}" # Branch from which we want to release |
| 48 | + self.commit_message = f"Updated changelog and package version for Netcode in anticipation of v{self.package_version} release" |
| 49 | + |
| 50 | + GITHUB_TOKEN_NAME = "NETCODE_GITHUB_TOKEN" |
| 51 | + YAMATO_API_KEY_NAME = "NETCODE_YAMATO_API_KEY" |
| 52 | + self.github_token = os.environ.get(GITHUB_TOKEN_NAME) |
| 53 | + self.yamato_api_token = os.environ.get(YAMATO_API_KEY_NAME) |
| 54 | + self.commiter_name = "netcode-automation" |
| 55 | + self. commiter_email = "[email protected]" |
| 56 | + |
| 57 | + self.yamato_samples_to_build = [ |
| 58 | + { |
| 59 | + "name": "BossRoom", |
| 60 | + "jobDefinition": f".yamato%2Fproject-builders%2Fproject-builders.yml%23build_BossRoom_project", |
| 61 | + }, |
| 62 | + { |
| 63 | + "name": "Asteroids", |
| 64 | + "jobDefinition": f".yamato%2Fproject-builders%2Fproject-builders.yml%23build_Asteroids_project", |
| 65 | + }, |
| 66 | + { |
| 67 | + "name": "SocialHub", |
| 68 | + "jobDefinition": f".yamato%2Fproject-builders%2Fproject-builders.yml%23build_SocialHub_project", |
| 69 | + } |
| 70 | + ] |
| 71 | + |
| 72 | + self.yamato_build_automation_configs = [ |
| 73 | + { |
| 74 | + "job_name": "Build Sample for Windows with minimal supported editor (2022.3), burst ON, IL2CPP", |
| 75 | + "variables": [ |
| 76 | + { "key": "BURST_ON_OFF", "value": "on" }, |
| 77 | + { "key": "PLATFORM_WIN64_MAC_ANDROID", "value": "win64" }, |
| 78 | + { "key": "SCRIPTING_BACKEND_IL2CPP_MONO", "value": "il2cpp" }, |
| 79 | + { "key": "UNITY_VERSION", "value": "2022.3" } # Minimal supported editor |
| 80 | + ] |
| 81 | + }, |
| 82 | + { |
| 83 | + "job_name": "Build Sample for Windows with latest functional editor (6000.2), burst ON, IL2CPP", |
| 84 | + "variables": [ |
| 85 | + { "key": "BURST_ON_OFF", "value": "on" }, |
| 86 | + { "key": "PLATFORM_WIN64_MAC_ANDROID", "value": "win64" }, |
| 87 | + { "key": "SCRIPTING_BACKEND_IL2CPP_MONO", "value": "il2cpp" }, |
| 88 | + { "key": "UNITY_VERSION", "value": "6000.2" } # Editor that most our users will use (not alpha). Sometimes when testing on trunk we have weird editor issues not caused by us so the preference will be to test on latest editor that our users will use. |
| 89 | + ] |
| 90 | + }, |
| 91 | + { |
| 92 | + "job_name": "Build Sample for Windows with latest editor (trunk), burst ON, IL2CPP", |
| 93 | + "variables": [ |
| 94 | + { "key": "BURST_ON_OFF", "value": "on" }, |
| 95 | + { "key": "PLATFORM_WIN64_MAC_ANDROID", "value": "win64" }, |
| 96 | + { "key": "SCRIPTING_BACKEND_IL2CPP_MONO", "value": "il2cpp" }, |
| 97 | + { "key": "UNITY_VERSION", "value": "trunk" } # latest editor |
| 98 | + ] |
| 99 | + }, |
| 100 | + { |
| 101 | + "job_name": "Build Sample for MacOS with minimal supported editor (2022.3), burst OFF, Mono", |
| 102 | + "variables": [ |
| 103 | + { "key": "BURST_ON_OFF", "value": "off" }, |
| 104 | + { "key": "PLATFORM_WIN64_MAC_ANDROID", "value": "mac" }, |
| 105 | + { "key": "SCRIPTING_BACKEND_IL2CPP_MONO", "value": "mono" }, |
| 106 | + { "key": "UNITY_VERSION", "value": "2022.3" } # Minimal supported editor |
| 107 | + ] |
| 108 | + }, |
| 109 | + { |
| 110 | + "job_name": "Build Sample for MacOS with latest functional editor (6000.2), burst OFF, Mono", |
| 111 | + "variables": [ |
| 112 | + { "key": "BURST_ON_OFF", "value": "off" }, |
| 113 | + { "key": "PLATFORM_WIN64_MAC_ANDROID", "value": "mac" }, |
| 114 | + { "key": "SCRIPTING_BACKEND_IL2CPP_MONO", "value": "mono" }, |
| 115 | + { "key": "UNITY_VERSION", "value": "6000.2" } # Editor that most our users will use (not alpha). Sometimes when testing on trunk we have weird editor issues not caused by us so the preference will be to test on latest editor that our users will use. |
| 116 | + ] |
| 117 | + }, |
| 118 | + { |
| 119 | + "job_name": "Build Sample for MacOS with latest editor (trunk), burst OFF, Mono", |
| 120 | + "variables": [ |
| 121 | + { "key": "BURST_ON_OFF", "value": "off" }, |
| 122 | + { "key": "PLATFORM_WIN64_MAC_ANDROID", "value": "mac" }, |
| 123 | + { "key": "SCRIPTING_BACKEND_IL2CPP_MONO", "value": "mono" }, |
| 124 | + { "key": "UNITY_VERSION", "value": "trunk" } # latest editor |
| 125 | + ] |
| 126 | + }, |
| 127 | + { |
| 128 | + "job_name": "Build Sample for Android with minimal supported editor (2022.3), burst ON, IL2CPP", |
| 129 | + "variables": [ |
| 130 | + { "key": "BURST_ON_OFF", "value": "on" }, |
| 131 | + { "key": "PLATFORM_WIN64_MAC_ANDROID", "value": "android" }, |
| 132 | + { "key": "SCRIPTING_BACKEND_IL2CPP_MONO", "value": "il2cpp" }, |
| 133 | + { "key": "UNITY_VERSION", "value": "2022.3" } # Minimal supported editor |
| 134 | + ] |
| 135 | + }, |
| 136 | + { |
| 137 | + "job_name": "Build Sample for Android with latest functional editor (6000.2), burst ON, IL2CPP", |
| 138 | + "variables": [ |
| 139 | + { "key": "BURST_ON_OFF", "value": "on" }, |
| 140 | + { "key": "PLATFORM_WIN64_MAC_ANDROID", "value": "android" }, |
| 141 | + { "key": "SCRIPTING_BACKEND_IL2CPP_MONO", "value": "il2cpp" }, |
| 142 | + { "key": "UNITY_VERSION", "value": "6000.2" } # Editor that most our users will use (not alpha). Sometimes when testing on trunk we have weird editor issues not caused by us so the preference will be to test on latest editor that our users will use. |
| 143 | + ] |
| 144 | + }, |
| 145 | + { |
| 146 | + "job_name": "Build Sample for Android with latest editor (trunk), burst ON, IL2CPP", |
| 147 | + "variables": [ |
| 148 | + { "key": "BURST_ON_OFF", "value": "on" }, |
| 149 | + { "key": "PLATFORM_WIN64_MAC_ANDROID", "value": "android" }, |
| 150 | + { "key": "SCRIPTING_BACKEND_IL2CPP_MONO", "value": "il2cpp" }, |
| 151 | + { "key": "UNITY_VERSION", "value": "trunk" } # latest editor |
| 152 | + ] |
| 153 | + } |
| 154 | + ] |
| 155 | + |
| 156 | + error_messages = [] |
| 157 | + if not os.path.exists(self.manifest_path): |
| 158 | + error_messages.append(f" Path does not exist: {self.manifest_path}") |
| 159 | + |
| 160 | + if not os.path.exists(self.changelog_path): |
| 161 | + error_messages.append(f" Path does not exist: {self.changelog_path}") |
| 162 | + |
| 163 | + if not os.path.exists(self.validation_exceptions_path): |
| 164 | + error_messages.append(f" Path does not exist: {self.validation_exceptions_path}") |
| 165 | + |
| 166 | + if not callable(self.command_to_run_on_release_branch): |
| 167 | + error_messages.append("command_to_run_on_release_branch is not a function! Actual value:", self.command_to_run_on_release_branch) |
| 168 | + |
| 169 | + if self.package_version is None: |
| 170 | + error_messages.append(f"Package version not found at {self.manifest_path}") |
| 171 | + |
| 172 | + if not self.github_token: |
| 173 | + error_messages.append(f"Error: {GITHUB_TOKEN_NAME} environment variable not set.") |
| 174 | + |
| 175 | + if not self.yamato_api_token: |
| 176 | + error_messages.append(f"Error: {YAMATO_API_KEY_NAME} environment variable not set.") |
| 177 | + |
| 178 | + # Initialize PyGithub and get the repository object |
| 179 | + self.github_manager = GithubUtils(self.github_token, self.github_repo) |
| 180 | + |
| 181 | + if not self.github_manager.is_branch_present(self.default_repo_branch): |
| 182 | + error_messages.append(f"Branch '{self.default_repo_branch}' does not exist.") |
| 183 | + |
| 184 | + if self.github_manager.is_branch_present(self.release_branch_name): |
| 185 | + error_messages.append(f"Branch '{self.release_branch_name}' is already present in the repo.") |
| 186 | + |
| 187 | + if error_messages: |
| 188 | + summary = "Failed to initialize NetcodeReleaseConfig due to invalid setup:\n" + "\n".join(f"- {msg}" for msg in error_messages) |
| 189 | + raise ValueError(summary) |
0 commit comments