diff options
| author | Stefan Boberg <[email protected]> | 2025-11-13 16:10:35 +0100 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-11-13 16:10:35 +0100 |
| commit | 4c99b0238adb340c8659ac167d47f03136684ca5 (patch) | |
| tree | 42078fb266ea0e4e014f58c6d468e621d9d9182c | |
| parent | sentry/asan configuration tweaks (#649) (diff) | |
| download | zen-4c99b0238adb340c8659ac167d47f03136684ca5.tar.xz zen-4c99b0238adb340c8659ac167d47f03136684ca5.zip | |
Update to curl 8.17.0 (from 8.11.0) (#648)
Upgrade libcurl to 8.17.0 and enable native Mac CA validation via Apple SecTrust over the file-based approach which was in place previously. This should be more robust and more closely matches the behaviour of Apple's curl build and the rest of the OS.
| -rw-r--r-- | VERSION.txt | 2 | ||||
| -rw-r--r-- | repo/packages/l/libcurl/versions.txt | 4 | ||||
| -rw-r--r-- | repo/packages/l/libcurl/xmake.lua | 4 | ||||
| -rw-r--r-- | scripts/download_artifacts.py | 344 |
4 files changed, 351 insertions, 3 deletions
diff --git a/VERSION.txt b/VERSION.txt index ef0ff1640..a0697b195 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.7.9
\ No newline at end of file +5.7.10-pre0
\ No newline at end of file diff --git a/repo/packages/l/libcurl/versions.txt b/repo/packages/l/libcurl/versions.txt index 52b5001b0..6cca3e986 100644 --- a/repo/packages/l/libcurl/versions.txt +++ b/repo/packages/l/libcurl/versions.txt @@ -1,3 +1,7 @@ +8.17.0 230032528ce5f85594d4f3eace63364c4244ccc3c801b7f8db1982722f2761f4 +8.16.0 9459180ab4933b30d0778ddd71c91fe2911fab731c46e59b3f4c8385b1596c91 +8.15.0 699a6d2192322792c88088576cff5fe188452e6ea71e82ca74409f07ecc62563 +8.14.1 5760ed3c1a6aac68793fc502114f35c3e088e8cd5c084c2d044abdf646ee48fb 8.11.0 c95d5a1368803729345a632ce42cceeefd5f09c3b4d9582f858f6779f4b8b254 8.10.1 3763cd97aae41dcf41950d23e87ae23b2edb2ce3a5b0cf678af058c391b6ae31 8.10.0 be30a51f7bbe8819adf5a8e8cc6991393ede31f782b8de7b46235cc1eb7beb9f diff --git a/repo/packages/l/libcurl/xmake.lua b/repo/packages/l/libcurl/xmake.lua index 3c789e7f2..a5d80c61e 100644 --- a/repo/packages/l/libcurl/xmake.lua +++ b/repo/packages/l/libcurl/xmake.lua @@ -65,7 +65,7 @@ package("libcurl") elseif package:is_plat("linux", "bsd") then package:add("syslinks", "pthread") elseif package:is_plat("windows", "mingw") then - package:add("syslinks", "advapi32", "crypt32", "wldap32", "winmm", "ws2_32", "user32") + package:add("syslinks", "advapi32", "crypt32", "iphlpapi", "secur32", "wldap32", "winmm", "ws2_32", "user32") end if package:is_plat("mingw") and is_subhost("msys") then @@ -139,7 +139,7 @@ package("libcurl") table.insert(configs, (version:ge("7.80") and "-DCURL_USE_SCHANNEL=ON" or "-DCMAKE_USE_SCHANNEL=ON")) end if package:is_plat("macosx", "iphoneos") then - table.insert(configs, '-DCURL_CA_BUNDLE=/etc/ssl/cert.pem') + table.insert(configs, '-DUSE_APPLE_SECTRUST=ON') end if package:is_plat("windows") then table.insert(configs, "-DCURL_STATIC_CRT=" .. (package:runtimes():startswith("MT") and "ON" or "OFF")) diff --git a/scripts/download_artifacts.py b/scripts/download_artifacts.py new file mode 100644 index 000000000..52805738f --- /dev/null +++ b/scripts/download_artifacts.py @@ -0,0 +1,344 @@ +#!/usr/bin/env python3 +""" +Download GitHub release artifacts for Zen. + +This script downloads Mac, Linux, and Windows artifacts from the GitHub release +corresponding to the current version in VERSION.txt and copies them to a specified +UE (p4) workspace directory. + +Before copying the artifacts, it syncs (to head) the files contained in the downloaded +archives from Perforce and then opens them for editing and leaves them in the default +pending changelist. + +""" + +import argparse +import os +import sys +from pathlib import Path +import shutil +import subprocess + + +def read_version(repo_root): + """Read the version from VERSION.txt.""" + version_file = repo_root / "VERSION.txt" + if not version_file.exists(): + print(f"Error: VERSION.txt not found at {version_file}", file=sys.stderr) + sys.exit(1) + + version = version_file.read_text().strip() + print(f"Version: {version}") + return version + + +def download_artifact_gh(version, artifact_name, output_path, verbose=False): + """Download a release artifact using gh CLI.""" + print(f"Downloading {artifact_name}...") + print(f" To: {output_path}") + + try: + # Build gh release download command + cmd = ['gh', 'release', 'download', f'v{version}', '--pattern', artifact_name] + + if verbose: + print(f" Command: {' '.join(cmd)}") + + # Create a temporary directory as a subdirectory of current working directory + # so gh can access the git repository context + temp_dir = Path.cwd() / '.temp_download' + temp_dir.mkdir(exist_ok=True) + + try: + # Download to temp directory + result = subprocess.run( + cmd, + cwd=temp_dir, + capture_output=True, + text=True + ) + + if result.returncode != 0: + print(f" Error: gh release download failed", file=sys.stderr) + if result.stderr: + print(f" {result.stderr.strip()}", file=sys.stderr) + return False + + # Move the downloaded file to the target location + downloaded_file = temp_dir / artifact_name + if not downloaded_file.exists(): + print(f" Error: Downloaded file not found at {downloaded_file}", file=sys.stderr) + return False + + shutil.move(str(downloaded_file), str(output_path)) + + file_size = output_path.stat().st_size + print(f" Downloaded successfully ({file_size:,} bytes)") + return True + finally: + # Clean up temp directory + if temp_dir.exists(): + shutil.rmtree(temp_dir, ignore_errors=True) + + except FileNotFoundError: + print(f" Error: 'gh' command not found. Please install GitHub CLI.", file=sys.stderr) + print(f" Visit: https://cli.github.com/", file=sys.stderr) + return False + except Exception as e: + print(f" Error: {e}", file=sys.stderr) + return False + + +def get_archive_files(zip_path): + """Get list of files contained in the zip archive.""" + import zipfile + + try: + with zipfile.ZipFile(zip_path, 'r') as zip_ref: + return [info.filename for info in zip_ref.filelist if not info.is_dir()] + except Exception as e: + print(f" Error reading archive: {e}", file=sys.stderr) + return [] + + +def checkout_files_p4(target_dir, file_list, verbose=False): + """Check out specific files from Perforce.""" + if not file_list: + return True + + print(f"Checking out files from Perforce...") + + try: + # First sync files to latest revision + sync_cmd = ['p4', 'sync'] + file_list + + if verbose: + print(f" Command: {' '.join(sync_cmd)}") + print(f" Working directory: {target_dir}") + + sync_result = subprocess.run( + sync_cmd, + cwd=target_dir, + capture_output=True, + text=True + ) + + if sync_result.returncode == 0 or 'up-to-date' in sync_result.stdout: + if verbose and sync_result.stdout and sync_result.stdout.strip(): + print(f" {sync_result.stdout.strip()}") + else: + # Sync might fail if files don't exist yet, which is okay + if sync_result.stderr and sync_result.stderr.strip(): + print(f" Sync warning: {sync_result.stderr.strip()}") + + # Now check out files using p4 edit + # Use relative paths and run from target_dir so p4 can infer P4CLIENT correctly + cmd = ['p4', 'edit'] + file_list + + if verbose: + print(f" Command: {' '.join(cmd)}") + print(f" Working directory: {target_dir}") + + result = subprocess.run( + cmd, + cwd=target_dir, + capture_output=True, + text=True + ) + + if result.returncode == 0 or 'opened for edit' in result.stdout: + # Count how many files were opened + output_lines = result.stdout.strip().split('\n') if result.stdout.strip() else [] + file_count = len([line for line in output_lines if 'opened for edit' in line]) + print(f" Checked out {file_count} file(s)") + return True + else: + # p4 edit might return non-zero if files don't exist yet or are already open + # This is often not a fatal error + if result.stdout and result.stdout.strip(): + print(f" {result.stdout.strip()}") + if result.stderr and result.stderr.strip(): + print(f" {result.stderr.strip()}") + return True # Continue anyway + except FileNotFoundError: + print(f" Warning: 'p4' command not found. Skipping Perforce checkout.", file=sys.stderr) + return True # Continue without P4 + except Exception as e: + print(f" Warning: Error during P4 checkout: {e}", file=sys.stderr) + return True # Continue anyway + + +def revert_unchanged_files_p4(target_dir, file_list, verbose=False): + """Revert files that have no content changes from the checked-in version.""" + if not file_list: + return + + print(f"Reverting unchanged files...") + + try: + # Use p4 revert -a to revert unchanged files + # -a flag reverts files that are open for edit but have no content changes + revert_cmd = ['p4', 'revert', '-a'] + file_list + + if verbose: + print(f" Command: {' '.join(revert_cmd)}") + print(f" Working directory: {target_dir}") + + revert_result = subprocess.run( + revert_cmd, + cwd=target_dir, + capture_output=True, + text=True + ) + + if revert_result.returncode == 0: + # Count how many files were reverted + output_lines = revert_result.stdout.strip().split('\n') if revert_result.stdout.strip() else [] + # p4 revert -a outputs lines like "file.txt - was edit, reverted" + reverted_count = len([line for line in output_lines if 'reverted' in line.lower()]) + if reverted_count > 0: + print(f" Reverted {reverted_count} unchanged file(s)") + else: + print(f" No unchanged files to revert") + else: + if revert_result.stderr and revert_result.stderr.strip(): + print(f" Revert warning: {revert_result.stderr.strip()}") + except FileNotFoundError: + # p4 not available, skip + pass + except Exception as e: + print(f" Warning: Error during P4 revert: {e}", file=sys.stderr) + + +def extract_artifact(zip_path, target_dir, artifact_name): + """Extract a zip file to the target directory.""" + import zipfile + + print(f"Extracting {artifact_name}...") + print(f" To: {target_dir}") + + try: + with zipfile.ZipFile(zip_path, 'r') as zip_ref: + zip_ref.extractall(target_dir) + + print(f" Extracted successfully") + return True + except Exception as e: + print(f" Error extracting: {e}", file=sys.stderr) + return False + + +def main(): + parser = argparse.ArgumentParser( + description="Download Zen release artifacts from GitHub for the current version." + ) + parser.add_argument( + "output_dir", + type=Path, + help="Directory where artifacts will be copied" + ) + parser.add_argument( + "--version-file", + type=Path, + help="Path to VERSION.txt (default: auto-detect from script location)" + ) + parser.add_argument( + "-v", "--verbose", + action="store_true", + help="Print command lines before executing external commands" + ) + + args = parser.parse_args() + + # Determine repository root + if args.version_file: + repo_root = args.version_file.parent + else: + # Assume script is in scripts/ directory + script_dir = Path(__file__).resolve().parent + repo_root = script_dir.parent + + # Read version + version = read_version(repo_root) + + # Create output directory if it doesn't exist + output_dir = args.output_dir.resolve() + output_dir.mkdir(parents=True, exist_ok=True) + print(f"Output directory: {output_dir}\n") + + # Define artifacts to download + artifacts = [ + { + "name": "zenserver-win64.zip", + "platform": "Windows", + "target_subdir": "Engine/Binaries/Win64" + }, + { + "name": "zenserver-macos.zip", + "platform": "macOS", + "target_subdir": "Engine/Binaries/Mac" + }, + { + "name": "zenserver-linux.zip", + "platform": "Linux", + "target_subdir": "Engine/Binaries/Linux" + } + ] + + # Download each artifact + success_count = 0 + failed_artifacts = [] + + for artifact in artifacts: + artifact_name = artifact["name"] + platform = artifact["platform"] + target_subdir = artifact["target_subdir"] + + # Download to temporary location first + temp_path = output_dir / artifact_name + + # Target extraction directory + target_dir = output_dir / target_subdir + target_dir.mkdir(parents=True, exist_ok=True) + + # Download using gh CLI + print(f"[{platform}]") + if download_artifact_gh(version, artifact_name, temp_path, args.verbose): + # Get list of files in the archive + archive_files = get_archive_files(temp_path) + + # Check out only those specific files from P4 before extracting + if archive_files: + checkout_files_p4(target_dir, archive_files, args.verbose) + + # Extract to platform-specific directory + if extract_artifact(temp_path, target_dir, artifact_name): + # Revert any files that didn't actually change + if archive_files: + revert_unchanged_files_p4(target_dir, archive_files, args.verbose) + + # Remove temporary zip file + temp_path.unlink() + success_count += 1 + else: + failed_artifacts.append(f"{platform} ({artifact_name})") + else: + failed_artifacts.append(f"{platform} ({artifact_name})") + print() + + # Summary + print("=" * 60) + print(f"Download Summary:") + print(f" Successful: {success_count}/{len(artifacts)}") + if failed_artifacts: + print(f" Failed:") + for artifact in failed_artifacts: + print(f" - {artifact}") + sys.exit(1) + else: + print(f" All artifacts downloaded successfully!") + print(f" Location: {output_dir}") + + +if __name__ == "__main__": + main() |