act_runner v0.6.1 host-mode on Windows cannot run steps (unresolvable step-script
path) or stage JS actions; Windows containers are impractical for net48/x86/MXAccess.
Skip the windows + live-mxaccess jobs until a working Windows runner exists, so
push/PR checks are the green portable + java jobs. x86 Worker verification stays on
the manual windev worktree process. Re-enable via repo var WINDOWS_CI_ENABLED=true.
Claude-Session: https://claude.ai/code/session_01DMXXvNuPekkkrTEyPNxEkW
act host-mode on Windows does not materialize a JS action's dist/ (actions/checkout
fails with "Cannot find module .../dist/index.js"), so the windows + live-mxaccess
jobs check the repo out with plain git instead (public repo, anonymous https clone
of GITHUB_SHA). The self-hosted windev runner otherwise works (host mode, persistent).
Claude-Session: https://claude.ai/code/session_01DMXXvNuPekkkrTEyPNxEkW
CI now runs end-to-end: portable + java jobs green on fix/ci-selfhosted-tooling.
Flip the tracker status and record the root cause (runner container.network) and
the five real defects the run surfaced and fixed. windows/live-mxaccess jobs
remain queued pending a self-hosted windev runner.
Claude-Session: https://claude.ai/code/session_01DMXXvNuPekkkrTEyPNxEkW
The last portable failure: pytest-asyncio 1.x does not install a current event
loop for synchronous tests and clears it after each async test, so a later sync
test that builds a grpc.aio.Channel (create_channel) hit
"RuntimeError: There is no current event loop" on Python 3.12 depending on test
order (CI hit it; local order did not). Add an autouse conftest fixture that
ensures a usable current loop per test. Local: 127 passed, 1 skipped.
Claude-Session: https://claude.ai/code/session_01DMXXvNuPekkkrTEyPNxEkW
Two real defects the CI run surfaced (driving to fully green):
- OrphanWorkerTerminatorTests hard-coded a Windows path (C:\...); on the Linux
runner Path.GetFullPath does not root it, so the terminator's exact-path match
found nothing (Expected 2/1 kills, Actual 0). Use an OS-appropriate normalized
path so the matching logic is validated on every platform (5/5 pass locally).
- clients/java generated MxaccessWorker.java was stale — missing the canonical
max_frame_bytes field. Refreshed via `gradle generateProto` (protobuf 4.33.1,
the pinned version — the diff is purely the field, no version churn). Broaden
the ci.yml churn-revert to both generated aggregates so verify-clean still
guards real drift elsewhere.
Claude-Session: https://claude.ai/code/session_01DMXXvNuPekkkrTEyPNxEkW
Surfaced by the first real CI run on the self-hosted runner:
- scripts/check-codegen.ps1: `git status --porcelain` returns $null on a clean
tree, so `.Trim()` threw "cannot call a method on a null-valued expression" —
i.e. Check 2 could never report success. Pipe through Out-String (null -> '').
- clients/rust/protos/mxaccess_worker.proto: genuinely stale — missing the
canonical `max_frame_bytes` field. Refreshed from
src/ZB.MOM.WW.MxGateway.Contracts/Protos (Check 3 drift guard, added in P1).
- ci.yml java job: act cannot resolve the gradle/actions monorepo action
(`unsupported object type` on the v4 tag); install Gradle 9.5.1 directly instead
(matches the local build) since the repo has no gradle wrapper.
Claude-Session: https://claude.ai/code/session_01DMXXvNuPekkkrTEyPNxEkW
The portable and java jobs assumed tools GitHub-hosted runners preinstall but the
self-hosted catthehacker act image lacks: `pwsh` (the codegen freshness check uses
`shell: pwsh`) and `gradle` (the java job runs `gradle test`; the repo has no
wrapper). Install PowerShell as a .NET global tool (the SDK is already set up) and
provision gradle via gradle/actions/setup-gradle. No behavior change on
GitHub-hosted runners, which already have both.
Claude-Session: https://claude.ai/code/session_01DMXXvNuPekkkrTEyPNxEkW