Skip to content

Fail the macOS build if any bundled library links outside the bundle#10135

Merged
asheshv merged 3 commits into
pgadmin-org:masterfrom
dpage:macos-verify-bundle-linkage
Jul 24, 2026
Merged

Fail the macOS build if any bundled library links outside the bundle#10135
asheshv merged 3 commits into
pgadmin-org:masterfrom
dpage:macos-verify-bundle-linkage

Conversation

@dpage

@dpage dpage commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Belt-and-braces guard for the macOS appbundle build.

Background

9.16 failed to start on Intel Macs (#10123). The cryptography package no longer publishes a prebuilt wheel for Intel macOS, so pip compiled it from source on the builder, and its openssl-sys build linked the build host's Homebrew OpenSSL (/usr/local/opt/openssl@3/...) into _rust.abi3.so rather than the OpenSSL we ship inside the bundle. _fixup_imports deliberately skips _rust.abi3.so, so that dangling reference shipped unnoticed and the app died on startup on every machine that lacked (or could not validate) that external dylib.

The actual fix lives in the build configuration (force cryptography to link the bundled OpenSSL). This PR is the separate safety net so the same class of problem cannot silently reach a release again.

Change

Adds a _verify_bundle_linkage step, run after the bundle is fully assembled and relocated and before code-signing, that walks every .so/.dylib in the bundle and fails the build if any install-name points at a build-host prefix (/usr/local, /opt/homebrew, /opt/local, or $SLAVE_HOME on the CI builders). Legitimate OS libraries (/usr/lib, /System) and bundle-relative references (@loader_path/@rpath/@executable_path) pass untouched.

A correct, self-contained bundle passes silently; a left-behind external reference turns into a hard build failure on the builder instead of a runtime failure on a user's Mac.

Testing

macOS build scripts only; no runtime code paths affected. bash -n clean on both files, and the detection pipeline was checked against the real otool -L output from the #10123 reports (flags the two openssl@3 lines, ignores the @rpath self-id and the /usr/lib system libs).

Summary by CodeRabbit

  • Bug Fixes
    • Added an additional macOS app packaging validation to detect unsupported library references in the final app bundle.
    • The build now fails with a clear error if the bundle links to libraries from common host installation locations.
    • Helps prevent releases from accidentally depending on local build-machine libraries and improves bundle reliability.

The macOS appbundle is meant to be self-contained: every binary should
reference only OS libraries (/usr/lib, /System) or bundle-relative paths
(@loader_path/@rpath/@executable_path). An absolute install-name pointing
at a build-host location such as Homebrew's /usr/local/opt/openssl@3 or the
Jenkins workspace will resolve on the build machine but is absent (or, for a
differently-signed dylib, rejected by hardened-runtime library validation)
on an end user's Mac, so the app dies on startup.

This is exactly how 9.16 broke on Intel (issue pgadmin-org#10123): with no Intel
cryptography wheel published upstream, pip compiled it from source and its
openssl-sys build linked the build host's Homebrew OpenSSL into
_rust.abi3.so, which _fixup_imports deliberately skips, so the dangling
reference shipped unnoticed.

Add a _verify_bundle_linkage step that runs after the bundle is fully
assembled and relocated, and before code-signing, walking every .so/.dylib
and failing the build if anything links to a build-host prefix. This turns
the whole class of problem from a silent runtime failure on user machines
into a hard build failure on the builder.
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: de602533-29be-452d-8cd8-81b7f44c9ef8

📥 Commits

Reviewing files that changed from the base of the PR and between 6eea4e1 and 3e03e10.

📒 Files selected for processing (1)
  • pkg/mac/build-functions.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/mac/build-functions.sh

Walkthrough

Adds _verify_bundle_linkage to scan app-bundle Mach-O dependencies for forbidden build-host library paths and fail the macOS build when found. The verification runs after dangling-symlink pruning and before SBOM generation.

Changes

Bundle Linkage Verification

Layer / File(s) Summary
_verify_bundle_linkage implementation and build wiring
pkg/mac/build-functions.sh, pkg/mac/build.sh
Scans .so/.dylib dependencies via otool -L for disallowed host prefixes and aborts on matches; runs after symlink pruning and before SBOM generation.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main change: failing macOS builds when bundled libraries link outside the bundle.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/mac/build-functions.sh`:
- Around line 498-508: The Mach-O dependency scan in the bundle check is too
narrow because the loop only inspects files matched by the .so and .dylib
suffixes, so shipped executables and framework binaries can be missed. Update
the file discovery in the build-functions.sh scan to target all Mach-O files
under BUNDLE_DIR, then keep the existing otool -L, grep, and error reporting
logic in the same loop so any host-linked binary is caught regardless of
extension.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e48e57f7-c8e9-440b-bd04-fe6b4372a21a

📥 Commits

Reviewing files that changed from the base of the PR and between dfc4ef3 and 6eea4e1.

📒 Files selected for processing (2)
  • pkg/mac/build-functions.sh
  • pkg/mac/build.sh

Comment thread pkg/mac/build-functions.sh
Comment thread pkg/mac/build-functions.sh
@asheshv
asheshv merged commit 1884356 into pgadmin-org:master Jul 24, 2026
34 checks passed
asheshv added a commit that referenced this pull request Jul 24, 2026
…#10189)

_verify_bundle_linkage's host-library scan only matched files by
.so/.dylib name suffix, so a shipped executable (Contents/MacOS/*)
or a Python.framework payload with a host-linked dependency but no
matching suffix could slip through unchecked — the same class of
bug #10135 was added to catch.

Detect Mach-O executables/libraries by content via `file` instead
(same pattern the codesign step in this file already uses),
regardless of extension or executable permission bits, so readable
non-executable dylibs are covered too.
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