From edf07cff1e071fa1a2f936ee657f32ea4b1c50bd Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 12 Aug 2026 12:51:22 +0000 Subject: [PATCH 1/2] ci: verify the ferric Apple binaries depend on weak-node-api MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extends the "Test ferric Apple triplets" job so it doesn't only assert which architectures were produced, but also that each produced binary actually links the weak-node-api framework, catching regressions where a triplet builds but drops the dependency. The expected number of `@rpath/weak-node-api.framework/weak-node-api` lines is derived from the otool output itself — `otool -L` prints one header per file, or one per architecture for fat files — rather than hard-coded, so it doesn't rot when a triplet is added or dropped. Also renames lipo-info.txt to lipo-output.txt for symmetry with the new otool-output.txt, and uploads both as artifacts. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01SrPdjhQ6aG949mVDDaiT2U --- .github/workflows/check.yml | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 88635898..b5b47e5e 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -418,17 +418,24 @@ jobs: - run: pnpm exec ferric --apple working-directory: packages/ferric-example - name: Inspect the structure of the prebuilt binary - run: lipo -info ferric_example.apple.node/*/libferric_example.framework/libferric_example > lipo-info.txt + run: | + lipo -info ferric_example.apple.node/*/libferric_example.framework/libferric_example > lipo-output.txt + otool -L ferric_example.apple.node/*/libferric_example.framework/libferric_example > otool-output.txt working-directory: packages/ferric-example - - name: Upload lipo info + - name: Upload lipo output + uses: actions/upload-artifact@v7 + with: + name: lipo-output + path: packages/ferric-example/lipo-output.txt + - name: Upload otool output uses: actions/upload-artifact@v7 with: - name: lipo-info - path: packages/ferric-example/lipo-info.txt + name: otool-output + path: packages/ferric-example/otool-output.txt - name: Verify Apple triplet builds run: | # Create expected fixture content - cat > expected-lipo-info.txt << 'EOF' + cat > expected-lipo-output.txt << 'EOF' Architectures in the fat file: ferric_example.apple.node/ios-arm64_x86_64-simulator/libferric_example.framework/libferric_example are: x86_64 arm64 Architectures in the fat file: ferric_example.apple.node/macos-arm64_x86_64/libferric_example.framework/libferric_example are: x86_64 arm64 Architectures in the fat file: ferric_example.apple.node/tvos-arm64_x86_64-simulator/libferric_example.framework/libferric_example are: x86_64 arm64 @@ -438,5 +445,19 @@ jobs: Non-fat file: ferric_example.apple.node/xros-arm64/libferric_example.framework/libferric_example is architecture: arm64 EOF # Compare with expected fixture (will fail if files differ) - diff expected-lipo-info.txt lipo-info.txt + diff expected-lipo-output.txt lipo-output.txt + # Verify every binary depends on the weak-node-api framework. + # otool -L prints one header line per file, or one per architecture + # when the file is fat, so the number of headers is exactly the number + # of "@rpath/weak-node-api.framework/weak-node-api" lines we expect. + # Deriving it beats hard-coding a count, which silently rots whenever + # a triplet is added or dropped. + SLICE_COUNT=$(grep -c "^ferric_example\.apple\.node/.*:$" otool-output.txt || true) + WEAK_NODE_API_COUNT=$(grep -c "@rpath/weak-node-api\.framework/weak-node-api" otool-output.txt || true) + echo "Found $WEAK_NODE_API_COUNT weak-node-api dependencies across $SLICE_COUNT binaries" + if [ "$SLICE_COUNT" -eq 0 ] || [ "$WEAK_NODE_API_COUNT" -ne "$SLICE_COUNT" ]; then + echo "Expected $SLICE_COUNT occurrences of @rpath/weak-node-api.framework/weak-node-api (one per binary), found $WEAK_NODE_API_COUNT" + cat otool-output.txt + exit 1 + fi working-directory: packages/ferric-example From dbe62c8d75be584e6ecfebd6bbcb2890ccfe4fb4 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 12 Aug 2026 12:58:46 +0000 Subject: [PATCH 2/2] ci: accept the versioned weak-node-api install name on macOS The first CI run of this check reported 8 dependencies across 10 binary slices. The two misses were the macOS slices: macOS frameworks use the versioned bundle layout, so weak-node-api's install name there is @rpath/weak-node-api.framework/Versions/0.1.1/weak-node-api where iOS, tvOS and visionOS get the flat @rpath/weak-node-api.framework/weak-node-api Both are a genuine dependency on the framework, so match the optional "Versions//" component rather than only the flat form. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01SrPdjhQ6aG949mVDDaiT2U --- .github/workflows/check.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index b5b47e5e..3b6500f5 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -449,14 +449,19 @@ jobs: # Verify every binary depends on the weak-node-api framework. # otool -L prints one header line per file, or one per architecture # when the file is fat, so the number of headers is exactly the number - # of "@rpath/weak-node-api.framework/weak-node-api" lines we expect. - # Deriving it beats hard-coding a count, which silently rots whenever - # a triplet is added or dropped. + # of weak-node-api dependencies we expect. Deriving it beats + # hard-coding a count, which silently rots whenever a triplet is added + # or dropped. + # macOS frameworks use the versioned bundle layout, so their install + # name is .../weak-node-api.framework/Versions//weak-node-api + # where the embedded platforms get the flat + # .../weak-node-api.framework/weak-node-api — hence the optional + # "Versions//" in the pattern. SLICE_COUNT=$(grep -c "^ferric_example\.apple\.node/.*:$" otool-output.txt || true) - WEAK_NODE_API_COUNT=$(grep -c "@rpath/weak-node-api\.framework/weak-node-api" otool-output.txt || true) + WEAK_NODE_API_COUNT=$(grep -cE "@rpath/weak-node-api\.framework/(Versions/[^/]+/)?weak-node-api" otool-output.txt || true) echo "Found $WEAK_NODE_API_COUNT weak-node-api dependencies across $SLICE_COUNT binaries" if [ "$SLICE_COUNT" -eq 0 ] || [ "$WEAK_NODE_API_COUNT" -ne "$SLICE_COUNT" ]; then - echo "Expected $SLICE_COUNT occurrences of @rpath/weak-node-api.framework/weak-node-api (one per binary), found $WEAK_NODE_API_COUNT" + echo "Expected $SLICE_COUNT dependencies on the weak-node-api framework (one per binary), found $WEAK_NODE_API_COUNT" cat otool-output.txt exit 1 fi