about summary refs log tree commit diff
path: root/src/ci/scripts
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2025-08-15 15:44:03 +0000
committerbors <bors@rust-lang.org>2025-08-15 15:44:03 +0000
commit8b1889cc22439e02cf03cd8cff9764a307b21193 (patch)
tree1f3e2701b5207d409be0c0b7b8415ba1c66c394b /src/ci/scripts
parentc018ae5389c49cc4bcb8343d80dd8e7323325410 (diff)
parent9bf76aba76ecdc3c1524e005e13d8319d5ae4f7b (diff)
downloadrust-8b1889cc22439e02cf03cd8cff9764a307b21193.tar.gz
rust-8b1889cc22439e02cf03cd8cff9764a307b21193.zip
Auto merge of #145450 - Kobzol:rollup-cqclix0, r=Kobzol
Rollup of 11 pull requests

Successful merges:

 - rust-lang/rust#144210 (std: thread: Return error if setting thread stack size fails)
 - rust-lang/rust#145310 (Reduce usage of `compiler_for` in bootstrap)
 - rust-lang/rust#145311 (ci: clean windows disk space in background)
 - rust-lang/rust#145340 (Split codegen backend check step into two and don't run it with `x check compiler`)
 - rust-lang/rust#145408 (Deduplicate -L search paths)
 - rust-lang/rust#145412 (Windows: Replace `GetThreadId`+`GetCurrentThread` with `GetCurrentThreadId`)
 - rust-lang/rust#145413 (bootstrap: Reduce dependencies)
 - rust-lang/rust#145426 (Fix typos in bootstrap.example.toml)
 - rust-lang/rust#145430 (Fix wrong spans with external macros in the `dropping_copy_types` lint)
 - rust-lang/rust#145431 (Enhance UI test output handling for runtime errors)
 - rust-lang/rust#145448 (Autolabel `src/tools/{rustfmt,rust-analyzer}` changes with `T-{rustfmt,rust-analyzer}`)

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'src/ci/scripts')
-rw-r--r--src/ci/scripts/free-disk-space-windows-start.py72
-rw-r--r--src/ci/scripts/free-disk-space-windows-wait.py77
-rwxr-xr-xsrc/ci/scripts/free-disk-space.sh2
-rw-r--r--src/ci/scripts/free_disk_space_windows_util.py29
4 files changed, 179 insertions, 1 deletions
diff --git a/src/ci/scripts/free-disk-space-windows-start.py b/src/ci/scripts/free-disk-space-windows-start.py
new file mode 100644
index 00000000000..fbaad722bff
--- /dev/null
+++ b/src/ci/scripts/free-disk-space-windows-start.py
@@ -0,0 +1,72 @@
+"""
+Start freeing disk space on Windows in the background by launching
+the PowerShell cleanup script, and recording the PID in a file,
+so later steps can wait for completion.
+"""
+
+import subprocess
+from pathlib import Path
+from free_disk_space_windows_util import get_pid_file, get_log_file, run_main
+
+
+def get_cleanup_script() -> Path:
+    script_dir = Path(__file__).resolve().parent
+    cleanup_script = script_dir / "free-disk-space-windows.ps1"
+    if not cleanup_script.exists():
+        raise Exception(f"Cleanup script '{cleanup_script}' not found")
+    return cleanup_script
+
+
+def write_pid(pid: int):
+    pid_file = get_pid_file()
+    if pid_file.exists():
+        raise Exception(f"Pid file '{pid_file}' already exists")
+    pid_file.write_text(str(pid))
+    print(f"wrote pid {pid} in file {pid_file}")
+
+
+def launch_cleanup_process():
+    cleanup_script = get_cleanup_script()
+    log_file_path = get_log_file()
+    # Launch the PowerShell cleanup in the background and redirect logs.
+    try:
+        with open(log_file_path, "w", encoding="utf-8") as log_file:
+            proc = subprocess.Popen(
+                [
+                    "pwsh",
+                    # Suppress PowerShell startup banner/logo for cleaner logs.
+                    "-NoLogo",
+                    # Don't load user/system profiles. Ensures a clean, predictable environment.
+                    "-NoProfile",
+                    # Disable interactive prompts. Required for CI to avoid hangs.
+                    "-NonInteractive",
+                    # Execute the specified script file (next argument).
+                    "-File",
+                    str(cleanup_script),
+                ],
+                # Write child stdout to the log file.
+                stdout=log_file,
+                # Merge stderr into stdout for a single, ordered log stream.
+                stderr=subprocess.STDOUT,
+            )
+            print(
+                f"Started free-disk-space cleanup in background. "
+                f"pid={proc.pid}; log_file={log_file_path}"
+            )
+            return proc
+    except FileNotFoundError as e:
+        raise Exception("pwsh not found on PATH; cannot start disk cleanup.") from e
+
+
+def main() -> int:
+    proc = launch_cleanup_process()
+
+    # Write pid of the process to a file, so that later steps can read it and wait
+    # until the process completes.
+    write_pid(proc.pid)
+
+    return 0
+
+
+if __name__ == "__main__":
+    run_main(main)
diff --git a/src/ci/scripts/free-disk-space-windows-wait.py b/src/ci/scripts/free-disk-space-windows-wait.py
new file mode 100644
index 00000000000..b8612bb71c2
--- /dev/null
+++ b/src/ci/scripts/free-disk-space-windows-wait.py
@@ -0,0 +1,77 @@
+"""
+Wait for the background Windows disk cleanup process.
+"""
+
+import ctypes
+import time
+from free_disk_space_windows_util import get_pid_file, get_log_file, run_main
+
+
+def is_process_running(pid: int) -> bool:
+    PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
+    processHandle = ctypes.windll.kernel32.OpenProcess(
+        PROCESS_QUERY_LIMITED_INFORMATION, 0, pid
+    )
+    if processHandle == 0:
+        # The process is not running.
+        # If you don't have the sufficient rights to check if a process is running,
+        # zero is also returned. But in GitHub Actions we have these rights.
+        return False
+    else:
+        ctypes.windll.kernel32.CloseHandle(processHandle)
+        return True
+
+
+def print_logs():
+    """Print the logs from the cleanup script."""
+    log_file = get_log_file()
+    if log_file.exists():
+        print("free-disk-space logs:")
+        # Print entire log; replace undecodable bytes to avoid exceptions.
+        try:
+            with open(log_file, "r", encoding="utf-8", errors="replace") as f:
+                print(f.read())
+        except Exception as e:
+            raise Exception(f"Failed to read log file '{log_file}'") from e
+    else:
+        print(f"::warning::Log file '{log_file}' not found")
+
+
+def read_pid_from_file() -> int:
+    """Read the PID from the pid file."""
+
+    pid_file = get_pid_file()
+    if not pid_file.exists():
+        raise Exception(
+            f"No background free-disk-space process to wait for: pid file {pid_file} not found"
+        )
+
+    pid_file_content = pid_file.read_text().strip()
+
+    # Delete the file if it exists
+    pid_file.unlink(missing_ok=True)
+
+    try:
+        # Read the first line and convert to int.
+        pid = int(pid_file_content.splitlines()[0])
+        return pid
+    except Exception as e:
+        raise Exception(
+            f"Error while parsing the pid file with content '{pid_file_content!r}'"
+        ) from e
+
+
+def main() -> int:
+    pid = read_pid_from_file()
+
+    # Poll until process exits
+    while is_process_running(pid):
+        time.sleep(3)
+
+    print_logs()
+
+    return 0
+
+
+if __name__ == "__main__":
+    run_main(main)
diff --git a/src/ci/scripts/free-disk-space.sh b/src/ci/scripts/free-disk-space.sh
index 062ad801cd8..9264fe4de6d 100755
--- a/src/ci/scripts/free-disk-space.sh
+++ b/src/ci/scripts/free-disk-space.sh
@@ -4,7 +4,7 @@ set -euo pipefail
 script_dir=$(dirname "$0")
 
 if [[ "${RUNNER_OS:-}" == "Windows" ]]; then
-    pwsh $script_dir/free-disk-space-windows.ps1
+    python3 "$script_dir/free-disk-space-windows-start.py"
 else
     $script_dir/free-disk-space-linux.sh
 fi
diff --git a/src/ci/scripts/free_disk_space_windows_util.py b/src/ci/scripts/free_disk_space_windows_util.py
new file mode 100644
index 00000000000..488187864c2
--- /dev/null
+++ b/src/ci/scripts/free_disk_space_windows_util.py
@@ -0,0 +1,29 @@
+"""
+Utilities for Windows disk space cleanup scripts.
+"""
+
+import os
+from pathlib import Path
+import sys
+
+
+def get_temp_dir() -> Path:
+    """Get the temporary directory set by GitHub Actions."""
+    return Path(os.environ.get("RUNNER_TEMP"))
+
+
+def get_pid_file() -> Path:
+    return get_temp_dir() / "free-disk-space.pid"
+
+
+def get_log_file() -> Path:
+    return get_temp_dir() / "free-disk-space.log"
+
+
+def run_main(main_fn):
+    exit_code = 1
+    try:
+        exit_code = main_fn()
+    except Exception as e:
+        print(f"::error::{e}")
+    sys.exit(exit_code)