guard-step: stop the command when Woodpecker cancels a step with SIGKILL [CI]
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/verify Pipeline was successful
ci/woodpecker/push/dev-image Pipeline was canceled

This commit is contained in:
justme committed 2026-10-21 15:20:24 +08:00
1 parent d1ece67a6a
commit 334b96324d
2 files changed
+58 -1

No files matched your search

+17
View File
@@ -73,6 +73,23 @@ class GuardStepTests(unittest.TestCase):
self.assertFalse(alive(child))
self.assertEqual(self.guard('next', 30, 'true', stderr=subprocess.DEVNULL).wait(timeout=20), 125)
def test_sigkill_of_the_guard_like_a_woodpecker_cancel_still_stops_the_command(self):
# Woodpecker 取消步骤时只对步骤的进程组发 SIGKILL,守卫自己抓不到;命令在另一个会话里,要靠看门进程收尾
self.env['MOSHIRO_GUARD_GRACE'] = '1'
pid_file = Path(self.directory.name) / 'killed.pid'
step = self.guard('cancelled', 120, 'bash', '-c', f'echo $$ > {pid_file}; sleep 120 & wait', stderr=subprocess.DEVNULL)
deadline = time.monotonic() + 10
while not pid_file.exists() and time.monotonic() < deadline:
time.sleep(0.1)
time.sleep(0.5)
command = int(pid_file.read_text())
step.kill()
step.wait(timeout=10)
deadline = time.monotonic() + 15
while alive(command) and time.monotonic() < deadline:
time.sleep(0.2)
self.assertFalse(alive(command))
def test_a_background_process_left_by_a_finished_step_is_killed(self):
pid_file = Path(self.directory.name) / 'orphan.pid'
step = self.guard('leaky', 30, 'bash', '-c', f'sleep 120 & echo $! > {pid_file}', stderr=subprocess.DEVNULL)