From ef31d3e21b806d84e2268d3c7ea62b63ec43e7d1 Mon Sep 17 00:00:00 2001 From: Nick Bolton Date: Fri, 19 Jan 2024 14:44:50 +0000 Subject: [PATCH] Script to install deps (Windows only for now) (#7331) * Script to install deps (Windows only for now) * Set runner temp dir for choco * Add missing os import * Modify for CI * Update CL * Improve logging * Update workflow to install deps via script * Explain 3.1.1 version lock --- .github/workflows/job-test-windows.yml | 4 +- ChangeLog | 1 + scripts/install_deps.py | 87 ++++++++++++++++++++++++++ scripts/lib/windows.py | 15 +++++ scripts/windows_daemon.py | 16 +---- 5 files changed, 108 insertions(+), 15 deletions(-) create mode 100644 scripts/install_deps.py create mode 100644 scripts/lib/windows.py diff --git a/.github/workflows/job-test-windows.yml b/.github/workflows/job-test-windows.yml index 7cb7aea83..cea68f2d4 100644 --- a/.github/workflows/job-test-windows.yml +++ b/.github/workflows/job-test-windows.yml @@ -59,8 +59,8 @@ jobs: $client.DownloadFile("https://binaries.symless.com/bonjour/BonjourSDK.zip",".\bonjoursdk.zip") [System.IO.Compression.ZipFile]::ExtractToDirectory(".\bonjoursdk.zip", "$env:BONJOUR_BASE_DIR") - - name: Install OpenSSL - run: choco install openssl -y --no-progress + - name: Install dependencies + run: python ./scripts/install_deps.py --skip cmake ninja - name: Add msbuild to PATH uses: microsoft/setup-msbuild@v1.0.2 diff --git a/ChangeLog b/ChangeLog index 37a8b2e4e..fcbdd88d3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -28,6 +28,7 @@ Tasks: - #7327 Only use Ninja to build on Windows - #7328 Reset error state before calling Process32Next - #1177 Split CMake presets into debug and release +- #7331 Script to install deps (Windows only for now) # 1.14.6 diff --git a/scripts/install_deps.py b/scripts/install_deps.py new file mode 100644 index 000000000..2de01f1ba --- /dev/null +++ b/scripts/install_deps.py @@ -0,0 +1,87 @@ +import os +from lib import windows +import subprocess +import sys +import argparse + +def main(): + """Entry point for the script.""" + + parser = argparse.ArgumentParser() + parser.add_argument('--pause-on-exit', action='store_true') + parser.add_argument('--skip', nargs='*', default=[]) + args = parser.parse_args() + + try: + deps = Deps(args.skip) + deps.install() + except Exception as e: + print(f'Error: {e}') + + if (args.pause_on_exit): + input('Press enter to continue...') + +class Deps: + + def __init__(self, skip): + self.skip = skip + + def install(self): + """Installs dependencies.""" + + if (sys.platform == 'win32'): + self.windows() + else: + print(f'Unsupported platform: {sys.platform}') + + def windows(self): + """Installs dependencies on Windows.""" + + if not windows.is_admin(): + windows.relaunch_as_admin(__file__) + sys.exit() + + ci_env = os.environ.get('CI') + if ci_env: + print('CI environment detected') + self.choco_ci() + + # already installed on github runners. + self.skip.extend(['cmake', 'ninja']) + + self.choco("cmake") + self.choco("ninja") + + # lock openssl to 3.1.1. as of 19th jan 2024, 3.2.0 breaks cmake configure. + self.choco("openssl", "3.1.1") + + def choco(self, package, version=None): + """Installs a package using Chocolatey.""" + + if (package in self.skip): + print(f'Skipping: {package}') + return + + args = ['choco', 'install', package] + + if (version): + args.extend(['--version', version]) + + args.extend(['-y', '--no-progress']) + + subprocess.run(args, shell=True, check=True) + + def choco_ci(self): + """Configures Chocolatey cache for CI.""" + + runner_temp_key = 'RUNNER_TEMP' + runner_temp = os.environ.get(runner_temp_key) + if runner_temp: + # sets the choco cache dir, which should match the dir in the ci cache action. + key_arg = '--name="cacheLocation"' + value_arg = f'--value="{runner_temp}/choco"' + subprocess.run(['choco', 'config', 'set', key_arg, value_arg], shell=True, check=True) + else: + print(f'Warning: CI environment variable {runner_temp_key} not set') + +main() diff --git a/scripts/lib/windows.py b/scripts/lib/windows.py new file mode 100644 index 000000000..be88e9b3a --- /dev/null +++ b/scripts/lib/windows.py @@ -0,0 +1,15 @@ +import ctypes +import sys + +def relaunch_as_admin(script): + args = ' '.join(sys.argv[1:]) + command = f'{script} --pause-on-exit {args}' + print(f'Re-launching script as admin: {command}') + ctypes.windll.shell32.ShellExecuteW(None, 'runas', sys.executable, command, None, 1) + +def is_admin(): + """Returns True if the current process has admin privileges.""" + try: + return ctypes.windll.shell32.IsUserAnAdmin() + except ctypes.WinError: + return False diff --git a/scripts/windows_daemon.py b/scripts/windows_daemon.py index 17d7df942..69d9e9306 100644 --- a/scripts/windows_daemon.py +++ b/scripts/windows_daemon.py @@ -1,9 +1,9 @@ import os import subprocess -import ctypes import sys import argparse import glob +from lib import windows BIN_NAME = 'synergyd' SOURCE_BIN_DIR = os.path.join('build', 'bin') @@ -21,11 +21,8 @@ def main(): parser.add_argument('--target-bin-name', default=BIN_NAME) args = parser.parse_args() - if not is_admin(): - print('Re-launching script as admin') - args = ' '.join(sys.argv[1:]) - command = f'{__file__} --pause-on-exit {args}' - ctypes.windll.shell32.ShellExecuteW(None, 'runas', sys.executable, command, None, 1) + if not windows.is_admin(): + windows.relaunch_as_admin(__file__) sys.exit() try: @@ -83,11 +80,4 @@ def copy_bin_files(source_bin_dir, target_bin_dir, source_bin_name, target_bin_n except subprocess.CalledProcessError as e: print(f'Copy failed: {e}') -def is_admin(): - """Returns True if the current process has admin privileges.""" - try: - return ctypes.windll.shell32.IsUserAnAdmin() - except ctypes.WinError: - return False - main()