Skip to content

Write SHA256SUMS.txt with LF so shasum -c works - #2384

Merged
erikdarlingdata merged 1 commit into
devfrom
fix/2383-checksum-lf
Aug 20, 2026
Merged

Write SHA256SUMS.txt with LF so shasum -c works#2384
erikdarlingdata merged 1 commit into
devfrom
fix/2383-checksum-lf

Conversation

@erikdarlingdata

Copy link
Copy Markdown
Owner

Fixes #2383, found verifying the v3.5.0 assets.

Out-File on Windows emits CRLF whatever the encoding, so shasum -c on macOS/Linux takes the trailing carriage return as part of the filename and reports every entry as No such file or directory / FAILED open or read. That is what a tampered or truncated download looks like — the hashes were always right, the file just could not be used by the tool it exists for, on the two platforms where that tool is the default.

$ tr -d '\r' < SHA256SUMS.txt | shasum -a 256 -c -
PerformanceMonitorDarling-3.5.0.zip: OK
PerformanceMonitorLite-3.5.0.zip: OK

WriteAllText with an explicit LF join also avoids a BOM, which would break the first entry identically.

Anchored on $PWD deliberately: [IO.File]::WriteAllText resolves relative paths against .NET's current directory rather than PowerShell's location, so the bare releases/SHA256SUMS.txt the old line used would not reliably land in the same place. That divergence is the trap in swapping Out-File for the .NET API.

SHA256SUMS-linux.txt is written by sha256sum on the Linux job and was never affected — it verifies as published.

Caveat: the step is gated on github.event_name == 'release', so this cannot be exercised by CI and lands unverified until the next release publishes. Worth actually running shasum -c against that release's checksum file rather than assuming.

Out-File on Windows emits CRLF whatever the encoding, and shasum -c on
macOS/Linux then takes the trailing carriage return as part of the
FILENAME. Every entry reports "No such file or directory / FAILED open
or read" -- which is exactly what a tampered or truncated download looks
like, so the output says "something is wrong with this release" when
nothing is.

The hashes were always correct. The file simply could not be used by the
tool it exists for, on the two platforms where that tool is the default
-- including the audience for the linux-x64 tarball.

WriteAllText with an explicit LF join also drops any BOM, which would
break the first entry the same way. Anchored on $PWD because
[IO.File]::WriteAllText resolves relative paths against .NET's current
directory rather than PowerShell's location.

SHA256SUMS-linux.txt is written by sha256sum on the Linux job and was
never affected.

Fixes #2383
@claude

claude Bot commented Aug 20, 2026

Copy link
Copy Markdown

Reviewed. The fix itself is correct and well-reasoned — [IO.File]::WriteAllText with an explicit LF join and a no-BOM UTF8Encoding is the right way to sidestep Out-File's CRLF-on-Windows behavior, and anchoring on $PWD instead of a bare relative path avoids the .NET-vs-PowerShell cwd divergence called out in the PR description. Nice catch, and nice repro in the description.

One gap: nightly.yml has the identical bug, unfixed.

.github/workflows/nightly.yml (its own "Generate checksums" step, around line 198) does the exact same thing this PR is fixing in build.yml:

$checksums | Out-File -FilePath releases/SHA256SUMS.txt -Encoding utf8

That's the same Out-File CRLF-on-Windows pattern that breaks shasum -c on macOS/Linux for the exact same reason described in this PR (trailing \r gets read as part of the filename → every entry reports "FAILED open or read"). Nightly releases ship a SHA256SUMS.txt too (covering *.zip and *.exe), so it inherits the same broken-verification problem this PR fixes for tagged releases. Since it's not part of this diff, GitHub won't let me leave an inline comment on it, but it seems worth porting the same fix there (or filing a follow-up against #2383) so nightly checksums aren't left silently broken while release checksums get fixed.

No other correctness/security issues found — this is a CI-only change with no SQL surface, so the T-SQL/Lite-Darling-parity conventions don't apply here.

@erikdarlingdata
erikdarlingdata merged commit d34d1aa into dev Aug 20, 2026
6 checks passed
@erikdarlingdata
erikdarlingdata deleted the fix/2383-checksum-lf branch August 20, 2026 09:44
erikdarlingdata added a commit that referenced this pull request Aug 21, 2026
Both were found by asking what in this release is verified by anything
other than reading the diff. The checksum fix was half-applied (#2384 fixed
the release workflow, not the nightly), and the dispatch-ref bug meant the
release candidate I built to soak was not the branch I dispatched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

1 participant