Skip to content

Commit d3be181

Browse files
committed
ci: clean windows disk space in background
1 parent a153133 commit d3be181

File tree

4 files changed

+135
-1
lines changed

4 files changed

+135
-1
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,11 @@ jobs:
223223
cd src/ci/citool
224224
CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=../../../build/citool cargo build
225225
226+
- name: wait for Windows disk cleanup to finish
227+
if: ${{ matrix.free_disk && startsWith(matrix.os, 'windows-') }}
228+
run: |
229+
python3 src/ci/scripts/free-disk-space-windows-wait.py
230+
226231
- name: run the build
227232
run: |
228233
set +e
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Start freeing disk space on Windows in the background by launching
4+
the existing PowerShell cleanup script, while recording a PID file
5+
and redirecting logs, so later steps can wait for completion.
6+
"""
7+
import os
8+
import sys
9+
import subprocess
10+
from pathlib import Path
11+
12+
13+
# Get the temporary directory set by GitHub Actions
14+
def get_temp_dir() -> Path:
15+
return Path(os.environ.get("RUNNER_TEMP"))
16+
17+
18+
def main() -> int:
19+
script_dir = Path(__file__).resolve().parent
20+
cleanup_script = script_dir / "free-disk-space-windows.ps1"
21+
if not cleanup_script.exists():
22+
print(f"::error file={__file__}::Cleanup script '{cleanup_script}' not found")
23+
return 1
24+
25+
temp_dir = get_temp_dir()
26+
pid_file = temp_dir / "free-disk-space.pid"
27+
log_file_path = temp_dir / "free-disk-space.log"
28+
29+
if pid_file.exists():
30+
print(f"::error file={__file__}::Pid file '{pid_file}' already exists")
31+
return 1
32+
33+
# Launch the PowerShell cleanup in the background and redirect logs
34+
try:
35+
with open(log_file_path, "w", encoding="utf-8") as log_file:
36+
proc = subprocess.Popen(
37+
[
38+
"pwsh",
39+
# Suppress PowerShell startup banner/logo for cleaner logs.
40+
"-NoLogo",
41+
# Don't load user/system profiles. Ensures a clean, predictable environment.
42+
"-NoProfile",
43+
# Disable interactive prompts. Required for CI to avoid hangs.
44+
"-NonInteractive",
45+
# Execute the specified script file (next argument).
46+
"-File",
47+
str(cleanup_script),
48+
],
49+
# Write child stdout to the log file
50+
stdout=log_file,
51+
# Merge stderr into stdout for a single, ordered log stream
52+
stderr=subprocess.STDOUT,
53+
)
54+
except FileNotFoundError:
55+
print("::error::pwsh not found on PATH; cannot start disk cleanup.")
56+
return 1
57+
58+
pid_file.write_text(str(proc.pid))
59+
print(
60+
f"::notice file={__file__}::Started free-disk-space cleanup in background (PID={proc.pid}); log: {log_file_path}; pidfile: {pid_file}"
61+
)
62+
return 0
63+
64+
65+
if __name__ == "__main__":
66+
sys.exit(main())
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Wait for the background Windows disk cleanup process started by
4+
free-disk-space-windows-start.py, then print the full log.
5+
"""
6+
import os
7+
import sys
8+
import time
9+
import ctypes
10+
from pathlib import Path
11+
12+
13+
# Get the temporary directory set by GitHub Actions
14+
def get_temp_dir() -> Path:
15+
return Path(os.environ.get("RUNNER_TEMP"))
16+
17+
def is_process_running(pid: int) -> bool:
18+
PROCESS_QUERY_LIMITED_INFORMATION = 0x1000 # Sufficient for GetExitCodeProcess
19+
processHandle = ctypes.windll.kernel32.OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0,pid)
20+
if processHandle == 0:
21+
# Could be not running or we don't have sufficient rights to check
22+
return False
23+
else:
24+
ctypes.windll.kernel32.CloseHandle(processHandle)
25+
return True
26+
27+
28+
def main() -> int:
29+
temp_dir = get_temp_dir()
30+
pid_file = temp_dir / "free-disk-space.pid"
31+
log_file = temp_dir / "free-disk-space.log"
32+
33+
if not pid_file.exists():
34+
print("::notice::No background free-disk-space process to wait for.")
35+
return 0
36+
37+
try:
38+
pid = int(pid_file.read_text().strip().splitlines()[0])
39+
except Exception:
40+
# Delete the file if it exists
41+
pid_file.unlink(missing_ok=True)
42+
return 0
43+
44+
# Poll until process exits
45+
while is_process_running(pid):
46+
time.sleep(3)
47+
48+
# Delete the file if it exists
49+
pid_file.unlink(missing_ok=True)
50+
51+
if log_file.exists():
52+
print("free-disk-space logs:")
53+
# Print entire log; replace undecodable bytes to avoid exceptions.
54+
try:
55+
with open(log_file, "r", encoding="utf-8", errors="replace") as f:
56+
print(f.read())
57+
except Exception as e:
58+
print(f"::warning::Failed to read log file '{log_file}': {e}")
59+
return 0
60+
61+
62+
if __name__ == "__main__":
63+
sys.exit(main())

src/ci/scripts/free-disk-space.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ set -euo pipefail
44
script_dir=$(dirname "$0")
55

66
if [[ "${RUNNER_OS:-}" == "Windows" ]]; then
7-
pwsh $script_dir/free-disk-space-windows.ps1
7+
python3 "$script_dir/free-disk-space-windows-start.py"
88
else
99
$script_dir/free-disk-space-linux.sh
1010
fi

0 commit comments

Comments
 (0)