Skip to content

fix(build): pin opendal linux ABI#1872

Merged
yyhhyyyyyy merged 2 commits into
devfrom
fix/opendal-linux-glibc-native-binding
Jul 3, 2026
Merged

fix(build): pin opendal linux ABI#1872
yyhhyyyyyy merged 2 commits into
devfrom
fix/opendal-linux-glibc-native-binding

Conversation

@yyhhyyyyyy

@yyhhyyyyyy yyhhyyyyyy commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

pin opendal linux ABI

Summary by CodeRabbit

  • New Features

    • Added Linux packaging support for OpenDAL native libraries, including the needed runtime files in packaged apps.
    • Added a new smoke check to verify OpenDAL native packaging during Linux builds and releases.
  • Bug Fixes

    • Improved Linux app packaging reliability by ensuring OpenDAL native dependencies are included in the unpacked app resources.
    • Updated dependency versions to keep OpenDAL and its native packages aligned.

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds OpenDAL native package smoke testing and packaging support: a new smoke-test CLI script, an afterPack.js routine to copy platform-specific OpenDAL native packages into unpacked Electron builds, pinned opendal dependency versions, updated sharp install platform config for Linux libc/wasm32, CI workflow verification steps, and corresponding test coverage.

Changes

OpenDAL Native Packaging and Verification

Layer / File(s) Summary
Dependency pinning and npm script
package.json
Pins opendal and @opendal/lib-* optional dependencies to 0.49.2 and adds a smoke:opendal:native script.
Smoke test script
scripts/smoke-opendal-native.js
New CLI tool that parses arguments, normalizes platform/arch, resolves and validates OpenDAL native package presence in node_modules (including pnpm layouts), and conditionally loads the native module.
afterPack native package copying
scripts/afterPack.js
Adds a platform/arch resolver for @opendal/lib-* package names and copyOpendalNativePackages to copy them into app.asar.unpacked/node_modules during packaging.
Sharp install libc support
scripts/install-sharp-for-platform.js
Adds wasm32 cpu and glibc libc entries for Linux platform configs and writes/logs supportedArchitectures.libc when set.
CI workflow smoke steps
.github/workflows/build.yml, .github/workflows/release.yml
Adds Linux steps running the OpenDAL smoke test before and after packaging, the latter pointing at unpacked resource directories.
Test coverage
test/main/build/electronBuilderConfig.test.ts, test/main/scripts/afterPack.test.ts, test/main/scripts/installSharpForPlatform.test.ts
Validates asarUnpack config and opendal version pinning, refactors afterPack tests with shared Darwin/Linux mock-package seeding helpers, and adds a new test for Linux libc/cpu expansion.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CI as CI Workflow
  participant Script as smoke-opendal-native.js
  participant FS as node_modules / resourcesPath
  participant Loader as maybeLoadOpendal

  CI->>Script: run smoke:opendal:native (--platform, --arch, --resources-path)
  Script->>FS: resolve OpenDAL native package dir
  FS-->>Script: package.json + main file
  Script->>Loader: assert main exists, conditionally require index.cjs
  Loader-->>Script: load result or skip (cross-platform)
  Script-->>CI: exit 0 (success) or exit 1 (failure)
Loading

Possibly related PRs

  • ThinkInAIXYZ/deepchat#511: Both PRs modify scripts/install-sharp-for-platform.js's logic for updating pnpm-workspace.yaml supportedArchitectures, including Linux CPU/libc handling.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and matches the main change: pinning OpenDAL for Linux packaging and ABI compatibility.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/opendal-linux-glibc-native-binding

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.

@yyhhyyyyyy yyhhyyyyyy merged commit 67b2843 into dev Jul 3, 2026
7 of 8 checks passed
@yyhhyyyyyy yyhhyyyyyy deleted the fix/opendal-linux-glibc-native-binding branch July 3, 2026 08:48

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
scripts/smoke-opendal-native.js (1)

131-143: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Hardcoded index.cjs bypasses package.json main resolution.

maybeLoadOpendal hardcodes index.cjs as the opendal entry point instead of resolving it via package.json's main field the way assertPackageMainExists does for the native package. This is accurate for the currently pinned opendal@0.49.2 (confirmed it ships index.cjs), but silently breaks the smoke check if a future version pin changes the entry filename, since there's no assertion tying this hardcoded path to the actual manifest.

♻️ Proposed fix to derive the entry from package.json
 function maybeLoadOpendal(opendalDir, platform, arch, label) {
   if (platform !== process.platform || arch !== process.arch) {
     console.log(
       `[OpenDAL Smoke] ${label}: target ${platform}/${arch} differs from host ${process.platform}/${process.arch}; verified file presence only.`
     )
     return
   }

-  const opendalEntry = path.join(opendalDir, 'index.cjs')
+  const opendalEntry = assertPackageMainExists(opendalDir, `${label} opendal`)
   const requireFromOpendal = createRequire(opendalEntry)
   requireFromOpendal(opendalEntry)
   console.log(`[OpenDAL Smoke] ${label}: loaded opendal from ${opendalEntry}`)
 }
🤖 Prompt for 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.

In `@scripts/smoke-opendal-native.js` around lines 131 - 143, The OpenDAL load
path in maybeLoadOpendal is hardcoded to index.cjs instead of using the package
manifest, which can drift from the actual entry point. Update maybeLoadOpendal
to resolve the entry from opendal’s package.json main field, similar to
assertPackageMainExists for the native package, and use that resolved entry with
createRequire/requireFromOpendal so the smoke test stays aligned with future
package changes.
scripts/afterPack.js (1)

204-231: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider logging when no OpenDAL package resolves for a recognized platform.

When getOpendalNativePackages returns [] for a platform/arch combo that isn't in the switch, the function silently no-ops (Line 208-210). If CI's build matrix later adds a target (e.g. Windows ia32 or a new arch enum value) without updating the switch, the packaged app would ship without the native OpenDAL binary and no build failure would surface it.

♻️ Optional: warn on unmapped platform/arch
   const packageNames = getOpendalNativePackages(electronPlatformName, arch)

   if (packageNames.length === 0) {
+    console.warn(
+      `No OpenDAL native package mapping for ${electronPlatformName}/${arch}; skipping native copy.`
+    )
     return
   }
🤖 Prompt for 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.

In `@scripts/afterPack.js` around lines 204 - 231, The copyOpendalNativePackages
flow currently returns silently when getOpendalNativePackages() yields no
packages, which can hide unmapped platform/arch combinations. Update
copyOpendalNativePackages (near the packageNames check) to emit a warning that
includes electronPlatformName and arch before returning, so missing OpenDAL
mappings are visible in CI without changing the existing no-op behavior.
test/main/scripts/afterPack.test.ts (1)

177-220: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding coverage for the darwin "universal" OpenDAL branch.

getOpendalNativePackages in scripts/afterPack.js has a distinct branch for platform === 'darwin' && archName === 'universal' that returns two packages (lib-darwin-x64 and lib-darwin-arm64). This parameterized test only covers arm64 (arch 3) and x64 (arch 1) individually; the universal/multi-package copy path isn't exercised here.

🤖 Prompt for 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.

In `@test/main/scripts/afterPack.test.ts` around lines 177 - 220, Add test
coverage in afterPack.test.ts for the darwin universal OpenDAL path in
getOpendalNativePackages. The current parameterized case only verifies arm64 and
x64 separately, so add a new scenario that uses archName "universal" and asserts
both OpenDAL native packages are copied into the unpacked node_modules by
afterPack. Reference the existing afterPack, seedDarwinNativePrerequisites, and
getOpendalNativePackages behavior so the new test clearly exercises the
multi-package branch.
🤖 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.

Nitpick comments:
In `@scripts/afterPack.js`:
- Around line 204-231: The copyOpendalNativePackages flow currently returns
silently when getOpendalNativePackages() yields no packages, which can hide
unmapped platform/arch combinations. Update copyOpendalNativePackages (near the
packageNames check) to emit a warning that includes electronPlatformName and
arch before returning, so missing OpenDAL mappings are visible in CI without
changing the existing no-op behavior.

In `@scripts/smoke-opendal-native.js`:
- Around line 131-143: The OpenDAL load path in maybeLoadOpendal is hardcoded to
index.cjs instead of using the package manifest, which can drift from the actual
entry point. Update maybeLoadOpendal to resolve the entry from opendal’s
package.json main field, similar to assertPackageMainExists for the native
package, and use that resolved entry with createRequire/requireFromOpendal so
the smoke test stays aligned with future package changes.

In `@test/main/scripts/afterPack.test.ts`:
- Around line 177-220: Add test coverage in afterPack.test.ts for the darwin
universal OpenDAL path in getOpendalNativePackages. The current parameterized
case only verifies arm64 and x64 separately, so add a new scenario that uses
archName "universal" and asserts both OpenDAL native packages are copied into
the unpacked node_modules by afterPack. Reference the existing afterPack,
seedDarwinNativePrerequisites, and getOpendalNativePackages behavior so the new
test clearly exercises the multi-package branch.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ee5c177c-68e9-4e60-8f0c-571d09ae43e9

📥 Commits

Reviewing files that changed from the base of the PR and between c82ee12 and 4099fd0.

📒 Files selected for processing (9)
  • .github/workflows/build.yml
  • .github/workflows/release.yml
  • package.json
  • scripts/afterPack.js
  • scripts/install-sharp-for-platform.js
  • scripts/smoke-opendal-native.js
  • test/main/build/electronBuilderConfig.test.ts
  • test/main/scripts/afterPack.test.ts
  • test/main/scripts/installSharpForPlatform.test.ts

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