aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2025-11-13 16:10:35 +0100
committerGitHub Enterprise <[email protected]>2025-11-13 16:10:35 +0100
commit4c99b0238adb340c8659ac167d47f03136684ca5 (patch)
tree42078fb266ea0e4e014f58c6d468e621d9d9182c
parentsentry/asan configuration tweaks (#649) (diff)
downloadzen-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.txt2
-rw-r--r--repo/packages/l/libcurl/versions.txt4
-rw-r--r--repo/packages/l/libcurl/xmake.lua4
-rw-r--r--scripts/download_artifacts.py344
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()