From 2841253d05581c02629def26fa3a433c2e1cb211 Mon Sep 17 00:00:00 2001 From: Vadim Lebedev Date: Thu, 9 Oct 2025 18:27:24 +0300 Subject: [PATCH] fix: Windows runner cancellation delays due to LXC script execution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes issue where Windows runners experience delays in job cancellation and pickup of new jobs after cancellation. The problem occurred when Windows runners with LXC platform configuration attempted to execute Linux shell scripts during cleanup, causing failures and blocking the runner. Changes: - Add runtime OS detection in stopHostEnvironment() - Skip LXC script execution on Windows platforms - Implement Windows-specific cleanup using os.RemoveAll() - Ensure graceful error handling to prevent runner blocking - Preserve all existing LXC functionality on Linux/Unix systems The fix prevents "fork/exec stop-lxc.sh: directory name is invalid" errors and allows Windows runners to pick up new jobs immediately after cancellation, matching Linux/FreeBSD runner behavior. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- act/runner/run_context.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/act/runner/run_context.go b/act/runner/run_context.go index dd72ff09..509d4dda 100644 --- a/act/runner/run_context.go +++ b/act/runner/run_context.go @@ -260,6 +260,12 @@ func (rc *RunContext) stopHostEnvironment(ctx context.Context) error { return nil } + // Skip LXC script execution on Windows - LXC is not supported on Windows + if runtime.GOOS == "windows" { + logger.Debugf("Skipping LXC cleanup on Windows") + return rc.performWindowsHostCleanup(ctx) + } + var stopScript bytes.Buffer if err := stopTemplate.Execute(&stopScript, struct { Name string @@ -281,6 +287,24 @@ func (rc *RunContext) stopHostEnvironment(ctx context.Context) error { )(ctx) } +func (rc *RunContext) performWindowsHostCleanup(ctx context.Context) error { + logger := common.Logger(ctx) + + // Clean up the container root directory + if rc.JobContainer != nil { + root := rc.JobContainer.GetRoot() + if root != "" { + logger.Debugf("Cleaning up Windows host directory: %s", root) + if err := os.RemoveAll(root); err != nil { + logger.Debugf("Failed to remove directory %s: %v", root, err) + // Don't fail cleanup if directory removal fails - this prevents blocking + // the runner from picking up new jobs due to file system issues + } + } + } + return nil +} + func (rc *RunContext) startHostEnvironment() common.Executor { return func(ctx context.Context) error { logger := common.Logger(ctx)