Skip to content

fix(firewall): cache the Windows binary as sfw.exe so the shims can run it - #24

Merged
Julian Gruber (juliangruber) merged 1 commit into
mainfrom
fix/windows-exe-binary
Oct 1, 2026
Merged

Julian Gruber (juliangruber) merged 1 commit into
mainfrom
fix/windows-exe-binary

Conversation

@juliangruber

@juliangruber Julian Gruber (juliangruber) commented Sep 30, 2026 •

Copy link
Copy Markdown
Member

Why

Found by the first dispatch of the CI simulation on main (run 36721798455): every Windows install through the current action failed, deterministically, while the pre-shim v1.3.2 action passed.

Runner Variant Runs OK
ubuntu-26.04 candidate (main) 10 10
ubuntu-26.04 baseline (v1.3.2) 10 10
windows-2025 baseline (v1.3.2) 10 10
windows-2025 candidate (main) 10 0
windows-11-arm candidate (main) 10 0

The install log:

'"C:\hostedtoolcache\windows\socket-firewall-free\1.15.3\x64\sfw"' is not recognized as an internal or external command,
operable program or batch file.

The binary is cached as sfw with no suffix. The .cmd shims the action writes run it through cmd.exe, which does not execute a suffix-less file, and neither does PowerShell. Bash on a Windows runner does, which is why sfw npm install typed in a workflow started fine: it then resolved npm to the shim, and the shim failed. So with the default shims: true, every Windows install via main has been broken since the shims landed in bad87d6 on Aug 4. Nobody hit it because no release has been tagged since March and current customer pins predate the shims.

What

Cache the file under FIREWALL_EXEC_FILE, sfw.exe on Windows and sfw elsewhere, the way PATCH_EXEC_NAME already does, and point the binary path (and therefore the shims) at it. FIREWALL_EXEC_NAME stays the bare name the release asset names are built from. One unit test. dist/ rebuilt.

Stacked on #23 so that dispatching the simulation on this branch produces a report.

Verification

Run 36723011554, the simulation dispatched on this branch, 3 iterations per runner:

Runner Variant Runs OK
windows-2025 candidate (this fix) 3 3
windows-11-arm candidate (this fix) 3 3
windows-2025 baseline v1.3.2 3 3
ubuntu-26.04 candidate 3 3
ubuntu-26.04 baseline v1.3.2 3 3

Windows goes from 0 of 10 on main to 3 of 3 here with only the file-name change.

🤖 Generated with Claude Code


Note

Medium Risk
Changes firewall install and cache paths on Windows (high-impact for CI), but scope is narrow and guarded by cache miss logic plus new unit tests.

Overview
Fixes broken Windows installs when package-manager shims are enabled: the action cached the firewall as sfw without an extension, but .cmd shims invoke the binary through cmd.exe, which requires sfw.exe.

Introduces FIREWALL_EXEC_FILE (sfw.exe on Windows, sfw elsewhere—matching the existing patch binary naming) and uses it for tool-cache storage, the resolved binary path, and shim targets. Adds findCachedFirewall so a runner tool-cache hit from older action versions (directory present but wrong filename) is treated as a miss and re-downloaded. dist/main.js is rebuilt; checksum reads switch to readFile from node:fs/promises.

Unit tests cover the platform-specific filename and cache validation behavior.

Reviewed by Cursor Bugbot for commit 8c28dcd. Configure here.

Comment thread src/tools/firewall.js
}

const pathBinary = path.join(pathCache, FIREWALL_EXEC_NAME)
const pathBinary = path.join(pathCache, FIREWALL_EXEC_FILE)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Blocking: an existing cache entry can point at a binary that isn't there.

Earlier action versions cached socket-firewall-<edition>/1.15.3/<arch>/sfw (no .exe) under the same cache key. find() (L168-170) only checks that the directory and its .complete marker exist, so on a self-hosted Windows runner that keeps its tool cache, the download is skipped. This line then builds ...\sfw.exe, which doesn't exist. The step goes green, and every shim fails afterwards until someone clears the cache.

Fix: if FIREWALL_EXEC_FILE isn't in pathCache after find(), treat it as a cache miss. Please add a unit test where find returns a directory containing only sfw.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 8c28dcd. findCachedFirewall wraps find and treats an entry without FIREWALL_EXEC_FILE as a miss, so the download runs and cacheFile replaces the stale entry under the same key.

Unit tests cover the three cases: no entry, an entry holding the binary this version runs, and an entry holding only the other name (sfw on Windows, sfw.exe elsewhere, so the miss is exercised on every CI platform rather than only on the Windows legs).

@Andre153 Andre Coetzee (Andre153) left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One blocker inline: a stale cache entry can point at a missing sfw.exe.

Two more things:

  • This doesn't depend on #23. Please retarget it to main and take it out of draft.
  • It needs to ship in the same release as #18. Without it, every Windows sfw npm call through the action fails.

…un it

Since the shims landed (bad87d6, Aug 4) every Windows install through
this action with the default `shims: true` has failed: the binary is
cached as `.../sfw` with no suffix, and the `.cmd` shims run it through
cmd.exe, which does not execute a suffix-less file ("is not recognized
as an internal or external command"). Bash on a Windows runner does, so
`sfw npm install` typed in a workflow started fine; it then resolved
`npm` to the shim, and the shim failed. The CI simulation on main showed
0 of 10 installs succeeding on windows-2025 and windows-11-arm against
10 of 10 for the pre-shim v1.3.2 action.

Cache the file under FIREWALL_EXEC_FILE, `sfw.exe` on Windows and `sfw`
elsewhere, the way PATCH_EXEC_NAME already does, and point the binary
path and therefore the shims at it. FIREWALL_EXEC_NAME stays the bare
name the release asset names are built from.

A tool cache kept between jobs can still hold an entry an earlier
version wrote under the same key, holding `sfw` and no `sfw.exe`.
`find` only checks the version directory and its `.complete` marker, so
it would hand that entry back and the step would go green with a binary
path that does not exist. findCachedFirewall treats an entry without
FIREWALL_EXEC_FILE as a miss, and the fresh download replaces it.
@juliangruber

This comment was marked as low quality.

@juliangruber
Julian Gruber (juliangruber) changed the base branch from ci/simulation-results-via-annotations to main October 1, 2026 10:02
@juliangruber
Julian Gruber (juliangruber) marked this pull request as ready for review October 1, 2026 10:02

@Andre153 Andre Coetzee (Andre153) left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cache check looks good. Ship in the same release as #18.

@juliangruber
Julian Gruber (juliangruber) merged commit 7396a59 into main Oct 1, 2026
9 of 10 checks passed
Julian Gruber (juliangruber) added a commit that referenced this pull request Oct 1, 2026
sfw v1.15.4 restores the "not found in PATH" verdict for a command
PowerShell genuinely cannot resolve on Windows (SocketDev/firewall#210);
v1.15.3 reported that case as a resolver error. The action installs only
the version its checksum table covers, so the fix is not installable
through it until this bump.

Recompute all twelve checksums from the published v1.15.4 assets and
rebuild dist/.

Also move findCachedFirewall above firewallDownloadUrls. #18 and #24
each passed lint on their own, but merging both left the export out of
the alphabetical order the sort-source-methods rule wants, which fails
lint on main and blocks any commit touching this file.
Julian Gruber (juliangruber) added a commit that referenced this pull request Oct 1, 2026
sfw v1.15.4 restores the "not found in PATH" verdict for a command
PowerShell genuinely cannot resolve on Windows (SocketDev/firewall#210);
v1.15.3 reported that case as a resolver error. The action installs only
the version its checksum table covers, so the fix is not installable
through it until this bump.

Recompute all twelve checksums from the published v1.15.4 assets and
rebuild dist/.

Also move findCachedFirewall above firewallDownloadUrls. #18 and #24
each passed lint on their own, but merging both left the export out of
the alphabetical order the sort-source-methods rule wants, which fails
lint on main and blocks any commit touching this file.
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