基於Jekins+GitLab的混合工程實現Flutter自動化打包方案
簡介
Android專案想要依賴Flutter工程,存在兩種依賴方式:1、直接採用專案工程依賴(需要組內成員配置flutter環境)2、通過aar工程產物的方式依賴,對原生侵入較小,組內其他成員無感知。
因此這裡採用了方案二。
注意由於Flutter 1.22.x後,flutter版本有了較大的變化,其中flutter engine從flutter通過打包命令生成的aar剝離,因此直接依賴aar的方式並不能達到要求。
這是Android專案對Flutter專案的依賴主要分為三部分:flutter-release.aar,flutter engine,第三方plugins。
這裡又有了兩種處理方式:
- 我們可以在專案的build.gradle中,將所有的依賴寫上,但這顯然會讓專案的build.gradle 檔案變得混亂。
- 使用fat-aar的方式將所有的依賴裝在到flutter-release.aar中,簡化專案結構。
這裡,採用方案二。
至此,大體的打包過程我們已經知悉,接下來,我們可以通過命令列,和修改配置檔案的方式,手動打包成功。
將aar遷移到Android專案中,就可以正常執行了。
但是,作為一個成熟的專案,這樣的人工打包方案自然是不能長久,因此gitlab+jekins的自動打包流程就需要建立起來了。
自動打包需求
1、在jekins介面可以一鍵完成flutter自動打包,Android依賴包更新。
2、支援flutter開發分支和master分支切換,來滿足開發和釋出的需求變更。
3、Android可以支援露出flutter的git commit id,來確認flutter的程式碼是否是最新程式碼。
自動化打包方案
方案一:dart指令碼+maven倉庫遠端依賴方式,也是我最開始採用的方案。
步驟一:建立maven倉庫,諮詢了公司運維,得知還沒有自己的maven私庫後,找運維同學分配了主機,通過nexus建立了maven私庫。
建立成功後介面如下:
其中maven-release,為版本釋出的aar倉庫依賴,maven-snapshot為開發階段的快照aar依賴。
步驟二:
通過指令碼修改.adroid下的部分配置檔案,打包生成aar。
具體的指令碼邏輯可以自己檢視,主要參考了http://jsshou.cn/blog/flutter/flutter_build_android.html#%E8%84%9A%E6%9C%AC%E5%BC%80%E5%8F%91
步驟三:通過dart指令碼上傳aar到maven倉庫。
將上述的檔案配置完成後,就可以執行命令了,其中上傳maven庫時,要尤其主要地址和artifact-id的問題。
步驟四:在專案中通過類似其他網路庫的依賴方式進行依賴:
方案二:shell指令碼+jekins打包機檔案遷移
方案一提供了一個很好地版本管理和快照的maven倉庫方式,但是並沒有和jekins很好地結合,例如無法獲取flutter專案的commint_id,動態依賴不同的flutter分支,因此這裡採用了第二種方式。
區別點主要在兩點:
- 修改dart命令為shell命令,剝離整體對flutter的專案依賴,直接通過shell命令修改flutter程式碼中的build檔案。
- 不再執行上傳操作,直接在打包機中將生成的aar遷移到android的lib目錄下依賴。
- 同時生成commit檔案,遷移到android專案的assets目錄下。
綜上:採用了方案二來完成打包的邏輯。
打包實現邏輯
1、分支選擇及路徑配置
#!/bin/bash #初始化預設值 build_configuration="release" flutter_git="stable" while [ "$1" != "" ]; do case $1 in -b | --build_configuration) shift build_configuration=("$1") ;; -f | --flutter_git) shift flutter_git="$1" ;; esac shift done if [ "$build_configuration" = "daily" ]; then flutter_git="dev" elif [ "$build_configuration" = "daily_new" ]; then flutter_git="dev" elif [ "$build_configuration" = "debug" ]; then flutter_git="dev" else flutter_git="stable" fi echo "${build_configuration} 當前選擇 git 分支 ${flutter_git}" work_path=${PWD} cd ${work_path} # 當前位置跳到指令碼位置 echo "work_path == ${work_path}" flutter_path="${work_path}/stock_flutter/.android/Flutter/build/outputs/aar" echo "flutter_path == ${flutter_path}" target_path="${work_path}/libcommon/libs" echo "target_path == ${target_path}" target_asset_path="${work_path}/libcommon/src/main/assets/" function moveArchiveFile() { # echo "moveFile ${build_configuration}" if [ $build_configuration = "Debug" ]; then echo "done ==" exit fi filesPath="${flutter_path}/" cd $filesPath files=$(ls ${PWD}) length=0 for filename in $files; do let length=length+1 done limitedLength=0 echo "length == ${length}" if [[ $length -gt $limitedLength ]]; then for filename in $files; do # echo "file1 == ${target_path}${filename}" # echo "file2 == ${filesPath}${filename}" echo "file $filename" moveArrFile $filename echo "flutter 依賴包移動成功" done else echo "flutter 資源打包失敗" fi } function moveArrFile() { if [ ! -d ${target_asset_path} ];then mkdir ${target_asset_path} else echo "資料夾已經存在" fi if [[ $1 == *"txt"* ]]; then echo "txt" rm -rf "${target_asset_path}$1" mv -f "${filesPath}$1" "${target_asset_path}" else rm -rf "${target_path}$1" mv -f "${filesPath}$1" "${target_path}" fi } |
clone flutter倉庫程式碼
echo "************************* 更新本地檔案 Flutter *************************" cd ${work_path} #exit echo "************************* 開始下載、打包 flutter 資源 *************************" export PUB_HOSTED_URL=https://pub.flutter-io.cn export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn echo "remove cache data" rm -rf "${work_path}/stock_flutter" git clone ssh://git@git.5th.im:2222/long-bridge-frontend/stock_flutter.git stock_flutter -b master cd stock_flutter git checkout -f ${flutter_git} git pull #git submodule update --init git submodule update --force --recursive --init --remote #read commit id git_commit_id=$(git rev-parse --short HEAD) echo "commit id = ${git_commit_id}" echo "./flutterw clean" ./flutterw clean ./flutterw doctor ./flutterw pub get |
修改flutter 打包的配置檔案
由於需要區分google和普通release,主要是v7和v8的不同。
其中主要是
- .android下的build.gradle .android/Flutter/build.gradle 版本修改。
- .android/gradle/wrapper/gradle.properties 版本修改,這裡修改是由於我們專案的打包機上gradle版本問題,只能和android專案的保持一致。
echo "************************* 開始修改flutter-build相關檔案 *************************" #這裡可以使用shell命令來修改檔案 #${work_path}/stock_flutter/.flutter/bin/dart ${work_path}/stock_flutter/configs/build_android.dart googleGradlePlugin=" dependencies {\n embed \"io.flutter:flutter_embedding_release:1.0.0-a1440ca392ca23e874a105c5f3248b495bd0e247\"\n embed \"io.flutter:arm64_v8a_release:1.0.0-a1440ca392ca23e874a105c5f3248b495bd0e247\"\n embed \"io.flutter:armeabi_v7a_release:1.0.0-a1440ca392ca23e874a105c5f3248b495bd0e247\"\n def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()\n def plugins = new Properties()\n def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')\n if (pluginsFile.exists()) {\n pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }\n }\n plugins.each { name, path->\n File editableAndroidProject = new File(path, 'android' + File.separator + 'build.gradle')\n println name\n if (editableAndroidProject.exists()) {\n embed project(path: \":\$name\", configuration: 'default')\n }\n }\n }" gradlePlugin=" dependencies {\n embed \"io.flutter:flutter_embedding_release:1.0.0-a1440ca392ca23e874a105c5f3248b495bd0e247\"\n embed \"io.flutter:armeabi_v7a_release:1.0.0-a1440ca392ca23e874a105c5f3248b495bd0e247\"\n def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()\n def plugins = new Properties()\n def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')\n if (pluginsFile.exists()) {\n pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }\n }\n plugins.each { name, path->\n File editableAndroidProject = new File(path, 'android' + File.separator + 'build.gradle')\n println name\n if (editableAndroidProject.exists()) {\n embed project(path: \":\$name\", configuration: 'default')\n }\n }\n } " cd .android sed -ig 's/3.5.0/3.4.0/' build.gradle sed -i '' '10a\'$'\nclasspath "com.kezong:fat-aar:1.2.5"\n' build.gradle cd Flutter sed -i '' '$a\'$'\napply plugin: "com.kezong.fat-aar"\n' build.gradle sed -i '' '$a\'$'\napply from: "../config/dependencies_gradle_plugin.gradle"\n' build.gradle cd .. mkdir "config" cd config touch dependencies_gradle_plugin.gradle if [ "$build_configuration" = "google" ];then echo ${googleGradlePlugin} > dependencies_gradle_plugin.gradle else echo ${gradlePlugin} > dependencies_gradle_plugin.gradle fi cd .. cd gradle cd wrapper sed -ig 's/5.6.2/5.6.4/' gradle-wrapper.properties echo "************************* 結束脩改flutter-build相關檔案 *************************" |
打包生成aar檔案 遷移aar檔案
echo "************************* 開始打包 flutter 資源 *************************" cd ${work_path} cd stock_flutter if [ "$build_configuration" = "google" ];then ./flutterw build aar --no-debug --no-profile --target-platform android-arm64 else ./flutterw build aar --no-debug --no-profile --target-platform android-arm fi cd ${flutter_path} echo "commit id=${git_commit_id}" >flutter_version.txt ls moveArchiveFile sleep 5 cd ${work_path} |
遠端打包方式
遠端打包通過jekins配置,主要需要配置的點在於
--build_configuration 後的配置區別:
- 不配置,對應 flutter分支為stable,主要用於專案發版
- daily ,對應 flutter分支為dev,主要用於Android daily開發中需要更新最新的flutter程式碼。
- google,對應 flutter分支為stable,但是對應架構為v8,主要用於google市場上架。
相關文章
- Flutter iOS 混合工程自動化FlutteriOS
- 基於Jenkins實現php專案的自動化測試、自動打包和自動部署JenkinsPHP
- iOS如何實現自動化打包iOS
- 使用 fastlane 實現自動化打包AST
- 基於RestAssured實現介面自動化REST
- 基於gulp的前端自動化方案前端
- 實現Xcode 9自動化打包XCode
- Flutter混合工程改造實踐Flutter
- 基於DotNetty實現自動釋出 - 實現一鍵打包釋出Netty
- iOS--利用Fastlane實現自動化打包iOSAST
- Java + SikuliX 基於影像實現自動化測試Java
- Now直播iOS Flutter混合工程實踐iOSFlutter
- 基於多Engine、Navigator2.0實現混合棧管理方案實踐
- 基於DotNetty實現自動釋出 - 自動檢測程式碼變化Netty
- 基於聲網 Flutter SDK 實現互動直播Flutter
- 微店的Flutter混合開發元件化與工程化架構Flutter元件化架構
- Jenkins + Git + fastlane + 蒲公英實現自動化打包上傳JenkinsGitAST
- fastlane實現自動化打包上傳測試平臺AST
- 關於jenkins自動化打包探索Jenkins
- 利用人工智慧實現基於影像的自動化檢查人工智慧
- 基於vue自動化表單實踐Vue
- 關於iOS自動化打包的一些分享iOS
- fastlane 自動化打包工具實踐AST
- FLUTTER混合工程踩坑之旅Flutter
- Flutter混合工程開發探究Flutter
- 基於postman的api自動化測試實踐PostmanAPI
- 前端開發:基於cypress的自動化實踐前端
- 搬運:python基於pywinauto實現PC端自動化 python操作微信自動化Python
- 如何基於營銷自動化實現跨渠道整合營銷
- 基於 Springboot+layui 實現介面自動化平臺Spring BootUI
- 基於 Pytest+Requests+Allure 實現介面自動化測試
- 基於JQuery實現的文字框自動填充功能jQuery
- 使用Jenkins實現前端自動化打包部署(Linux版本)Jenkins前端Linux
- 基於Python+requests搭建的自動化框架-實現流程化的介面串聯Python框架
- Flutter 多環境、多渠道自動打包Flutter
- 58 趕集基於 Docker 的自動化部署實踐Docker
- 自動化打包那些事
- Python的iOS自動化打包PythoniOS