flutter项目使用jenkins自动部署

2021-06-24  本文已影响0人  可别

操作系统:macOS Big Sur
前置需求:

# Terminal:homebrew、rvm、ruby、gem、cocoapods
# 编译器:vscode、androidStudio、xcode
# Flutter:flutter sdk、dart
# Android&iOS:android sdk、gradle、jdk、.keystore、P12、.mobileprovision等
# terminal运行flutter doctor无异常
# vscode编译运行flutter项目成功
# androidStudio和xcode单独编译运行flutter项目下的android和ios项目成功

ok,开始搞jenkins

1、使用homebrew安装jenkins

Terminal运行命令brew install Jenkins

2、运行jenkins

Terminal运行命令jenkins,最终出现 Jenkins is fully up and running代表运行成功

3、初始化jenkins

在浏览器地址栏输入http://localhost:8080/
然后首次安装启动就会出现新手引导,根据引导操作
自定义jenkins那里选择安装推荐的插件
PS:这里我很多插件都安装失败了,这个没关系,可以进去再自己安装或者不再安装貌似也没啥影响,继续向下操作即可
最后的实例配置那,默认即可,也可以设置一个地址
PS:如果要设置的话,就是自己的电脑ip地址+8080端口就行,配置完之后系统管理里报了一个反向代理设置有误,目前没发现这个报错有什么不好的影响,这个地址也可以以后在jenkins系统管理-系统配置里改的,这个主要是用来让别的同事来访问时要用的,自己用的话就不用设置,额外说一个,如果同事电脑挂了vpn,大概率是访问不了你设置的这个地址的,退掉vpn即可

4、安装插件

进来第一步就是安装插件了,这里要用到哪些我也是根据别人的博客找的,但是由于我主要是用shell命令,所以好像很多都没用上,但是安装了也不亏。。。
gitLab Plugin、gitLab Hook Plugin、Xcode integration、keychains and provisioning profiles Management,DingTalk等
PS:说下这个Upload Keychain or Provisioning Profile File插件,这个是用来管理iOS证书和配置文件的,但是吐血的是,无论如何都传不上去,搞到头秃,最后没办法,放弃治疗,好在还有别的办法,往下看
然后DingTalk这个是在构建成功后自动通知到钉钉群的插件,我这边用到了,下面也有介绍

5、iOS相关设置

系统管理-Manage Credentials


WX20210624-114517.png

点击 Stores scoped to Jenkins下面的域-全局,然后就可以添加全局凭据了,这里要添加的是:

gitLab或者gitHub账号密码(Username with password)
/Library/Keychains路径(macOS Keychain password and path)
mobileprovision文件(Apple Developer Profile)
P12文件(Certificate)

Upload Keychain or Provisioning Profile File插件用不了,配置文件在这里添加也是一样的

6、Android相关设置

系统管理-系统配置-全局属性-环境变量
Android SDK设置


2.png

系统管理-全局工具配置
JDK设置


3.png

Gradle设置


4.png

7、钉钉插件通知配置

在钉钉群的设置-智能群助手-添加自定义机器人
要复制一下webhook链接,下面要用,还有关键字设置,要钉钉和jenkins一致


5.png

在jenkins系统管理-系统配置中,设置钉钉,点击测试如果群聊能收到通知就可以


6.png

8、新建任务

这里是Android和iOS各建一个,选择freestyle即可,两边别的都一样,就是shell命令不一样,下面会贴
点开新建的任务,点击配置

①描述和钉钉


8.png

②git信息


9.png

git这里是自己项目的git地址和之前全局配置的git账号密码,也可以再这里添加新的账号密码

③构建触发器和构建环境都不用选

④构建
选择执行shell,然后填写shell命令(iOS和Android我都贴上了,可以自己参考和修改)
里面的一些关键密码和文件名等,我改成了文字描述或者***,都填自己的
此shell支持的一些功能:清空指定文件夹,替换指定文件,替换指定文件的指定内容,导出安装包,上传蒲公英,安装包重命名(version+build+时间),安装包上传svn

iOS打包shell

# keychain-这里可能你进去看到只有login.keychain-db,复制一份然后去掉-db即可
security unlock-keychain -p 电脑密码 ${HOME}/library/keychains/login.keychain

# 工程名-在xcode中查看PROJECT
APP_NAME="Runner"

# target-在xcode中查看TARGETS
TARGET_NAME="primary"

# 证书
# 这里是钥匙串中证书的显示简介-常用名称
CODE_SIGN_DISTRIBUTION="Apple Development: *** (Q3******UZ)"

# 这里是mobileprovision文件的UUID
provisoning_profile="e4270330-***********-473b3a50de58"

# 模式
CONFIGURATION="Release"

# 路径 这个路径要自己看/Users/你的电脑用户名/.jenkins/workspace/下的,你每建一个项目,构建后都会在这下面创建对应的文件夹存放git clone下来的项目
WORKSPACE_PATH=${WORKSPACE}/witparking/ios/${APP_NAME}.xcworkspace
# 这个是导出ipa用的文件,用xcode导出一个对应模式的ipa就能获取到,把那个文件的路径放这里
EXPORT_OPTIONS=/Users/你的电脑用户名/Desktop/***/ExportOptions.plist
ArchivePath=/Users/***/.jenkins/workspace/witParkingIOS@tmp/
EXPORTIPA=/Users/***/.jenkins/workspace/witParkingIOS@tmp/

# 清空存放ipa的文件夹
cd ${EXPORTIPA}
rm -rf *

# 将指定文件的指定内容替换掉pro/dev/test
# 这里是修改main_primary文件的指定内容,切换环境
# 如下示例意思是,使用app5test.wit替换该文件的从app开始,到wit结束的指定字段
cd ${WORKSPACE}/witparking/lib/flavors
sed -i '' "s/app.*wit/app5test.wit/" main_primary.dart

# flutter pub get
cd ${WORKSPACE}/witparking/
flutter pub get

# build app,里面的primary是前面的target
flutter build ios --release --flavor primary -t lib/flavors/main_primary.dart

# 进入原生项目 archive和export
cd ${WORKSPACE}/witparking/ios/

pod install

# 导出achive,里面的primary是前面的target
xcodebuild archive -workspace ${WORKSPACE_PATH} -scheme "primary" -configuration ${CONFIGURATION} -sdk iphoneos -archivePath ${ArchivePath}runner.xcarchive

# 导出ipa
xcodebuild -exportArchive -archivePath ${ArchivePath}runner.xcarchive -exportPath ${EXPORTIPA}runner -exportOptionsPlist ¥{EXPORT_OPTIONS}

# echo "=================上传到蒲公英分发平台 ================="
curl -F "file=@${EXPORTIPA}runner/Runner.ipa" \

# uKey和api_key都可以去蒲公英自己的账号信息里查看
-F "uKey=662aad68ce*****32c8114d87a13" \
-F "_api_key=46755cd719*******b4fd8fa55f" \
[https://www.pgyer.com/apiv1/app/upload](https://www.pgyer.com/apiv1/app/upload)

# ipa重命名(这里重命名是因为上传svn有统一的命名格式)

# info.plist路径
project_infoplist_path=${WORKSPACE}/witparking/ios/Info.plist

# 取版本号
bundleVersion=$(/usr/libexec/PlistBuddy -c "print CFBundleShortVersionString" "${project_infoplist_path}")

# 取build值
bundleBuild=$(/usr/libexec/PlistBuddy -c "print CFBundleVersion" "${project_infoplist_path}")

# 获取年月日时分
DATE="$(date +%Y%m%d%H%M)"

cd ${EXPORTIPA}runner

# 拼接新名字
ipaReName=${bundleVersion}-${bundleBuild}-${DATE}.ipa

# 替换
mv Runner.ipa ${ipaReName}

# 上传svn

# 账号信息
svnname=账号
svnpwd=密码
hostname=root
hostpwd=rootpwd

# 待提交文件
myFile=${ipaReName}

# ipa文件地址
resource_dir=${EXPORTIPA}runner/${myFile}

# 本地仓库地址
commit_dir=/Users/***/Desktop/APP/测试环境/IOS

# svn路径
target_svn_dir=svn://*****/测试/版本管理/APP版本/APP

cd $commit_dir

# 先更新项目
svn update --username $svnname --password $svnpwd

# 复制安装包到提交目录
cp $resource_dir $commit_dir

#增加项目
svn add $commit_dir/$myFile

#上传项目
svn commit -m "commit file ipa" $commit_dir --username $svnname --password $svnpwd

echo "====================== svn commit end ======================"

Android apk打包shell

# apk目录
WORKSPACE_PATH=${WORKSPACE}/witparking/build/app/outputs/apk/primary/release

# 将指定文件的指定内容替换掉pro/dev/test
cd ${WORKSPACE}/witparking/lib/flavors
sed -i '' "s/app.*wit/app5test.wit/" main_primary.dart

# 清空存放apk的文件夹(首次编译没有这个路径的文件夹,因此首次编译需要注释掉这里)
cd ${WORKSPACE_PATH}
rm -rf *

# flutter pub get
cd ${WORKSPACE}/witparking/
flutter pub get

# 安卓down下来的插件有个错误,会导致运行失败,因此需要替换文件内容
# 被替换文件

A=/Users/***/Desktop/flutter/.pub-cache/hosted/pub.flutter-io.cn/contact_picker-0.0.2/android/src/main/java/net/goderbauer/flutter/contactpicker/ContactPickerPlugin.java

# 替换文件
B=/Users/****/Desktop/WitParkingDEV/ContactPickerPlugin.java

cat $B > $A

echo "==========已替换插件文件=========="

# 编译apk
flutter build apk --flavor primary -t lib/flavors/main_primary.dart --no-shrink

# 获取最新apk包的名称
cd ${WORKSPACE_PATH}

# apk名称
fileName="xx"

# 遍历获取后缀为apk的文件名
traverse_dir()
{
    filepath=${WORKSPACE_PATH}
    for file in `ls -a $filepath`
    do
        if [ -d ${filepath}/$file ]
        then
            if [[ $file != '.' && $file != '..' ]]
            then
                # 递归
                traverse_dir ${filepath}/$file
            fi
        else
            # 调用查找指定后缀文件
            check_suffix $file
        fi
    done
}

# 获取后缀为apk的文件
check_suffix()
{
    file=$1
    if [ "${file##*.}" = "apk" ];
    then
        fileName=${file}
    fi   
}

traverse_dir ${WORKSPACE_PATH}

# apk签名

# 别名
aliase='****'

# 库密码
storepass='****'

# 签名密码
keypass='****'

# 秘钥
keystore='/Users/****/Desktop/WitParkingDEV/com.rpms.uaandroid.keystore'
output="output"
if [ ! -d "$output" ];then
   mkdir $output
fi

# 签名
function sign(){
     jarsigner -verbose -digestalg SHA1 -sigalg MD5withRSA -keystore $keystore -storepass $storepass -keypass $keypass -signedjar $tempname $filename $aliase
}
# $output"/"$(basename $filename .apk)"_signed.apk"
for filename in *
do
   if [ "${filename##*.}" = "apk" ]; then
       outputname=$output"/"${filename//_unsign/_signed}
       echo "签名: "$filename
       tempname=$(basename $filename .apk)"_temp.apk"
       sign
       rm -rf $tempname
   fi
done
echo "-------签名已完成------"

# echo "=================上传到蒲公英分发平台 ================="
同上

# apk加时间戳
# 获取年月日时分
DATE="$(date +%Y%m%d%H%M)"

# 获取不带apk后缀的包名并重命名--从右边开始,删除第一个.及右边的字符
rename=${filename%.*}-${DATE}.apk
mv ${fileName} ${rename}

# 上传svn
同上

⑤构建后操作也不用做,保存

9、点击立即构建
如果构建失败可以点击当次构建,然后点击查看控制台输出,查看具体报错进行修改,一般来说只要androidStudio和xcode能够编译成功的话,这边问题都不大,一般都是一些小问题要改,如果构建成功,就会通知到钉钉群了


10.png
上一篇下一篇

猜你喜欢

热点阅读