Skip to content

Stop the chains on the way out, and update the actions - #1

Merged
inxilpro merged 2 commits into
mainfrom
claude/macos-actions-node-version-qwf6w3
Aug 13, 2026
Merged

inxilpro merged 2 commits into
mainfrom
claude/macos-actions-node-version-qwf6w3

Conversation

@inxilpro

Copy link
Copy Markdown
Contributor

What macOS was actually doing

Not hanging in the tests. The suite finished in six seconds with everything passing, and then the step sat there until the fifteen-minute job timeout cancelled it (run 31724590277):

17:13:16  Running: /bin/bash [bash 3.2.57(1)-release]
17:13:22  ............
17:13:22  12 examples, 0 failures
17:28:23  ##[error]The operation was canceled.
          Terminate orphan process: pid (22066) (sleep)
          Terminate orphan process: pid (1682) (bash)
          Terminate orphan process: pid (1210) (bash)

A macOS runner does not finish a step while a process that step started is still alive. Those orphans are the whole story, and the Linux runners simply never minded them — which is why this only ever showed on macOS.

Where the orphan came from

The library. A signal ran _finish, which removed the temp directory and exited without touching the chains, so the interrupt test left a chain shell running with nothing left to stop it. That is a bug on its own terms: the point of Ctrl-C on a build is that the compiler stops too. _finish now kills whatever has not reported a status before it cleans up, which covers the signal path and also a script that gives up before it reaches run.

The stray was immortal rather than merely slow because of a second thing. The fakes that stay busy waited on $WORK/done, a marker teardown deletes moments after it appears, so a fake that was mid-nap ended up waiting on a file that could never arrive. They now stop when $WORK goes as well — the same signal, and one that cannot be missed.

Reproduced locally before and after: the old code leaves /bin/sh …/driver.sh running with ppid 1, respawning a sleep every second in a $WORK that no longer exists. After the fix, nothing is left behind.

While in there

  • A driver that hangs is now killable. start_driver & made $! the wrapper subshell rather than the driver, so the watchdog was killing the wrapper and orphaning the very driver it meant to stop — the same class of bug, waiting to happen. The background copy execs, so the watchdog gets the driver's own pid, and a timed-out driver now says so instead of failing on a mystery status.
  • A spec for it. An interrupted driver now has to leave no chain running.
  • actions/checkout@v4@v7, which clears the Node.js 20 is deprecated warning. vmactions/freebsd-vm@v1 is already current (v1.5.3).
  • Lint is green again. It was failing on main at shellcheck, and two more failures were queued up behind it: shellcheck needed a source= directive to follow the example into the library, shfmt wanted a trailing newline, and checkbashisms read the space inside $(dirname "$0") as a second argument to the dot.

Checks

make check passes locally with the same tools CI uses (shellcheck 0.10.0, shfmt 3.10.0, checkbashisms from devscripts 2.23.7), and the suite is green under /bin/sh, dash and bash — 13 examples, no strays afterwards.


Generated by Claude Code

claude added 2 commits August 13, 2026 17:37
The macOS jobs were not hanging in the tests: the suite finished in six
seconds with all examples passing, and then the step sat there until the
fifteen-minute job timeout cancelled it. What held it open was a process
the suite left behind. The macOS runner does not finish a step while a
process that step started is still alive, and it says so at cleanup:

    Terminate orphan process: pid (22066) (sleep)
    Terminate orphan process: pid (1682) (bash)

The stray comes from the library. A signal ran _finish, which removed the
temp directory and exited without touching the chains, so the interrupt
test left a chain shell running with nothing to stop it. That is a bug in
its own right, since the point of Ctrl-C on a build is that the compiler
stops too, so _finish now kills whatever has not reported a status before
it cleans up. The Linux runners never minded the stray, which is why this
only ever showed on macOS.

The fakes that stay busy waited on $WORK/done, a marker teardown deletes
moments after it appears, so a fake mid-nap waited on a file that could
no longer arrive. They now stop when $WORK goes as well, which is the
same signal and cannot be missed.

Also, a driver that hangs is now killable: backgrounding start_driver
made $! the wrapper subshell rather than the driver, so the watchdog was
killing the wrapper and orphaning the driver it meant to stop. The
background copy execs, so the pid the watchdog gets is the driver's own,
and a timed-out driver says so instead of failing on a mystery status.

Alongside that, the workflow moves to actions/checkout@v7, which clears
the Node 20 deprecation warning, and lint goes green again: shellcheck
needed a source directive to follow the example into the library, shfmt
wanted a trailing newline, and checkbashisms read the space inside
$(dirname "$0") as a second argument to the dot.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ZzPaXJV5SX4DKtpQBmJkT
main renamed the variable and gave the chains proper labels; this keeps
that and adds back the two things lint still wants from the example: the
source directive shellcheck needs to follow the dot into the library, and
a trailing newline for shfmt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016ZzPaXJV5SX4DKtpQBmJkT
@inxilpro
inxilpro merged commit be6fa22 into main Aug 13, 2026
20 checks passed
@inxilpro
inxilpro deleted the claude/macos-actions-node-version-qwf6w3 branch August 13, 2026 17:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants