From dd2712945037e84dc81cd1541b677061b41f2168 Mon Sep 17 00:00:00 2001 From: monsieurleberre Date: Thu, 24 Sep 2026 21:16:09 -0300 Subject: [PATCH 1/2] fix(csharp-ci): disable MSBuild node reuse on shared hetzner runners The hetzner-3/hetzner-4 self-hosted runners share one host and OS user. When one job finishes, its orphan-process cleanup kills idle MSBuild node processes that a different, still-running job on the sibling runner had left attached to for node reuse, so that job's build dies mid-flight with MSB4166 (node terminated unexpectedly). Set MSBUILDDISABLENODEREUSE: '1' on the build-and-test job so MSBuild never registers or reattaches to a shared out-of-proc node in the first place. scala-ci.yaml runs no dotnet/MSBuild and needs no change. Fixes the reusable-workflow half of peacefulstudio/daml-codegen-csharp-internal#1086; that repo's own inline jobs were already fixed in PR #1312, but env vars set by a workflow_call caller do not propagate into this workflow's own job env. --- .github/workflows/csharp-ci.yaml | 3 +++ CHANGELOG.md | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/.github/workflows/csharp-ci.yaml b/.github/workflows/csharp-ci.yaml index fd56966..9fe314e 100644 --- a/.github/workflows/csharp-ci.yaml +++ b/.github/workflows/csharp-ci.yaml @@ -248,6 +248,9 @@ jobs: contents: read packages: read pull-requests: write + # MSBuild node reuse: a sibling job's orphan-process cleanup on the shared hetzner-3/hetzner-4 host can kill this job's idle MSBuild node mid-build (peacefulstudio/daml-codegen-csharp-internal#1086) + env: + MSBUILDDISABLENODEREUSE: '1' defaults: run: shell: bash diff --git a/CHANGELOG.md b/CHANGELOG.md index eec6b8a..ae16474 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- Fix `csharp-ci.yaml`'s `build-and-test` job losing MSBuild mid-build with `MSB4166` ("node terminated unexpectedly") when a caller lands on the shared `hetzner-3`/`hetzner-4` self-hosted pool. The two runners share one host and OS user; when one job finishes, its orphan-process cleanup kills lingering MSBuild "node" processes, including idle out-of-proc nodes a *different*, still-running job on the sibling runner had left attached to for node reuse — that job's build then dies mid-flight. The job now sets `MSBUILDDISABLENODEREUSE: '1'`, which makes MSBuild skip the node-reuse handshake entirely (`XMake.cs` `ProcessNodeReuseSwitch`, `CommunicationsUtilities.cs:657`, `NodeProviderOutOfProcBase.cs:265-307`), so no job ever registers a shared out-of-proc node a sibling's cleanup could kill. `scala-ci.yaml` invokes no `dotnet`/MSBuild and is unaffected. First hit by `peacefulstudio/daml-codegen-csharp-internal` (issue #1086, fixed for that repo's own inline jobs in #1312); this closes the same gap in the reusable workflow, which the caller's job `env:` can't reach under `workflow_call`. Consumers on GitHub-hosted runners see no change. (#0) + ## [2.4.1] - 2026-08-30 ### Fixed From 18b658f2366467de806a7434936558478e174435 Mon Sep 17 00:00:00 2001 From: monsieurleberre Date: Thu, 24 Sep 2026 21:16:55 -0300 Subject: [PATCH 2/2] docs(changelog): reference PR #40 for the MSBuild node-reuse fix --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae16474..047ebfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- Fix `csharp-ci.yaml`'s `build-and-test` job losing MSBuild mid-build with `MSB4166` ("node terminated unexpectedly") when a caller lands on the shared `hetzner-3`/`hetzner-4` self-hosted pool. The two runners share one host and OS user; when one job finishes, its orphan-process cleanup kills lingering MSBuild "node" processes, including idle out-of-proc nodes a *different*, still-running job on the sibling runner had left attached to for node reuse — that job's build then dies mid-flight. The job now sets `MSBUILDDISABLENODEREUSE: '1'`, which makes MSBuild skip the node-reuse handshake entirely (`XMake.cs` `ProcessNodeReuseSwitch`, `CommunicationsUtilities.cs:657`, `NodeProviderOutOfProcBase.cs:265-307`), so no job ever registers a shared out-of-proc node a sibling's cleanup could kill. `scala-ci.yaml` invokes no `dotnet`/MSBuild and is unaffected. First hit by `peacefulstudio/daml-codegen-csharp-internal` (issue #1086, fixed for that repo's own inline jobs in #1312); this closes the same gap in the reusable workflow, which the caller's job `env:` can't reach under `workflow_call`. Consumers on GitHub-hosted runners see no change. (#0) +- Fix `csharp-ci.yaml`'s `build-and-test` job losing MSBuild mid-build with `MSB4166` ("node terminated unexpectedly") when a caller lands on the shared `hetzner-3`/`hetzner-4` self-hosted pool. The two runners share one host and OS user; when one job finishes, its orphan-process cleanup kills lingering MSBuild "node" processes, including idle out-of-proc nodes a *different*, still-running job on the sibling runner had left attached to for node reuse — that job's build then dies mid-flight. The job now sets `MSBUILDDISABLENODEREUSE: '1'`, which makes MSBuild skip the node-reuse handshake entirely (`XMake.cs` `ProcessNodeReuseSwitch`, `CommunicationsUtilities.cs:657`, `NodeProviderOutOfProcBase.cs:265-307`), so no job ever registers a shared out-of-proc node a sibling's cleanup could kill. `scala-ci.yaml` invokes no `dotnet`/MSBuild and is unaffected. First hit by `peacefulstudio/daml-codegen-csharp-internal` (issue #1086, fixed for that repo's own inline jobs in #1312); this closes the same gap in the reusable workflow, which the caller's job `env:` can't reach under `workflow_call`. Consumers on GitHub-hosted runners see no change. (#40) ## [2.4.1] - 2026-08-30