From 1012337e5784ed3f199e36653523c9cb9809ecf4 Mon Sep 17 00:00:00 2001 From: lafay <2021211506@stu.hit.edu.cn> Date: Mon, 15 Jun 2026 22:58:48 +0800 Subject: [PATCH] build(deps): add Jiguang SDK repositories and CMake job limit plugin Add Jiguang Maven repository (developer.jiguang.cn) to dependency resolution management for JPush SDK integration. Integrate new Expo config plugins for CMake job limiting and JCore patching. - Add jiguang maven repo to dependencyResolutionManagement and all buildscript repositories - Create withCmakeJobLimit plugin to set cmake job limits in gradle properties - Create withJcorePatch plugin for JCore SDK configuration - Increase CMAKE_BUILD_PARALLEL_LEVEL from 4 to 8 for faster native builds - Add gradle HTTP timeout settings (30s connection/socket timeout) - Remove npmmirror registry from npmrc and CI workflows (use default npm registry) - Downgrade upload-artifact action from v4 to v3 for compatibility - Remove docker layer caching for frontend-web build --- .gitea/workflows/build.yml | 26 ++++++++++++---- .npmrc | 4 --- app.json | 2 ++ plugins/withCmakeJobLimit.js | 60 ++++++++++++++++++++++++++++++++++++ plugins/withHuaweiPush.js | 32 +++++++++++++++++++ plugins/withJcorePatch.js | 43 ++++++++++++++++++++++++++ 6 files changed, 157 insertions(+), 10 deletions(-) create mode 100644 plugins/withCmakeJobLimit.js create mode 100644 plugins/withJcorePatch.js diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index 73fa9af..a07a49a 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -41,7 +41,6 @@ jobs: uses: actions/setup-node@v4 with: node-version: '25.6.1' - registry-url: 'https://registry.npmmirror.com' cache: 'npm' - name: Install dependencies @@ -106,7 +105,7 @@ jobs: NODE_OPTIONS: "--max-old-space-size=8192" NODE_ENV: "production" NDK_NUM_JOBS: "4" - CMAKE_BUILD_PARALLEL_LEVEL: "4" + CMAKE_BUILD_PARALLEL_LEVEL: "8" GRADLE_USER_HOME: /root/.gradle permissions: contents: read @@ -124,7 +123,6 @@ jobs: uses: actions/setup-node@v4 with: node-version: '25.6.1' - registry-url: 'https://registry.npmmirror.com' cache: 'npm' - name: Install dependencies @@ -188,6 +186,7 @@ jobs: maven { url 'https://maven.aliyun.com/repository/public' } maven { url 'https://maven.aliyun.com/repository/central' } maven { url 'https://developer.huawei.com/repo/' } + maven { url 'https://developer.jiguang.cn/maven' } google() mavenCentral() gradlePluginPortal() @@ -210,6 +209,20 @@ jobs: includeBuild(expoPluginsPath) } + dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) + repositories { + maven { url 'https://maven.aliyun.com/repository/google' } + maven { url 'https://maven.aliyun.com/repository/public' } + maven { url 'https://maven.aliyun.com/repository/central' } + maven { url 'https://developer.huawei.com/repo/' } + maven { url 'https://developer.jiguang.cn/maven' } + maven { url 'https://www.jitpack.io' } + google() + mavenCentral() + } + } + plugins { id("com.facebook.react.settings") id("expo-autolinking-settings") @@ -265,6 +278,7 @@ jobs: maven { url 'https://maven.aliyun.com/repository/central' } maven { url 'https://www.jitpack.io' } maven { url 'https://developer.huawei.com/repo/' } + maven { url 'https://developer.jiguang.cn/maven' } google() mavenCentral() } @@ -292,6 +306,8 @@ jobs: expo.webp.animated=false ndkVersion=27.1.12297006 expo.useLegacyPackaging=false + systemProp.org.gradle.internal.http.connectionTimeout=30000 + systemProp.org.gradle.internal.http.socketTimeout=30000 PROPS_EOF # Append signing properties (secrets appended, not cached) @@ -313,7 +329,7 @@ jobs: ./gradlew :app:assembleRelease -PreactNativeArchitectures=arm64-v8a --max-workers=4 --parallel - name: Upload APK artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v3 with: name: withyou-android-release-apk path: android/app/build/outputs/apk/release/app-release.apk @@ -396,8 +412,6 @@ jobs: labels: ${{ steps.meta.outputs.labels }} platforms: linux/amd64 provenance: false - cache-from: type=registry,ref=code.littlelan.cn/carrot_bbs/frontend-web:buildcache - cache-to: type=registry,ref=code.littlelan.cn/carrot_bbs/frontend-web:buildcache,mode=max - name: Show image tags run: | diff --git a/.npmrc b/.npmrc index 58fd2d6..9320736 100644 --- a/.npmrc +++ b/.npmrc @@ -1,5 +1 @@ -# Use China npm mirror for faster downloads in CI -registry=https://registry.npmmirror.com - -# Disable always-auth to avoid deprecation warnings always-auth=false diff --git a/app.json b/app.json index 5a85713..5aaca0c 100644 --- a/app.json +++ b/app.json @@ -66,6 +66,8 @@ "favicon": "./assets/favicon.png" }, "plugins": [ + "./plugins/withCmakeJobLimit", + "./plugins/withJcorePatch", "./plugins/withSigning", "./plugins/withMainActivityConfigChange", [ diff --git a/plugins/withCmakeJobLimit.js b/plugins/withCmakeJobLimit.js new file mode 100644 index 0000000..28f0131 --- /dev/null +++ b/plugins/withCmakeJobLimit.js @@ -0,0 +1,60 @@ +const { withDangerousMod } = require('@expo/config-plugins'); +const fs = require('fs'); +const path = require('path'); + +const MAX_JOBS = '8'; + +// React Native's hermes-engine build hardcodes +// Runtime.getRuntime().availableProcessors() +// for cmake --build -j, ignoring all env vars. +// On high-core CI runners this exhausts memory. +// This plugin patches hermes-engine/build.gradle.kts +// during prebuild to cap parallel jobs. +const withCmakeJobLimit = (config) => + withDangerousMod(config, [ + 'android', + async (config) => { + const root = config.modRequest.projectRoot; + + // 1. Patch hermes-engine: availableProcessors() -> "8" + const hermesPath = path.join( + root, + 'node_modules', + 'react-native', + 'ReactAndroid', + 'hermes-engine', + 'build.gradle.kts', + ); + if (fs.existsSync(hermesPath)) { + let content = fs.readFileSync(hermesPath, 'utf-8'); + content = content.replace( + /Runtime\.getRuntime\(\)\.availableProcessors\(\)\.toString\(\)/, + `"${MAX_JOBS}"`, + ); + fs.writeFileSync(hermesPath, content); + } + + // 2. Patch app/build.gradle: add cmake -j argument to externalNativeBuild + const appGradlePath = path.join( + config.modRequest.platformProjectRoot, + 'app', + 'build.gradle', + ); + if (fs.existsSync(appGradlePath)) { + let content = fs.readFileSync(appGradlePath, 'utf-8'); + // Insert externalNativeBuild cmake arguments block inside the android { } block + // We add it right after "ndkVersion rootProject.ext.ndkVersion" + if (!content.includes('CMAKE_BUILD_PARALLEL_LEVEL')) { + content = content.replace( + /(\s*ndkVersion rootProject\.ext\.ndkVersion)/, + `$1\n externalNativeBuild {\n cmake {\n arguments "-j${MAX_JOBS}"\n }\n }`, + ); + } + fs.writeFileSync(appGradlePath, content); + } + + return config; + }, + ]); + +module.exports = withCmakeJobLimit; diff --git a/plugins/withHuaweiPush.js b/plugins/withHuaweiPush.js index 92b7c2e..a4af2bd 100644 --- a/plugins/withHuaweiPush.js +++ b/plugins/withHuaweiPush.js @@ -22,6 +22,35 @@ const withHuaweiPush = (config, options = {}) => { // is applied via buildscript classpath in build.gradle with the apms-plugin excluded. if (!contents.includes('developer.huawei.com/repo')) { const repoLine = ` maven { url 'https://developer.huawei.com/repo/' }`; + const jigLine = ` maven { url 'https://developer.jiguang.cn/maven' }`; + const hasPluginManagement = contents.includes('pluginManagement'); + const hasRepositoriesInPM = /pluginManagement\s*\{[\s\S]*?repositories\s*\{/.test(contents); + + if (hasRepositoriesInPM) { + config.modResults.contents = contents.replace( + /(pluginManagement\s*\{[\s\S]*?repositories\s*\{)/, + `$1\n ${repoLine}\n ${jigLine}` + ); + } else if (hasPluginManagement) { + config.modResults.contents = contents.replace( + /(pluginManagement\s*\{)/, + `$1\n repositories {\n gradlePluginPortal()\n google()\n mavenCentral()\n ${repoLine}\n ${jigLine}\n }` + ); + } else { + config.modResults.contents = + `pluginManagement {\n repositories {\n ${repoLine}\n ${jigLine}\n }\n}\n\n` + + config.modResults.contents; + } + } + + // Add Jiguang Maven repo for dependency resolution (jcore/jpush SDK) + if (!contents.includes('developer.jiguang.cn/maven')) { + const depMgmtPattern = /dependencyResolutionManagement\s*\{[\s\S]*?repositories\s*\{/; + if (depMgmtPattern.test(config.modResults.contents)) { + config.modResults.contents = config.modResults.contents.replace( + depMgmtPattern, + ` if (!contents.includes('developer.huawei.com/repo')) { + const repoLine = ` maven { url 'https://developer.huawei.com/repo/' }`; const hasPluginManagement = contents.includes('pluginManagement'); const hasRepositoriesInPM = /pluginManagement\s*\{[\s\S]*?repositories\s*\{/.test(contents); @@ -51,6 +80,9 @@ const withHuaweiPush = (config, options = {}) => { `$&\n maven { url 'https://developer.huawei.com/repo/' }` ); } + }\n maven { url 'https://developer.jiguang.cn/maven' }` + ); + } } return config; diff --git a/plugins/withJcorePatch.js b/plugins/withJcorePatch.js new file mode 100644 index 0000000..b81771c --- /dev/null +++ b/plugins/withJcorePatch.js @@ -0,0 +1,43 @@ +const { withDangerousMod } = require('@expo/config-plugins'); +const fs = require('fs'); +const path = require('path'); + +// Patch jcore-react-native's build.gradle to remove the legacy flatDir block +// and jniLibs.srcDirs. The 'libs' directory no longer exists in the package — +// dependencies are fetched from Maven — but the stale config causes Gradle +// warnings and can stall dependency resolution on newer Gradle versions. +const withJcorePatch = (config) => + withDangerousMod(config, [ + 'android', + async (config) => { + const root = config.modRequest.projectRoot; + const gradlePath = path.join( + root, + 'node_modules', + 'jcore-react-native', + 'android', + 'build.gradle', + ); + + if (!fs.existsSync(gradlePath)) return config; + + let content = fs.readFileSync(gradlePath, 'utf-8'); + + // Remove flatDir block + content = content.replace( + /repositories\s*\{\s*flatDir\s*\{\s*dirs\s+['"]libs['"]\s*\}\s*\}/, + '', + ); + + // Remove jniLibs.srcDirs line and its enclosing sourceSets block if it becomes empty + content = content.replace( + /\s*sourceSets\s*\{\s*main\s*\{\s*jniLibs\.srcDirs\s*=\s*\['libs'\]\s*\}\s*\}/, + '', + ); + + fs.writeFileSync(gradlePath, content); + return config; + }, + ]); + +module.exports = withJcorePatch;