Conversation
Build artifacts for all platforms are ready! 🚀Download the artifacts from: (execution 17686709336 / attempt 1) |
WalkthroughAdds a macOS-only step in afterPack to copy Assets.car before VMP signing (new helper in build/hooks/components/macos.js). electron-builder.json gains mac.extendInfo with CFBundleIconName "AppIcon". Also removes macOS ("darwin") from supportedPlatforms in src/main/modules/icons.ts, disabling mac icon updates. No public API changes. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Dev as Build Process
participant EB as electron-builder
participant AP as afterPack Hook
participant MC as copyAssetsCar
participant Sign as VMP Sign
participant Notarize as Notarization
Dev->>EB: Package app
EB->>AP: afterPack(context)
alt platform == darwin
AP->>MC: copyAssetsCar(appOutDir)
MC-->>AP: resolve / reject (caught -> non-fatal)
end
AP->>Sign: perform VMP signing (macOS)
Sign-->>AP: signed artifacts
AP->>Notarize: notarize (if configured)
Notarize-->>AP: result
AP-->>EB: done
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
build/hooks/afterPack.js(2 hunks)build/hooks/components/macos.js(1 hunks)electron-builder.json(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
**/*.{js,jsx,ts,tsx}: Usebun <file>instead ofnode <file>orts-node <file>
Bun automatically loads .env, so don't use dotenv.
UseBun.serve()for HTTP servers and WebSockets instead ofexpress.
Usebun:sqlitefor SQLite instead ofbetter-sqlite3.
UseBun.redisfor Redis instead ofioredis.
UseBun.sqlfor Postgres instead ofpgorpostgres.js.
Use built-inWebSocketinstead ofws.
PreferBun.fileovernode:fs's readFile/writeFile.
UseBun.$for shell commands instead of execa.
Files:
build/hooks/components/macos.jsbuild/hooks/afterPack.js
**/*.{js,jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
Import .css files directly in .tsx, .jsx, or .js files and it works with Bun.
Files:
build/hooks/components/macos.jsbuild/hooks/afterPack.js
🧬 Code graph analysis (2)
electron-builder.json (1)
src/main/modules/icons.ts (2)
updateAppIcon(160-179)setAppIcon(181-209)
build/hooks/afterPack.js (1)
build/hooks/components/macos.js (1)
copyAssetsCar(6-37)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: build (macos-latest)
- GitHub Check: build (windows-latest)
- GitHub Check: build (macos-13)
- GitHub Check: build (ubuntu-24.04-arm)
- GitHub Check: build (ubuntu-latest)
🔇 Additional comments (3)
electron-builder.json (1)
75-78: Icon configuration verified and correctly wiredAll checks have passed for the macOS icon setup:
- Assets.car is present at
build/Assets.carCFBundleIconNameis set to"AppIcon"inelectron-builder.json- No conflicting
mac.iconorCFBundleIconFileentries exist- The
afterPackhook ("./build/hooks/afterPack.js") is configured to include the asset before signingOptional: if you’d rather avoid the hook and ensure
Assets.caris always bundled pre-signing, you can add at the top level of your config:"extraResources": [ { "from": "build/Assets.car", "to": "Resources/Assets.car" } ]build/hooks/afterPack.js (2)
3-3: Import looks correct; ordering is appropriateImporting copyAssetsCar before use is fine, and placing the copy step before VMP signing is the right sequencing so the new resource is included in the code-signed envelope.
13-18: afterPack Hook: Simplify async flow and confirm Node.js runtimeTo keep your Electron‐Builder hooks running smoothly under Node.js (Electron-Builder hooks run in Node.js ≥8.11.x by design (electron.build)) and eliminate the unused Promise chaining, please update
build/hooks/afterPack.jsas follows:
- Replace the
await … .then().catch()pattern with atry/catcharound the awaited call.- (Optional) If you’d like to handle success/failure explicitly via a boolean return from
copyAssetsCar, assign the result and log accordingly.Essential refactor (no behavioral change; failures remain non-fatal):
- // macOS needs to add the Assets.car containing the Liquid Glass icon - if (process.platform === "darwin") { - await copyAssetsCar(context.appOutDir) - .then(() => true) - .catch(() => false); - } + // macOS needs to add the Assets.car containing the Liquid Glass icon + if (process.platform === "darwin") { + try { + await copyAssetsCar(context.appOutDir); + } catch (err) { + console.warn("Assets.car copy failed, continuing:", err?.message ?? err); + } + }Optional boolean-return refactor:
- try { - await copyAssetsCar(context.appOutDir); - } catch (err) { - console.warn("Assets.car copy failed, continuing:", err?.message ?? err); - } + const ok = await copyAssetsCar(context.appOutDir); + if (!ok) { + console.warn("Assets.car was not copied; continuing without liquid glass icon."); + }Note:
process.platformis a built-in Node.js property ("darwin"for macOS) (nodejs.cn) and should not be replaced with Bun APIs, as Electron-Builder invokes hooks via Node.js.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/main/modules/icons.ts (2)
112-147: Avoid sync I/O; let sharp read from path directly.Removes a blocking read and reduces memory churn.
- // Read the image file - const inputBuffer = fs.readFileSync(imagePath); @@ - const outputBuffer = await sharp(inputBuffer) + const outputBuffer = await sharp(imagePath) .resize(artSize, artSize)
184-205: Narrow API surface: type iconId as IconId.Prevents accidental calls with arbitrary strings and keeps callers aligned with the allowlist.
-export async function setAppIcon(iconId: string) { +export async function setAppIcon(iconId: IconId) {
♻️ Duplicate comments (5)
build/hooks/components/macos.js (5)
1-2: Use node: specifiers for built-ins.Switch to node: imports for clarity and bundler friendliness.
-import path from "path"; -import fs from "fs/promises"; +import path from "node:path"; +import fs from "node:fs/promises";
4-5: Return a boolean instead of throwing; let caller decide tolerance.Aligns with the afterPack usage and keeps pack logs cleaner.
-/** @type {(appOutDir: string) => Promise<void>} */ +/** @type {(appOutDir: string) => Promise<boolean>} */ export async function copyAssetsCar(appOutDir) {
11-19: Resolve .app when appOutDir is already the bundle or contains it.Handle both shapes electron-builder can pass.
- // Get the path to the app by finding the first directory that ends with `.app` - const appContents = await fs.readdir(appOutDir); - const appName = appContents.find((item) => item.endsWith(".app")); - if (!appName) { - console.log("No .app directory found in appOutDir, skipping Assets.car copy"); - return; - } - const appPath = path.join(appOutDir, appName); + // Resolve the .app bundle whether appOutDir IS the .app or CONTAINS the .app + let appPath = appOutDir; + if (!appPath.endsWith(".app")) { + const entries = await fs.readdir(appOutDir, { withFileTypes: true }); + const appDir = entries.find((e) => e.isDirectory() && e.name.endsWith(".app"))?.name; + if (!appDir) { + console.log("No .app directory found in appOutDir, skipping Assets.car copy"); + return false; + } + appPath = path.join(appOutDir, appDir); + }
20-27: Fail fast if source missing (and ensure target dir exists).Prevents noisy copy errors and clarifies why the copy was skipped.
// Craft the source and target paths const sourcePath = path.join(dirname, "build", "Assets.car"); const targetPath = path.join(appPath, "Contents", "Resources", "Assets.car"); // Log for debugging console.log(`Source path: ${sourcePath}`); console.log(`Target path: ${targetPath}`); + + // Ensure source exists + try { + await fs.access(sourcePath); + } catch { + console.warn(`Assets.car not found at ${sourcePath}; skipping copy.`); + return false; + } + // Ensure target directory exists + await fs.mkdir(path.dirname(targetPath), { recursive: true });
28-36: Don’t throw on copy failure; return false.Keeps afterPack flow resilient and logs remain actionable.
- // Copy the file from the source to the target - try { - await fs.copyFile(sourcePath, targetPath); - console.log(`Successfully copied Assets.car to ${targetPath}`); - } catch (error) { - console.error(`Failed to copy Assets.car: ${error.message}`); - throw error; - } + // Copy the file from the source to the target + try { + await fs.copyFile(sourcePath, targetPath); + console.log(`Successfully copied Assets.car to ${targetPath}`); + return true; + } catch (error) { + console.error(`Failed to copy Assets.car: ${error instanceof Error ? error.message : String(error)}`); + return false; + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
build/hooks/components/macos.js(1 hunks)src/main/modules/icons.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
**/*.{js,jsx,ts,tsx}: Usebun <file>instead ofnode <file>orts-node <file>
Bun automatically loads .env, so don't use dotenv.
UseBun.serve()for HTTP servers and WebSockets instead ofexpress.
Usebun:sqlitefor SQLite instead ofbetter-sqlite3.
UseBun.redisfor Redis instead ofioredis.
UseBun.sqlfor Postgres instead ofpgorpostgres.js.
Use built-inWebSocketinstead ofws.
PreferBun.fileovernode:fs's readFile/writeFile.
UseBun.$for shell commands instead of execa.
Files:
build/hooks/components/macos.jssrc/main/modules/icons.ts
**/*.{js,jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
Import .css files directly in .tsx, .jsx, or .js files and it works with Bun.
Files:
build/hooks/components/macos.js
**/*.{html,ts,css}
📄 CodeRabbit inference engine (.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc)
Use
bun build <file.html|file.ts|file.css>instead ofwebpackoresbuild
Files:
src/main/modules/icons.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: build (windows-latest)
- GitHub Check: build (macos-latest)
- GitHub Check: build (ubuntu-24.04-arm)
- GitHub Check: build (ubuntu-latest)
- GitHub Check: build (macos-13)
🔇 Additional comments (1)
src/main/modules/icons.ts (1)
193-197: Icons feature correctly gated on unsupported platforms — no action required.IPC, preload, and renderer checks are present: the IPC handler "icons:is-platform-supported" returns supportedPlatforms.includes(process.platform), preload exposes isPlatformSupported()/setCurrentIcon() (which relay IPC results), the renderer settings and onboarding components call isPlatformSupported() to hide/abort the UI, and setCurrentIconId returns false when the platform is unsupported.
Confirmed locations: src/main/modules/icons.ts (platform check / setCurrentIconId), src/main/ipc/app/icons.ts (IPC handlers), src/preload/index.ts (iconsAPI), src/renderer/src/components/settings/sections/icon/section.tsx, src/renderer/src/components/onboarding/stages/icon.tsx.
Note: This will cause the existing custom icons system to break, and will replace the old icons.
Summary by CodeRabbit
Bug Fixes
Chores