CI: Re-land file-hash cache keys with fix for Intel macOS libunwind regression#1700
Draft
CI: Re-land file-hash cache keys with fix for Intel macOS libunwind regression#1700
Conversation
Three fixes carried forward from the post-#1666 CI churn so the re-land doesn't re-introduce the same bugs. 1. Git tag fallback under fetch-depth: 2 git describe --tags --abbrev=0 requires the tagged commit to be reachable in local history; with fetch-depth: 2 it always resolves to "none", defeating tag-based cache rotation. Switch to git tag --sort=-v:refname | head -1 || true, which reads fetched tag refs regardless of shallow clone depth and stays compatible with bash pipefail. 2. Normalize Intel macOS dylib paths before codesign On macos-latest-large, ghcup's GHC links the final binary against libunwind from Homebrew's llvm@18 (/usr/local/opt/llvm@18/lib/ libunwind.1.dylib). End-user Macs without Homebrew LLVM don't have that path, so the v3.16.3 binary failed to launch with "dyld: Library not loaded" — this is the exact regression called out in the v3.16.4 changelog. Rewrite the load command to /usr/lib/libunwind.1.dylib (which ships with every macOS 11+ install) using install_name_tool, before codesign runs, so the re-sign covers the patched binary. 3. Regression guard for Homebrew dylib deps New CI step runs otool -L on each macOS binary and fails the build if any LC_LOAD_DYLIB references /usr/local/opt/ or /opt/homebrew/. Runs on both Intel and arm64 matrix entries so future regressions on either architecture are caught in PR CI instead of reaching a release. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Complements the otool Homebrew guard. The guard proves load commands do not reference Homebrew paths; the smoke-launch proves the binary actually boots (catching install_name_tool corruption, init-time failures, etc.). rendergraph is skipped because it reads piped JSON from stdin and errors without input — if fossa/diagnose/millhone launch, rendergraph loads through the same dyld path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Re-lands #1666 (file-hash + release-tag-rotation CI cache keys) together with a fix for the Intel macOS dynamic-linking regression that caused the original PR to be reverted in #1675 / v3.16.4.
Opening as a draft until the Intel-macOS artifact has been verified on a clean Mac without Homebrew LLVM.
What changed
Commit 1 — revert of the revert. Re-applies the PR #1666 diff verbatim:
hashFiles(...)-based cabal-store keys, release-tag-rotated dist-newstyle keys, and deletion ofcompute_cache_key.sh. See the original #1666 description for motivation (cache-pressure reduction + build-time variance on master).Commit 2 — three fixes carried forward:
Git tag fallback under
fetch-depth: 2(build-all.yml,bench.yml,integrations-test.yml).git describe --tags --abbrev=0requires the tagged commit to be reachable in local history, whichfetch-depth: 2breaks — it always resolved to"none", defeating tag-based cache rotation. Switched togit tag --sort=-v:refname | head -1 || true, which reads fetched tag refs regardless of shallow depth and stays compatible with bashpipefail.Normalize Intel macOS dylib paths before codesign (
build-all.yml). Onmacos-latest-large, ghcup's GHC links the final binary against libunwind from Homebrew'sllvm@18at/usr/local/opt/llvm@18/lib/libunwind.1.dylib. End-user Macs without Homebrew LLVM don't have that path, so the v3.16.3 binary failed to launch withdyld: Library not loaded— this is the exact regression called out in the v3.16.4 changelog ("revert caching changes as they caused a problem with missing libs on macos"). Rewrite the load command to/usr/lib/libunwind.1.dylib(system libunwind, present on every macOS 11+ install) usinginstall_name_tool, beforecodesignruns so the re-sign covers the patched binary.Regression guard for Homebrew dylib deps (
build-all.yml). New CI step runsotool -Lon each macOS binary and fails the build if anyLC_LOAD_DYLIBreferences/usr/local/opt/or/opt/homebrew/. Runs on both Intel and arm64 matrix entries so future regressions on either architecture are caught in PR CI instead of reaching a release.Evidence that the fix addresses the regression
Comparison of the released artifacts (no other build env differences):
Both binaries are otherwise identical (same size 112150704 bytes, same load commands, same SDK / minos). The libunwind entry is the only functional difference between them.
Acceptance criteria
/usr/local/opt/*or/opt/homebrew/*entries underotool -L.Testing plan
CI-side
install_name_toolstep on a scratch branch to confirm the guard catches the regression (can do this out-of-band to avoid polluting this PR's history).Binary-side (required before un-drafting)
macOS-intel-binariesartifact from this branch'sbuild-allrun.otool -L fossa | grep -E '/usr/local|/opt/homebrew'— expect no output../fossa --version. Expect the normal version string, not adyld: Library not loadederror.macOS-arm64-binariesartifact — same expectations.Regression history checks
refs/tags/...fetch conflict (actions/checkout@v6is already on master and carries forward).Risks
_Unwind_*C ABI that Haskell RTS / GHC rely on. If GHC starts using LLVM-specific unwinding intrinsics, the rewrite would break at runtime. Mitigation: the regression guard plus bare-Mac smoke test would catch this.macos-latest-largeimage moves libunwind to a different Homebrew path (e.g.,llvm@19), theinstall_name_tool -changewon't match and the guard will fire. That is the intended behavior — we want to be notified, not silently ship a broken binary.References
actions/checkout@v6bump (already on master).Checklist
.fossa.yml/fossa-deps/ subcommand changes.