diff --git a/.github/workflows/nightly-build.yml b/.github/workflows/nightly-build.yml index 2efeb0174..ce07892bc 100644 --- a/.github/workflows/nightly-build.yml +++ b/.github/workflows/nightly-build.yml @@ -94,7 +94,6 @@ jobs: if: matrix.os == 'ubuntu-latest' run: | sudo apt-get install -y rpm - yarn build:npm linux yarn build:linux env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -107,7 +106,6 @@ jobs: - name: Build Mac if: matrix.os == 'macos-latest' run: | - yarn build:npm mac yarn build:mac env: CSC_LINK: ${{ secrets.CSC_LINK }} @@ -125,7 +123,6 @@ jobs: - name: Build Windows if: matrix.os == 'windows-latest' run: | - yarn build:npm windows yarn build:win env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b59cccd50..7428aa031 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -80,7 +80,6 @@ jobs: if: matrix.os == 'ubuntu-latest' run: | sudo apt-get install -y rpm - yarn build:npm linux yarn build:linux env: @@ -95,7 +94,6 @@ jobs: if: matrix.os == 'macos-latest' run: | sudo -H pip install setuptools - yarn build:npm mac yarn build:mac env: CSC_LINK: ${{ secrets.CSC_LINK }} @@ -113,7 +111,6 @@ jobs: - name: Build Windows if: matrix.os == 'windows-latest' run: | - yarn build:npm windows yarn build:win env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/build/entitlements.mac.plist b/build/entitlements.mac.plist index 38c887b21..6bc22e913 100644 --- a/build/entitlements.mac.plist +++ b/build/entitlements.mac.plist @@ -8,5 +8,7 @@ com.apple.security.cs.allow-dyld-environment-variables + com.apple.security.cs.disable-library-validation + diff --git a/electron-builder.yml b/electron-builder.yml index e67ed2315..1f6dce36b 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -114,6 +114,7 @@ publish: url: https://releases.cherry-ai.com electronDownload: mirror: https://npmmirror.com/mirrors/electron/ +beforePack: scripts/before-pack.js afterPack: scripts/after-pack.js afterSign: scripts/notarize.js artifactBuildCompleted: scripts/artifact-build-completed.js diff --git a/package.json b/package.json index 694f88af9..35e85d175 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,6 @@ "build:linux": "dotenv npm run build && electron-builder --linux --x64 --arm64", "build:linux:arm64": "dotenv npm run build && electron-builder --linux --arm64", "build:linux:x64": "dotenv npm run build && electron-builder --linux --x64", - "build:npm": "node scripts/build-npm.js", "release": "node scripts/version.js", "publish": "yarn build:check && yarn release patch push", "pulish:artifacts": "cd packages/artifacts && npm publish && cd -", @@ -74,7 +73,6 @@ "@libsql/client": "0.14.0", "@libsql/win32-x64-msvc": "^0.4.7", "@napi-rs/system-ocr": "^1.0.2", - "@strongtz/win32-arm64-msvc": "^0.4.7", "graceful-fs": "^4.2.11", "jsdom": "26.1.0", "node-stream-zip": "^1.15.0", diff --git a/scripts/after-pack.js b/scripts/after-pack.js index 21bef1782..b8e4c8af1 100644 --- a/scripts/after-pack.js +++ b/scripts/after-pack.js @@ -1,104 +1,10 @@ -const { Arch } = require('electron-builder') const fs = require('fs') const path = require('path') exports.default = async function (context) { const platform = context.packager.platform.name - const arch = context.arch - - if (platform === 'mac') { - const node_modules_path = path.join( - context.appOutDir, - 'Cherry Studio.app', - 'Contents', - 'Resources', - 'app.asar.unpacked', - 'node_modules' - ) - - keepPackageNodeFiles(node_modules_path, '@libsql', arch === Arch.arm64 ? ['darwin-arm64'] : ['darwin-x64']) - - keepPackageNodeFiles( - node_modules_path, - '@img', - arch === Arch.arm64 - ? ['sharp-darwin-arm64', 'sharp-libvips-darwin-arm64'] - : ['sharp-darwin-x64', 'sharp-libvips-darwin-x64'] - ) - - keepPackageNodeFiles( - node_modules_path, - '@napi-rs', - arch === Arch.arm64 ? ['system-ocr-darwin-arm64'] : ['system-ocr-darwin-x64'] - ) - } - - if (platform === 'linux') { - const node_modules_path = path.join(context.appOutDir, 'resources', 'app.asar.unpacked', 'node_modules') - const _arch = arch === Arch.arm64 ? ['linux-arm64-gnu', 'linux-arm64-musl'] : ['linux-x64-gnu', 'linux-x64-musl'] - keepPackageNodeFiles(node_modules_path, '@libsql', _arch) - - keepPackageNodeFiles( - node_modules_path, - '@img', - arch === Arch.arm64 - ? ['sharp-libvips-linux-arm64', 'sharp-linux-arm64'] - : ['sharp-libvips-linux-x64', 'sharp-linux-x64'] - ) - } - - if (platform === 'windows') { - const node_modules_path = path.join(context.appOutDir, 'resources', 'app.asar.unpacked', 'node_modules') - if (arch === Arch.arm64) { - keepPackageNodeFiles(node_modules_path, '@strongtz', ['win32-arm64-msvc']) - keepPackageNodeFiles(node_modules_path, '@libsql', ['win32-arm64-msvc']) - } - if (arch === Arch.x64) { - keepPackageNodeFiles(node_modules_path, '@strongtz', ['win32-x64-msvc']) - keepPackageNodeFiles(node_modules_path, '@libsql', ['win32-x64-msvc']) - } - - keepPackageNodeFiles( - node_modules_path, - '@img', - arch === Arch.arm64 - ? ['sharp-win32-arm64', 'sharp-libvips-win32-arm64'] - : ['sharp-win32-x64', 'sharp-libvips-win32-x64'] - ) - - keepPackageNodeFiles( - node_modules_path, - '@napi-rs', - arch === Arch.arm64 ? ['system-ocr-win32-arm64-msvc'] : ['system-ocr-win32-x64-msvc'] - ) - } - if (platform === 'windows') { fs.rmSync(path.join(context.appOutDir, 'LICENSE.electron.txt'), { force: true }) fs.rmSync(path.join(context.appOutDir, 'LICENSES.chromium.html'), { force: true }) } } - -/** - * 使用指定架构的 node_modules 文件 - * @param {*} nodeModulesPath - * @param {*} packageName - * @param {*} arch - * @returns - */ -function keepPackageNodeFiles(nodeModulesPath, packageName, arch) { - const modulePath = path.join(nodeModulesPath, packageName) - - if (!fs.existsSync(modulePath)) { - console.log(`[After Pack] Directory does not exist: ${modulePath}`) - return - } - - const dirs = fs.readdirSync(modulePath) - dirs - .filter((dir) => !arch.includes(dir)) - .forEach((dir) => { - fs.rmSync(path.join(modulePath, dir), { recursive: true, force: true }) - console.log(`[After Pack] Removed dir: ${dir}`, arch) - }) -} diff --git a/scripts/before-pack.js b/scripts/before-pack.js new file mode 100644 index 000000000..f0d4bdb09 --- /dev/null +++ b/scripts/before-pack.js @@ -0,0 +1,97 @@ +const { Arch } = require('electron-builder') +const { downloadNpmPackage } = require('./utils') + +// if you want to add new prebuild binaries packages with different architectures, you can add them here +// please add to allX64 and allArm64 from yarn.lock +const allArm64 = { + '@img/sharp-darwin-arm64': '0.34.3', + '@img/sharp-win32-arm64': '0.34.3', + '@img/sharp-linux-arm64': '0.34.3', + '@img/sharp-linuxmusl-arm64': '0.34.3', + + '@img/sharp-libvips-darwin-arm64': '1.2.0', + '@img/sharp-libvips-linux-arm64': '1.2.0', + '@img/sharp-libvips-linuxmusl-arm64': '1.2.0', + + '@libsql/darwin-arm64': '0.4.7', + '@libsql/linux-arm64-gnu': '0.4.7', + '@libsql/linux-arm64-musl': '0.4.7', + '@strongtz/win32-arm64-msvc': '0.4.7', + + '@napi-rs/system-ocr-darwin-arm64': '1.0.2', + '@napi-rs/system-ocr-win32-arm64-msvc': '1.0.2' +} + +const allX64 = { + '@img/sharp-darwin-x64': '0.34.3', + '@img/sharp-linux-x64': '0.34.3', + '@img/sharp-linuxmusl-x64': '0.34.3', + '@img/sharp-win32-x64': '0.34.3', + + '@img/sharp-libvips-darwin-x64': '1.2.0', + '@img/sharp-libvips-linux-x64': '1.2.0', + '@img/sharp-libvips-linuxmusl-x64': '1.2.0', + + '@libsql/darwin-x64': '0.4.7', + '@libsql/linux-x64-gnu': '0.4.7', + '@libsql/linux-x64-musl': '0.4.7', + '@libsql/win32-x64-msvc': '0.4.7', + + '@napi-rs/system-ocr-darwin-x64': '1.0.2', + '@napi-rs/system-ocr-win32-x64-msvc': '1.0.2' +} + +const platformToArch = { + mac: 'darwin', + windows: 'win32', + linux: 'linux' +} + +exports.default = async function (context) { + const arch = context.arch + const archType = arch === Arch.arm64 ? 'arm64' : 'x64' + const platform = context.packager.platform.name + + const arm64Filters = Object.keys(allArm64).map((f) => '!node_modules/' + f + '/**') + const x64Filters = Object.keys(allX64).map((f) => '!node_modules/' + f + '/*') + + const downloadPackages = async (packages) => { + console.log('downloading packages ......') + const downloadPromises = [] + + for (const name of Object.keys(packages)) { + if (name.includes(`${platformToArch[platform]}`) && name.includes(`-${archType}`)) { + downloadPromises.push( + downloadNpmPackage( + name, + `https://registry.npmjs.org/${name}/-/${name.split('/').pop()}-${packages[name]}.tgz` + ) + ) + } + } + + await Promise.all(downloadPromises) + } + + const changeFilters = async (packages, filtersToExclude, filtersToInclude) => { + await downloadPackages(packages) + // remove filters for the target architecture (allow inclusion) + + let filters = context.packager.config.files[0].filter + filters = filters.filter((filter) => !filtersToInclude.includes(filter)) + // add filters for other architectures (exclude them) + filters.push(...filtersToExclude) + + context.packager.config.files[0].filter = filters + } + + if (arch === Arch.arm64) { + await changeFilters(allArm64, x64Filters, arm64Filters) + return + } + + if (arch === Arch.x64) { + await changeFilters(allX64, arm64Filters, x64Filters) + return + } +} diff --git a/scripts/build-npm.js b/scripts/build-npm.js deleted file mode 100644 index c3a63d522..000000000 --- a/scripts/build-npm.js +++ /dev/null @@ -1,105 +0,0 @@ -const { downloadNpmPackage } = require('./utils') - -async function downloadNpm(platform) { - if (!platform || platform === 'mac') { - downloadNpmPackage( - '@libsql/darwin-arm64', - 'https://registry.npmjs.org/@libsql/darwin-arm64/-/darwin-arm64-0.4.7.tgz' - ) - downloadNpmPackage('@libsql/darwin-x64', 'https://registry.npmjs.org/@libsql/darwin-x64/-/darwin-x64-0.4.7.tgz') - - // sharp for macOS - downloadNpmPackage( - '@img/sharp-darwin-arm64', - 'https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.3.tgz' - ) - downloadNpmPackage( - '@img/sharp-darwin-x64', - 'https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.3.tgz' - ) - downloadNpmPackage( - '@img/sharp-libvips-darwin-arm64', - 'https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.0.tgz' - ) - downloadNpmPackage( - '@img/sharp-libvips-darwin-x64', - 'https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.0.tgz' - ) - downloadNpmPackage( - '@napi-rs/system-ocr-darwin-arm64', - 'https://registry.npmjs.org/@napi-rs/system-ocr-darwin-arm64/-/system-ocr-darwin-arm64-1.0.2.tgz' - ) - downloadNpmPackage( - '@napi-rs/system-ocr-darwin-x64', - 'https://registry.npmjs.org/@napi-rs/system-ocr-darwin-x64/-/system-ocr-darwin-x64-1.0.2.tgz' - ) - } - - if (!platform || platform === 'linux') { - downloadNpmPackage( - '@libsql/linux-arm64-gnu', - 'https://registry.npmjs.org/@libsql/linux-arm64-gnu/-/linux-arm64-gnu-0.4.7.tgz' - ) - downloadNpmPackage( - '@libsql/linux-arm64-musl', - 'https://registry.npmjs.org/@libsql/linux-arm64-musl/-/linux-arm64-musl-0.4.7.tgz' - ) - downloadNpmPackage( - '@libsql/linux-x64-gnu', - 'https://registry.npmjs.org/@libsql/linux-x64-gnu/-/linux-x64-gnu-0.4.7.tgz' - ) - downloadNpmPackage( - '@libsql/linux-x64-musl', - 'https://registry.npmjs.org/@libsql/linux-x64-musl/-/linux-x64-musl-0.4.7.tgz' - ) - - downloadNpmPackage( - '@img/sharp-libvips-linux-arm64', - 'https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.0.tgz' - ) - downloadNpmPackage( - '@img/sharp-libvips-linux-x64', - 'https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.0.tgz' - ) - downloadNpmPackage( - '@img/sharp-libvips-linuxmusl-arm64', - 'https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.0.tgz' - ) - downloadNpmPackage( - '@img/sharp-libvips-linuxmusl-x64', - 'https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.0.tgz' - ) - } - - if (!platform || platform === 'windows') { - downloadNpmPackage( - '@libsql/win32-x64-msvc', - 'https://registry.npmjs.org/@libsql/win32-x64-msvc/-/win32-x64-msvc-0.4.7.tgz' - ) - downloadNpmPackage( - '@strongtz/win32-arm64-msvc', - 'https://registry.npmjs.org/@strongtz/win32-arm64-msvc/-/win32-arm64-msvc-0.4.7.tgz' - ) - - downloadNpmPackage( - '@img/sharp-win32-arm64', - 'https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.3.tgz' - ) - downloadNpmPackage( - '@img/sharp-win32-x64', - 'https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.3.tgz' - ) - - downloadNpmPackage( - '@napi-rs/system-ocr-win32-arm64-msvc', - 'https://registry.npmjs.org/@napi-rs/system-ocr-win32-arm64-msvc/-/system-ocr-win32-arm64-msvc-1.0.2.tgz' - ) - downloadNpmPackage( - '@napi-rs/system-ocr-win32-x64-msvc', - 'https://registry.npmjs.org/@napi-rs/system-ocr-win32-x64-msvc/-/system-ocr-win32-x64-msvc-1.0.2.tgz' - ) - } -} - -const platformArg = process.argv[2] -downloadNpm(platformArg) diff --git a/scripts/utils.js b/scripts/utils.js index 6cb5b35c3..cafa07b68 100644 --- a/scripts/utils.js +++ b/scripts/utils.js @@ -1,12 +1,15 @@ const fs = require('fs') const path = require('path') const os = require('os') +const zlib = require('zlib') +const tar = require('tar') +const { pipeline } = require('stream/promises') -function downloadNpmPackage(packageName, url) { +async function downloadNpmPackage(packageName, url) { const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'npm-download-')) - const targetDir = path.join('./node_modules/', packageName) - const filename = packageName.replace('/', '-') + '.tgz' + const filename = path.join(tempDir, packageName.replace('/', '-') + '.tgz') + const extractDir = path.join(tempDir, 'extract') // Skip if directory already exists if (fs.existsSync(targetDir)) { @@ -16,23 +19,44 @@ function downloadNpmPackage(packageName, url) { try { console.log(`Downloading ${packageName}...`, url) - const { execSync } = require('child_process') - execSync(`curl --fail -o ${filename} ${url}`) + + // Download file using fetch API + const response = await fetch(url) + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`) + } + + const fileStream = fs.createWriteStream(filename) + await pipeline(response.body, fileStream) console.log(`Extracting ${filename}...`) - execSync(`tar -xvf ${filename}`) - execSync(`rm -rf ${filename}`) - execSync(`mkdir -p ${targetDir}`) - execSync(`mv package/* ${targetDir}/`) + + // Create extraction directory + fs.mkdirSync(extractDir, { recursive: true }) + + // Extract tar.gz file using Node.js streams + await pipeline(fs.createReadStream(filename), zlib.createGunzip(), tar.extract({ cwd: extractDir })) + + // Remove the downloaded file + fs.rmSync(filename, { force: true }) + + // Create target directory + fs.mkdirSync(targetDir, { recursive: true }) + + // Move extracted package contents to target directory + const packageDir = path.join(extractDir, 'package') + if (fs.existsSync(packageDir)) { + fs.cpSync(packageDir, targetDir, { recursive: true }) + } } catch (error) { console.error(`Error processing ${packageName}: ${error.message}`) - if (fs.existsSync(filename)) { - fs.unlinkSync(filename) - } throw error + } finally { + // Clean up temp directory + if (fs.existsSync(tempDir)) { + fs.rmSync(tempDir, { recursive: true, force: true }) + } } - - fs.rmSync(tempDir, { recursive: true, force: true }) } module.exports = { diff --git a/yarn.lock b/yarn.lock index 96f37725a..dc40f695a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7034,14 +7034,6 @@ __metadata: languageName: node linkType: hard -"@strongtz/win32-arm64-msvc@npm:^0.4.7": - version: 0.4.7 - resolution: "@strongtz/win32-arm64-msvc@npm:0.4.7" - checksum: 10c0/21946f2ed43ff0b2381f945e22cf7f5ef6de412347c36523ed1d72f33591b2b85bf4cc9dd493f0eab95ed5e152d3944a2329791c3d8ed88c7ad450ccd9078015 - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - "@swc/core-darwin-arm64@npm:1.11.21": version: 1.11.21 resolution: "@swc/core-darwin-arm64@npm:1.11.21" @@ -9417,7 +9409,6 @@ __metadata: "@playwright/test": "npm:^1.52.0" "@reduxjs/toolkit": "npm:^2.2.5" "@shikijs/markdown-it": "npm:^3.12.0" - "@strongtz/win32-arm64-msvc": "npm:^0.4.7" "@swc/plugin-styled-components": "npm:^7.1.5" "@tanstack/react-query": "npm:^5.85.5" "@tanstack/react-virtual": "npm:^3.13.12"