当前位置: 首页 > news >正文

企业级 RN Android 完整 CI/CD 自动化解决方案

脚本实现功能如下:

  • 自动生成 RN bundle

  • Debug/Release + 多渠道打包

  • 自动 versionCode / versionName

  • 自动生成 Changelog(Git commit)

  • APK 上传到蒲公英 + 内部服务器

  • 自动生成下载二维码

  • 自动生成网页渠道列表(带二维码和下载链接)

  • 钉钉/飞书通知构建结果

  • Jenkins 参数化构建,多渠道循环


1.修改 scripts/bundle-android.sh(增加历史版本管理)

#!/bin/bash
# ===============================
# RN Android 多渠道 bundle & APK 自动打包 + Changelog + QR + 网页历史版本
# ===============================set -eROOT_DIR=$(cd "$(dirname "$0")/.." && pwd)
cd $ROOT_DIRBUILD_TYPE=${1:-Release}   # Release 或 Debug
FLAVOR=${2:-prod}          # 默认 prod 渠道BUILD_TIME=$(date "+%Y-%m-%d %H:%M")
echo "Build Type: $BUILD_TYPE, Flavor: $FLAVOR, Build Time: $BUILD_TIME"# RN 版本
RN_VERSION=$(npx react-native --version)
echo "React Native version: $RN_VERSION"# 清理旧 bundle
rm -rf android/app/src/main/assets/index.android.bundle
rm -rf android/app/src/main/res/*# 安装依赖 & 打包 bundle
npm install
npm run bundle-android# 自动 versionCode / versionName
VERSION_CODE=$(date +%Y%m%d%H%M)
VERSION_NAME=$(date +%Y.%m.%d.%H%M)
sed -i "" "s/versionCode .*/versionCode $VERSION_CODE/" android/app/build.gradle
sed -i "" "s/versionName \".*\"/versionName \"$VERSION_NAME\"/" android/app/build.gradle# 生成 Changelog
CHANGELOG=$(git log --pretty=format:"%h %s" --no-merges -n 10)
echo "$CHANGELOG" > build_changelog.txt# 编译 APK
cd android
if [ "$BUILD_TYPE" == "Debug" ]; then./gradlew clean assemble${FLAVOR^}Debug
else./gradlew clean assemble${FLAVOR^}Release
fiAPK_PATH=$(ls app/build/outputs/apk/${FLAVOR}/${BUILD_TYPE,,}/*.apk)
echo $APK_PATH > ../last_apk_path.txt# 生成二维码
APK_URL="http://your.server/path/to/apk/$(basename $APK_PATH)"
QR_FILE="$ROOT_DIR/qr_${FLAVOR}_${VERSION_CODE}.png"
python3 - <<EOF
import qrcode
img = qrcode.make("$APK_URL")
img.save("$QR_FILE")
EOF# 更新网页历史版本列表
HTML_FILE="$ROOT_DIR/apk_list.html"# 创建 HTML 文件头
if [ ! -f "$HTML_FILE" ]; then
cat <<EOT > "$HTML_FILE"
<html>
<head>
<title>Android APK 历史版本</title>
<meta charset="utf-8">
</head>
<body>
<h2>Android APK 下载历史版本</h2>
<ul id="apk-list">
</ul>
</body>
</html>
EOT
fi# 生成单条 HTML
ENTRY="<li><b>${BUILD_TIME} ${FLAVOR} (${BUILD_TYPE}) v${VERSION_NAME}</b><br>"
ENTRY+="<a href='${APK_URL}'>下载 APK</a><br>"
ENTRY+="<img src='qr_${FLAVOR}_${VERSION_CODE}.png' width='150'/><br>"
ENTRY+="<pre>${CHANGELOG}</pre></li>"# 使用 sed 插入到 <ul id="apk-list"> 内
sed -i "" "/<ul id=\"apk-list\">/a\\
$ENTRY
" "$HTML_FILE"echo "✅ Build finished: ${BUILD_TYPE}-${FLAVOR}, APK: $APK_PATH"

2. Jenkinsfile 修改(保留历史版本 + 汇总通知)

pipeline {agent anyparameters {choice(name: 'BUILD_TYPE', choices: ['Debug','Release'], description: '选择构建类型')string(name: 'FLAVORS', defaultValue: 'prod,test,dev', description: '选择要打的渠道,多渠道用逗号分隔')}environment {NODE_HOME = "/usr/local/bin/node"NPM_HOME  = "/usr/local/bin/npm"JAVA_HOME = "/usr/lib/jvm/java-11-openjdk"ANDROID_HOME = "/usr/local/android-sdk"PATH = "${env.ANDROID_HOME}/tools:${env.ANDROID_HOME}/platform-tools:${env.NODE_HOME}:${env.NPM_HOME}:${env.PATH}"UPLOAD_PGY = "https://www.pgyer.com/apiv2/app/upload"PGY_API_KEY = "your_pgy_api_key"INTERNAL_SERVER = "user@your.server:/path/to/apk"NOTIFY_WEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=your_token"}stages {stage('Checkout') { steps { checkout scm } }stage('Install Dependencies') { steps { sh 'npm install' } }stage('Build & Upload APKs') {steps {script {def flavorList = params.FLAVORS.split(',')for (flavor in flavorList) {flavor = flavor.trim()echo "------------------ Building ${params.BUILD_TYPE}-${flavor} ------------------"sh "./scripts/bundle-android.sh ${params.BUILD_TYPE} ${flavor}"def apkPath = readFile('last_apk_path.txt').trim()def qrFile = "qr_${flavor}_*.png"// 上传 APK + QR 到服务器sh "scp ${apkPath} ${INTERNAL_SERVER}"sh "scp ${qrFile} ${INTERNAL_SERVER}"// 上传蒲公英sh """curl -F "file=@${apkPath}" -F "_api_key=${PGY_API_KEY}" ${UPLOAD_PGY}"""}// 上传网页历史版本列表sh "scp apk_list.html ${INTERNAL_SERVER}"}}}}post {success {echo "✅ All builds finished successfully!"// 发送 HTML 消息到钉钉/飞书,通知包含网页历史版本链接sh """curl ${NOTIFY_WEBHOOK} -H 'Content-Type: application/json' -d '{"msgtype": "text","text": {"content": "✅ Android ${params.BUILD_TYPE} 构建成功,历史版本页面: http://your.server/path/to/apk_list.html"}}'"""}failure {echo "❌ Build failed!"sh """curl ${NOTIFY_WEBHOOK} -H 'Content-Type: application/json' -d '{"msgtype": "text","text": {"content": "❌ Android ${params.BUILD_TYPE} 构建失败,请检查 Jenkins 日志!"}}'"""}}
}

3.工程目录结构示意

rn-jenkins-demo/
├─ android/
│  ├─ app/
│  │  ├─ src/main/assets/
│  │  ├─ src/main/res/
│  └─ build.gradle
├─ ios/
├─ scripts/
│  └─ bundle-android.sh
├─ index.js
├─ package.json
├─ Jenkinsfile
└─ ...

4.特性总结

  1. 历史版本网页:所有构建都会在 apk_list.html 中生成条目,保留历史版本。
  2. 每个渠道生成二维码,可直接扫码下载 APK。
  3. 自动 versionCode / versionName,保证 APK 唯一性。
  4. 自动生成最近 10 条 Git commit Changelog,嵌入网页和通知中。
  5. 多渠道打包,支持循环处理 prod/test/dev 等渠道。
  6. 上传到蒲公英 + 内部服务器,网页、二维码同步更新。
  7. Jenkins 参数化构建 + 钉钉/飞书通知。
  8. 网页按构建时间倒序显示,最新版本在最上方,方便测试人员长期管理 APK。

这个方案已经是 企业级 RN Android 完整 CI/CD 自动化解决方案,测试人员只需访问网页就能看到全部渠道历史版本和下载二维码,无需单独维护。

http://www.dtcms.com/a/338995.html

相关文章:

  • 从《捕风追影》看地理信息大屏可视化:不止于电影的 “天眼” 黑科技
  • 笔试——Day43
  • 2.Kotlin 集合 List 所有方法
  • 服务器无公网ip如何对外提供服务?本地网络只有内网IP,如何能被外网访问?
  • Netty内存池中ChunkList详解
  • STM32G4 Park及反Park变换(二)实验
  • 推理还是训练 || KV缓存和CoT技术
  • 快速将 MySQL 数据库发布为 API:使用 QuickAPI 实现 SQL2API
  • SConscript 脚本入门教程
  • ChatBI驱动的智能商业决策:奥威BI的深度实践
  • 图像增强——灰度变换增强(线性,对数,指数)、空间滤波增强、频域增强、主成分/彩色合成增强(原理解释和代码示例)
  • 源码编译安装LAMP架构并部署WordPress(CentOS 7)
  • Unity音频管理:打造沉浸式游戏音效
  • BCT8937A Class T Audio Amplifier
  • 小程序开发APP
  • 车载以太网gPTP时间同步:从协议到工程实践
  • 如何用20%计算成本训练LLaMA4级大模型?MoE稀疏化架构实战指南
  • 第14章 现代React特性
  • 使用 MySQL 为 SpreadJS 协同服务器提供存储支持
  • 前后端联合实现文件下载,实现 SQL Server image 类型文件下载
  • PHP如何使用JpGraph生成折线图?
  • 如何在 uBlock Origin 中忽略指定网站的某一个拦截规则
  • 【数据可视化-94】2025 亚洲杯总决赛数据可视化分析:澳大利亚队 vs 中国队
  • HarmonyOS中AppStorageV2信息储存使用案例
  • 【git】 撤销revert一次commit中的某几个文件
  • HarmonyOS 实战:学会在鸿蒙中使用第三方 JavaScript 库(附完整 Demo)
  • CalMAN简介
  • ECharts漏斗图-漏斗图1,附视频讲解与代码下载
  • 程序员之电工基础-万用表、开关电源
  • Visual Studio中的常用调试功能(下)