Flutter多分支打包持续化集成

news2024/11/28 6:48:37

一、使用效果演示

1.1、选择参数打包

以下为参数使用说明。

  • packingType枚举
android、ios
android
ios
android&ios (新功能:并行打包)

备注:

android、ios:串行打包,即先打一个再打一个

android&ios:为并行打包

  • useOnlineConfig

勾选这个会使用线上配置打包app,专门用于发生产打包

image-20220127202810611
  • brandName

选择git分支,脚本会自动切分支打包

  • 其他

此外,你也可以添加app“默认api环境”、“代理ip”等,由于我们这块都集成到app内部调试页中了,可以用户手动切换,所以不需要就没列举出来。

1.2、任务细节展示

image-20220127202810611

1.3、结果输出

  • 保存历史记录到打包机器

一共四份文件(android 32位包、64位包、ios包、打包信息.txt)

小技巧:对于关键的打包,你也可以使用mac标签为红色,这样方便你下次查找。

image-20220127202810611
  • 同步到钉钉
image-20220127202810611

二、实现步骤

2.1、配置jenkins

创建任务后,选择参数化构建过程,添加参数:

packingType:选择选项参数

useOnlineConfig:选择布尔值参数

image-20220127202810611

branchName:选择Git参数

image-20220127202810611

选择源码管理tab添加项目参数

image-20220127202810611

其中Credentials凭证如果没有需要添加

我这边用的http,只需要添加用户名、密码即可,描述可以随便填一个方便自己查看

image-20220127202810611

最后切换到构建tab

选择执行shell,cd到指定目录执行本地脚本

cd /Users/mac/Desktop/diamond-app/PackageShellFiles
sh buildApp.sh
image-20220127202810611

2.2、编写脚本

这里脚本我拆成了两个,一个打包脚本,一个上传文件脚本

打包脚本:buildApp.sh

#!/bin/bash

export ANDROID_SDK_ROOT="${HOME}/Library/Android/sdk"
export ANDROID_HOME="${HOME}/Library/Android/sdk"

#获取workspace名称
projectName=jiyueji

#文件导出目录(projectName/workspace名称+当前时间)
exportPath=~/Desktop/${projectName}/$(date +"%F日%H-%M-%S秒")

#apk路径(取到apk的路径)
appAndroidPath=${exportPath}/${projectName}.apk
appIosPath=${exportPath}/${projectName}.ipa

#git更新信息
gitUpdateInformation=''

# jenkins选择的分支: origin/dev
echo "打包分支全称:${branchName}"

# jenkins选择的分支简称: dev
selectBranch=${branchName#*/}

#创建文件夹
createDir() {
  echo "创建文件目录"
  if [ ! -d "${exportPath}" ]; then
    mkdir -p ${exportPath}
  fi
  echo "文件夹创建成功,打包中间产物将全部导出到:${exportPath}目录下\n"
}

# android包
buildApk() {
  #    flutter clean
  flutter build apk
  mv ../build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk $appAndroidPath
  mv ../build/app/outputs/flutter-apk/app-arm64-v8a-release.apk ${exportPath}/app-arm64-v8a-release.apk
  echo "android打包结束\n"
  currentBranch=$(git symbolic-ref --short -q HEAD)
  packageString=''
  if [ $useOnlineConfig == true ]; then
    packageString='类型:android线上包\n分支:'$currentBranch'\n更新:'$gitUpdateInformation
  else
    packageString='类型:android测试包\n分支:'$currentBranch'\n更新:'$gitUpdateInformation
  fi
  ./uploadApp.sh $appAndroidPath $packageString
}
# ios包
buildIpa() {
  #flutter clean
  cd ../ios
  pod install
  flutter build ipa --export-options-plist=PackageShellFiles/ExportOptions.plist
  cd ../PackageShellFiles
  mv ../build/ios/ipa/己悦己租包.ipa $appIosPath
  echo "ios打包结束\n"
  currentBranch=$(git symbolic-ref --short -q HEAD)
  packageString=''
  if [ $useOnlineConfig == true ]; then
    packageString='类型:ios线上包\n分支:'$currentBranch'\n更新:'$gitUpdateInformation
  else
    packageString='类型:ios测试包\n分支:'$currentBranch'\n更新:'$gitUpdateInformation
  fi
  ./uploadApp.sh $appIosPath $packageString
}

#打印git commit信息
echoGitCommitId() {
  cd ..
  echo 拉取git信息

  # 更新远程分支
  git fetch origin
  # 选择的分支是否本地存在
  exists=$(git show-ref refs/heads/${selectBranch})
  if [ -n "$exists" ]; then
    git checkout "${selectBranch}"
  else
    git checkout -b "${selectBranch}" "${branchName}"
  fi

  # 当前分支
  currentBranch=$(git symbolic-ref --short -q HEAD)
  echo "切换分支完成,当前分支为:${branchName}"

  git pull
  echo "拉取最新代码"

  echo 当前编译包使用的Git分支为:$(git describe --contains --all HEAD | tr -s '\n')
  echo 当前编译包使用的Git commit短id为:$(git rev-parse --short HEAD)
  gitId=$(git rev-parse HEAD)
  echo 当前编译包使用的Git commit完整id为:$gitId
  gitUpdateInformation=$(git log origin dev --pretty=format:“%s” $gitId -3)
  cd PackageShellFiles
  echo 即将开始打包~
}

# 还原中间产物
resetConfig() {
  if [ -f "./tempConfig.dart" ]; then
    cp ./tempConfig.dart ../lib/config.dart
    rm -f ./tempConfig.dart
  fi
}

# 判断是否打线上包
checkUseOnlineConfig() {
  if [ $useOnlineConfig == true ]; then
    cp ../lib/config.dart ./tempConfig.dart
    cp ./onlineConfig.dart ../lib/config.dart
    echo '正在打线上包'
  else
    echo '正在打测试包'
  fi
}

buildApp() {
  #  打包信息.txt
  if [ $useOnlineConfig == true ]; then
    packageString='类型:线上包\n分支:'$currentBranch'\n更新:'$gitUpdateInformation
    echo $packageString > ${exportPath}/"打包信息.txt"
  else
    packageString='类型:测试包\n分支:'$currentBranch'\n更新:'$gitUpdateInformation
    echo $packageString > ${exportPath}/"打包信息.txt"
  fi

  # 选择打包
  if [ $packingType == android ]; then
    echo '当前只有打android包'
    buildApk
  elif [ $packingType == ios ]; then
    echo '当前只有打ios包'
    buildIpa
  elif [ $packingType == 'android、ios' ]; then
    echo 'android、ios串行打包'
    buildIpa
    buildApk
  else
    echo 'android、ios并行打包'
    buildIpa &
    buildApk
    wait
  fi
}

# 前置操作
resetConfig
echoGitCommitId
createDir

# 打包
checkUseOnlineConfig
buildApp

# 还原中间产物
resetConfig

首先我们拉取到最下面,看到我们有调用这几个方法

resetConfig:判断本地是否有保存配置文件tempConfig.dart,如果有则还原到项目中,起到一个重置的作用

echoGitCommitId:切换分支并拉取最新分支, b r a n c h N a m e 为用户选择的远程分支(例如 o r i g i n / d e v ) , 我们转换为本地分支 {branchName}为用户选择的远程分支(例如origin/dev),我们转换为本地分支 branchName为用户选择的远程分支(例如origin/dev,我们转换为本地分支{branchName#*/}(例如dev),然后判断本地是否有dev分支,如果有直接切换分支checkout,没有则checkout创建dev本地分支,然后执行git pull拉取最新代码,当然在这之前我们一定要先获取远程分支git fetch origin,否则会出现没有找不到远程分支的情况。

createDir:则是按照时间戳创建文件夹

checkUseOnlineConfig:判断是否是需要打线上包,如果是线上包,则使用拷贝命令cp,将内置文件配置文件覆盖到项目配置文件

buildApp:则根据packingType参数选择是android,还是ios的包。

buildIpa &
buildApk
wait

buildIpa &:表示开启后台线程运行

wait:表示等待前面子线程

需要注意的是如果你没有linux基础,一定要记得并行打包需要wait,因为在linux中主线程结束,进程会被销毁,即现象安卓打包线程结束,ios打包线程会被强制结束,同时cd命令在各个线程是分开的互不影响的

上传文件脚本:uploadApp.sh

上传文件脚本相对简单,可以0基础直接上手,主要是涉及到账号的申请找起来稍微麻烦:

钉钉key:在下面叙述

蒲公英key:右侧手机号 -> API信息

image-20220127202810611
#!/bin/bash

#待上传app路径
appPath=$1

#a更新信息
updateInformation=$2

#蒲公英上传结果
result=''

#蒲公英key
AKEY="428c221853ed052ca74846e5bfe4填自己账号"
UKEY="38951568cffd3426e9e8b5e59b66填自己账号"

#钉钉key
DKEY="3761c70fd171bf4726385b6176b053d1465f72e4bd43daf3463e6f77fb1填自己账号"

#上传蒲公英
uploadPgyer(){
  echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>上传蒲公英"
  result="$(curl -F "file=@$appPath" -F "uKey=$UKEY" -F "buildUpdateDescription=$updateInformation" -F "_api_key=$AKEY" -F 'buildInstallType=1' -F 'buildPassword=000000'  https://www.pgyer.com/apiv2/app/upload)"
  echo "app详细信息:\n"$result
  echo "\n\n\n\n"
}

#上传钉钉
uploadDingTalk(){
  echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>上传钉钉"
  data=$(echo $result | jq -r ".data")
  appName=$(echo $data | jq -r ".buildName")
  appVersion=$(echo $data | jq -r ".buildVersion")
  appQRCodeURL=$(echo $data | jq -r ".buildQRCodeURL")
  appShortcutUrl=$(echo $data | jq -r ".buildShortcutUrl")

  curl "https://oapi.dingtalk.com/robot/send?access_token=$DKEY" \
  -H 'Content-Type: application/json' \
  -d '{
        "msgtype": "link",
        "link": {
            "title": "'$appName''$appVersion'",
            "text": "'$updateInformation'",
            "picUrl": "'$appQRCodeURL'",
            "messageUrl": "https://www.pgyer.com/'$appShortcutUrl'"
        },
    }'
    echo "\n\n\n\n"
}

uploadPgyer
uploadDingTalk

2.3、输出到钉钉

在钉钉中创建群聊,添加机器人使用手机 -> 群设置 -> 只能群助手,选择webhook机器人即可,在创建过程中会生成机器人的key

image-20220127202810611

2.4、配置打包电脑历史记录

FileShare网页分享

image-20220127202810611

我们需要在打包电脑安装utools软件,utools里面有一款局域网分享插件FileShare,然后我们把想分享的文件夹拖进去即可。

缺点:不是很稳定,我这边用过了一个星期可能需要重启这个服务,即关闭再打开。优点是网页可以内网穿透放到外网去

image-20220127202810611

smb服务共享

我们在打包电脑上设置 -> 共享 -> 文件共享,添加共享文件夹

image-20220127202810611

然后使用局域网服务器访问:访达 -> 已连接的服务器 -> 打包机器

这样我们就相当于把磁盘共享了,可以很方便的编辑,也不用拷贝来拷贝去了

image-20220127202810611

ssh连接

如果喜欢ssh远程连接的同学也可以使用这个

设置 -> 共享 -> 远程登录,拷贝右侧的登录命令输入在终端即可,密码为打包电脑的登录密码

image-20220127202810611

可以看到这种操作也是非常的爽,有逼格

image-20220127202810611

2.5、问题修复

如果你的jenkins卡在拉取代码过程中,如下所示:

image-20220127202810611

我们需要配置全局的name、email,选择 系统管理 ->系统配置 -> Git plugin

image-20220127202810611 image-20220127202810611

三、不足与改进

3.1、持续化打包

关于jenkins,你可以设置定时打包、提交代码就打包,由于我这里暂时没有这个需求,就没加

3.2、oss存储

由于我这里使用的是蒲公英作为三方存储,二维码都是同一个,每次从钉钉上点旧的包进去也是最新的包。这点可以考虑使用阿里云的oss作为存储方案,一个二维码对应一个包

3.3、钉钉界面

image-20220127202810611

界面上我们使用的是钉钉的默认app分享界面,这点有较大的优化控件,我们可以考虑使用自定义消息UI来改善这个问题

四、源码文件

这里给到的源码文件是完整的PackageShellFiles文件夹,点击下载

各个文件作用解释如下:

tempConfig.dart:临时生成文件 (这里没有显示),在打正式包过程中临时生成,以保存项目的config.dart配置

buildApp.sh :jenkins打包脚本入口

buildLocalApp.sh:手动打包脚本入口

ExportOptions.plist:ios配置清单

onlineConfig.dart:默认的线上配置清单,在打正式包时替换config.dart

uploadApp.sh:上传文件到蒲公英、钉钉脚本

image-20220127202810611

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/153188.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

与香港财政司司长同台,欧科云链在这场峰会上都说了啥?

今天,POWER 2023香港Web3创新者峰会在中国香港如期召开,香港特别行政区政府财政司司长陈茂波、财经事务及库务局副局长陈浩濂、全国政协委员、立法会议员吴杰庄等港府要员出席峰会。 作为本场峰会的受邀企业,欧科云链控股(01499.HK)公司执行董…

Kernel Pwn基础教程之 Double Fetch

一、前言 Double Fetch是一种条件竞争类型的漏洞,其主要形成的原因是由于用户态与内核态之间的数据在进行交互时存在时间差,我们在先前的学习中有了解到内核在从用户态中获取数据时会使用函数copy_from_user,而如果要拷贝的数据过于复杂的话…

人工智能-正则表达式

目录1、正则表达式概述2、re模块3、匹配单个字符4、匹配多个字符5、匹配开头和结尾6、匹配分组7、总结1、正则表达式概述 在实际开发过程中经常会需要查找某些复杂字符串的格式 正则表达式:记录文本规则的代码 正则表达式特点: 语法令人头疼&#xff…

立创eda专业版学习笔记(4)(隐藏铺铜)

这里的隐藏有两个意思,一个是铺铜过后把铺铜的填充区域隐藏,方便看图,另外一个是隐藏铺铜的轮廓,方便后续改进。 第一种隐藏,隐藏铺铜的填充区域(成片的图块),但是保留轮廓线 这是全…

联想LJ2655DN激光打印机清零方法

联想LJ2655DN激光打印机是市面上常见的打印机,为了节约成本,我们一般使用都是代用硒鼓来代替原装硒鼓,但是发现更换完硒鼓以后还是不能打印甚至有的机器能够打印但是打印速度会变慢或很慢,这个时候这就需要我们对打印机进行清零复位操作了,此款机器因用户更换的硒鼓类型不…

C++ 模板进阶

目录 1. 非类型模板参数 2. 模板的特化 2.1 概念 2.2 函数模板特化 2.3 类模板特化 2.3.1 全特化 2.3.2 偏特化 2.3.3 类模板特化应用示例 3. 模板总结 1. 非类型模板参数 我们在C语言中使用数组的时候可以定义静态数组,但是有个缺陷就是编译器在对越界检查…

Java自定义泛型类注意点

目录 自定义泛型类 如果定义了泛型类,实例化没有指明类的泛型,则认为此泛型类型为Object类型 由于子类在继承带泛型的父类时,指明了泛型类型。则实例化子类对象时,不需要指明类型 由于子类在继承带泛型的父类时,没有…

WebDAV之葫芦儿·派盘 + Photosync

PhotoSync 支持WebDAV方式连接葫芦儿派盘。 苹果手机通过无线传输,备份和共享照片/视频到计算机,其他手机,NAS和流行的云和照片服务的最佳解决办法,快来试下PhotoSync同步工具吧。 PhotoSync面向移动设备

安装部署wordpress(Ubuntu)

wordpress是一个目前流行的基于web的内容管理系统软件。它是基于PHP语言和MySQL数据库开发的,用户可以在支持 PHP 和 MySQL数据库的服务器上快速轻松的部署自己的网站(博客,外贸网站等等)。WordPress有非常多的第三方开发的免费模…

产线工控安全之现状分析及方案应对

产线安全现状 工业控制系统是支撑国民经济的重要设施,是工业领域的神经中枢。现在工业控制系统已经广泛应用于电力、通信、化工、交通、航天等工业领域,支撑起国计民生的关键基础设施。 随着传统的工业转型,数字化、网络化和智能化的工业控…

数学建模---数值微积分

目录 一.引言 二.数值微分 1.数值差分与差商 利用matlab观察差分与差商的区别: 例题: 二.数值积分 1.数值积分基本定理 2.常见的数值积分公式: 积分公式的精度: 3.数值积分的matlab实现 一.引言 在科学研究和工程计算中&…

LINUX提权之环境变量提权篇

前言 上一篇文章给大家介绍了linux中的内核提权的一些知识点不知道大家学的怎么样了,今天给大家带来一个全新的提权方法——“环境变量提权”,本文会介绍关于环境变量提权的基本知识以及利用方法。 环境变量提权 PATH是Linux系统中的环境变量,指定存储…

全球月活用户4年破10亿,TikTok的3大底层逻辑

武汉瑞卡迪电子商务有限公司:在即将过去的2022年,TikTok成为了众多出海品牌想要赢得新生意的重要平台。品牌应该如何看待TikTok?如何利用节点营销抓住机会?那些已经在TikTok上成功的品牌背后,是否有一些定式&#xff0…

centos7安装ansible

在ansible中主控机器必须是linux机器,不可以是windows,但是被控机器可以是windows。 control machine:192.168.184.128 target machine:192.168.184.129(被管理机器上不需要安装什么软件) 1.ansible的安装前提是要有python&…

vue的基础指令演示代码及简单案例

目录 一、内容绑定,事件绑定 v-text v-html v-on 案例:计数器 二、显示切换,属性绑定 v-show v-if v-bind 案例:图片切换 三、列表循环,表单元素绑定 v-for v-on补充 v-model 通过Vue实现常见的网页效果…

QSFP-DD封装小知识,你了解吗?

随着数据中心和高级网络应用中数据流量的上升,光模块市场向更高的速度,更低的功耗和更小的外形或尺寸发展。QSFP-DD封装有什么特征和优势?它与QSFP28/QSFP56模块有什么区别的?本期文章,我们一起了解一下QSFP-DD封装相关…

【Linux篇】之网络文件系统(nfs)配置

nfs : Network File System 网络文件系统 作用:linux内核启动之后,通过网络的方式从ubuntu服务器中挂载根文件系统, 而不需要将根文件系统部署到开发板。 1> 安装nfs服务器端 sudo apt-get install nfs-kernel-server2> 修改nfs服务的…

解读手机拍照的各个参数(AI水印)

AI水印就是在照片里面自动添加一些文字或者符号,里面有一些固定的水印,目前还不了解能不能识别一些不是固定地方的景色。(目前给出来的是黄山、张家界景点,不晓得华山这种能不能自动添加上水印)。

Go 1.19.3 channel原理简析

channel channel和goroutine是Go语言的核心命脉。这篇文章来简单介绍一下Go chan的原理,源码并不好读,应结合gmp调度模型来理解,后续补充吧。 由上图可见,chan的底层结构是一个hchan结构体,其中buf字段指向了一个环形…

网狐大联盟服务端源码分析-服务核心

源码目录结构,如下图,服务工程 cpp文件列表及含义: WHBase64.cpp : base6编码类 WHCommandLine.cpp : 命令行参数操作类 WHDataLocker.cpp : 数据锁类,线程操作数据时用 WHDataQueue.cpp : 数据队列类,异步操作数据用 WHEncrypt.cpp : 加密类 WHIniData.cpp : ini文件操作类 WH…