美文网首页
flutter项目使用jenkins自动部署

flutter项目使用jenkins自动部署

作者: 可别 | 来源:发表于2021-06-24 14:22 被阅读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

    相关文章

      网友评论

          本文标题:flutter项目使用jenkins自动部署

          本文链接:https://www.haomeiwen.com/subject/rbswyltx.html