Skip to content

Commit d505245

Browse files
ci: fix real-stack workflow on Windows + macOS
CI surfaced two issues the local validation didn't catch: - Windows: `mvn -B -DskipTests package -Dmaven.javadoc.skip=true` fails on Windows runners because the default GitHub Actions shell on Windows is PowerShell, which mangles -D... arguments — it splits `-Dmaven.javadoc.skip=true` into ".javadoc.skip=true" treating it as a phase. Force `shell: bash` so Git Bash handles -D quoting consistently with Linux/macOS. - macOS: 15s port-file timeout was too short for cold-start macos-latest runners. Bump to 60s and surface the server's stdout+stderr on timeout for diagnostics.
1 parent 50c6609 commit d505245

2 files changed

Lines changed: 35 additions & 4 deletions

File tree

.github/workflows/heartbeat-real-stack.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ jobs:
4040
python-version: '3.11'
4141

4242
- name: Build SDK jar
43+
# bash on every OS — PowerShell on Windows mangles -D... arguments,
44+
# splitting `-Dmaven.javadoc.skip=true` into ".javadoc.skip=true" as
45+
# a phase. The bash shell on Windows runners (Git Bash) handles -D
46+
# quoting consistently with Linux/macOS.
47+
shell: bash
4348
run: mvn -B -DskipTests package -Dmaven.javadoc.skip=true
4449

4550
# Compile smoke + run real-stack E2E in a single shell so the

tests/heartbeat-real-stack/run_real_stack.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,42 @@ def main(argv: list[str]) -> int:
6666
)
6767

6868
try:
69-
# Wait for port file to appear.
70-
deadline = time.time() + 15
69+
# Wait for port file to appear. 60s is generous — macos-latest GitHub
70+
# runners can be slow to cold-start Python; 15s sometimes wasn't enough.
71+
# On any timeout we surface the server's stdout+stderr so the cause is
72+
# visible in CI logs instead of failing silently.
73+
deadline = time.time() + 60
74+
port_text: str | None = None
7175
while time.time() < deadline:
76+
if server_proc.poll() is not None:
77+
# Server crashed before writing the port file.
78+
stdout_bytes, _ = server_proc.communicate(timeout=2)
79+
output = stdout_bytes.decode("utf-8", errors="replace") if stdout_bytes else ""
80+
print(
81+
f"FAIL: server exited with code {server_proc.returncode} before writing port file.\n"
82+
f"--- server stdout/stderr ---\n{output}",
83+
file=sys.stderr,
84+
)
85+
return 1
7286
if port_file.exists():
7387
port_text = port_file.read_text().strip()
7488
if port_text:
7589
break
7690
time.sleep(0.1)
77-
else:
78-
print("FAIL: server didn't write port file in 15s", file=sys.stderr)
91+
if not port_text:
92+
# Port file timeout — kill server and surface its output.
93+
server_proc.terminate()
94+
try:
95+
stdout_bytes, _ = server_proc.communicate(timeout=5)
96+
except subprocess.TimeoutExpired:
97+
server_proc.kill()
98+
stdout_bytes, _ = server_proc.communicate()
99+
output = stdout_bytes.decode("utf-8", errors="replace") if stdout_bytes else ""
100+
print(
101+
"FAIL: server didn't write port file in 60s.\n"
102+
f"--- server stdout/stderr ---\n{output}",
103+
file=sys.stderr,
104+
)
79105
return 1
80106

81107
port = int(port_text)

0 commit comments

Comments
 (0)