Android打包Flutter模块上传到maven仓库的最佳实现

2021-12-06 21:31:12 浏览数 (1)

Android打包Flutter模块上传到maven仓库的最佳实现

在混合开发中,把Flutter模块打包成aar提供给宿主工程依赖可以很大成都降低团队Flutter的学习成本,也是很多混合开发团队的首选,但是如何把build出来的aar包上传到maven仓库,却是一个值得探讨的话题,以为上传到远端maven仓库会存在以下问题:

1、如何自动化上传所有的aar和pom文件?

在对Flutter模块进行打包时,很少只会打出一个aar模块,因为许多依赖的三方库在打包时也会生成aar和pom文件,通过手动的方式上传到maven仓库显然是不合适的,因此需要一个自动化脚本来帮我们遍历build/host/outputs/repo下面的所有aar和pom文件并上传。

2、如何隔离不同项目flutter模块里相同三方依赖冲突的风险?

如果有5个不同项目里都有flutter模块,这些模块都依赖的webview_flutter,但是版本有可能不同,webview_flutter生成的pom文件里组织名是相同的,如果直接上传到maven,可能会影响到其他的项目。需要隔离不同flutter中引用的相同框架生成的aar来规避不确定风险,因为一旦出现这样的风险,将会很难排查。

以下就是针对上诉问题,我给你的答案:

首先在flutter项目根目录定义一个package.properties的文件,其内容如下:

代码语言:javascript复制
projectName=demo
packageName=com.example.upload
buildVersion=1.0.5
mavenRepository=http://admin:admin123@localhost:8081/repository/flutter_modules/
mavenSnapshots=http://admin:admin123@localhost:8081/repository/maven-snapshots/
复制代码

projectName:flutter项目的名称,该名称会作为maven仓库中的artifactId来起隔离作用。

packageName:即yaml文件中定义的androidPackage,这个也是生成flutter aar的groupId

buildVersion:要打包的aar版本号,每次升级在这里修改版本号,也是maven中的version,通过在文件里显示定义,也能更好的起到记录作用。

mavenRepository:发布Release版本要上传的仓库地址

mavenSnapshots:发布Debug版本要上传的仓库地址,因为debug版本的发布频繁,因此使用snapshots来管理。

配置文件做好后,创建一个名为packageHelper.sh的文件,文件内容如下,我把关键节点用注解的方式标注在了脚本中:

代码语言:javascript复制
#!/bin/bash
# shellcheck disable=SC2086
# shellcheck disable=SC2001
# shellcheck disable=SC2005
# shellcheck disable=SC2016
​
#引入配置文件
PROPERTIES="package.properties"
#maven依赖三要素
packageNameV=""
projectNameV=""
buildVersionV=""
​
#maven仓库地址
mavenRepositoryV=""
mavenSnapshotsV=""
​
#是否为release版本
isRelease=$1
​
#当前使用的仓库,根据isRelease的不同而不同
usedMavenRepo=""
​
#读取配置文件信息并做容错处理
if [ -f "$PROPERTIES" ]
then
  . $PROPERTIES
  packageNameV=$packageName
  projectNameV=$projectName
  buildVersionV=$buildVersion
​
  if [ -z "$packageNameV" ]; then
      echo ERROR:"package.properties文件中没有配置packageName!"
      exit 1
  fi
​
  if [ -z "$projectNameV" ]; then
      echo ERROR:"package.properties文件中没有配置projectName!"
      exit 1
  fi
​
  if [ -z "$buildVersionV" ]; then
      echo ERROR:"package.properties文件中没有配置buildVersion!"
      exit 1
  fi
​
  mavenRepositoryV=$mavenRepository
  mavenSnapshotsV=$mavenSnapshots
​
  if [[ -z "$mavenRepositoryV" ]] && [[ -z "$mavenSnapshotsV" ]]
  then
    echo ERROR:"请检查是否在package.properties中正确配置了maven仓库信息!"
      exit 1
  fi
else
  echo ERROR:"请先根据要求配置package.properties文件然后执行该脚本!"
  exit 1
fi
​
#根据是否为release版来确定使用的仓库地址
if [ $isRelease = "true" ]
then
  usedMavenRepo=$mavenRepositoryV
  echo "当前打包Release版本,版本号:$buildVersion,running..."
else
  usedMavenRepo=$mavenSnapshotsV
  echo "当前打包Debug版本,版本号固定为1.0-SNAPSHOT,running..."
fi
​
#如果不是release版本,则版本号强行指定为1.0-SNAPSHOT
showBuildVersion=1.0-SNAPSHOT
​
#打包前清理
echo "flutter clear..."
flutter clean
​
#打包前获取依赖
echo "flutter pub get..."
flutter pub get
​
echo "flutter pub get..."
​
#根据isRelease执行不同的打包逻辑
if [ $isRelease = "true" ]
then
  showBuildVersion=$buildVersionV
  #打包release版本,避免生成多余的包导致资源浪费
  flutter build aar --target-platform android-arm --no-profile --no-debug --build-number "$showBuildVersion"
else
  #打包debug版本,避免生成多余的包导致资源浪费
  flutter build aar --target-platform android-arm --no-profile --no-release --build-number "$showBuildVersion"
fi
​
echo "aar打包完成,开始上传maven..."
​
#方法 修改所有pom文件的名称
function renameAllPomArtifactId() {
  find build/host/outputs/repo -name "*.pom" | while read -r file
  do
    sed -i -e "s/>$1</>$2</g" $file
  done
}
​
​
#第一次遍历repo文件夹下所有后缀名为.aar的文件
find build/host/outputs/repo -name "*.aar" | while read -r file
do
  #当前aar文件所在的目录
  currDirName=$(dirname $file)
  aarName=$file
  #当前aar文件对应的pom文件(aar和pom一一对应)
  pomName="$currDirName/$(basename $file .aar).pom"
​
  #从pom文件中读取出groupId信息
  groupId=$(awk '/<groupId>[^<] </groupId>/{gsub(/<groupId>|</groupId>/,"",$1);print $1;exit;}' $pomName)
  #从pom文件中读取出artifactId信息,但是此时的artifactId并不是我们在properties中配置的,而是编译器自动生成的
  artifactId=$(awk '/<artifactId>[^<] </artifactId>/{gsub(/<artifactId>|</artifactId>/,"",$1);print $1;exit;}' $pomName)
​
  #修改artifactId为在properties中配置的
  renameAllPomArtifactId $artifactId $projectName
done
​
#第二次遍历repo文件夹下所有后缀名为.aar的文件,为什么要二次遍历?
#为了防止pom中的artifactId还没有全部修改完便被上传到maven引起的问题
find build/host/outputs/repo -name "*.aar" | while read -r file
do
  #当前aar文件所在的目录
  currDirName=$(dirname $file)
  aarName=$file
  #当前aar文件对应的pom文件(aar和pom一一对应)
  pomName="$currDirName/$(basename $file .aar).pom"
​
  #从pom文件中读取出groupId信息
  groupId=$(awk '/<groupId>[^<] </groupId>/{gsub(/<groupId>|</groupId>/,"",$1);print $1;exit;}' $pomName)
  #从pom文件中读取出artifactId信息,此时已经修改为properties中配置的
  artifactId=$(awk '/<artifactId>[^<] </artifactId>/{gsub(/<artifactId>|</artifactId>/,"",$1);print $1;exit;}' $pomName)
​
  echo "正在上传 = $aarName ..."
​
  #执行上传maven仓库命令
  mvn deploy:deploy-file 
  -DgroupId=$groupId 
  -DartifactId=$projectName 
  -Dpackaging=aar 
  -Dversion=$showBuildVersion 
  -Dfile=$aarName 
  -DpomFile=$pomName 
  -Durl=$usedMavenRepo
​
done
​
#所有操作完成后给一个友善的提示
function finishEcho() {
    echo "
上传完毕!请通过如下方式引入Flutter模块到宿主项目中:
      1. 打开宿主项目根目录build.gradle文件并添加如下引用:
​
      String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ?: "https://storage.googleapis.com"
      repositories {
        repositories {
            //TODO 删除maven仓库url中配置的账号密码信息
            maven { url "$1" }
        }
        maven {
            url "$storageUrl/download.flutter.io"
        }
      }
​
      2. 在使用到Flutter的模中添加如下依赖:
​
      dependencies {
        debugImplementation '$2:$3:$4'
        //or
        releaseImplementation '$2:$3:$4'
      }
​
      3. 同步项目,完成Flutter模块的依赖。
      "
}
​
finishEcho $usedMavenRepo $packageNameV $projectName $showBuildVersion
​
复制代码

引入后项目结构如下:

在根目录下运行命令:

代码语言:javascript复制
//打包debug版本 不传参数默认为debug版本
./packageHelper.sh false 
//打包release版本
./packageHelper.sh true
复制代码

Tips:注意packageHelper.sh文件是否有运行权限

最后结果如下:

最后,就可以在宿主工程中愉快的引入flutter模块的依赖了~

Demo地址:flutter_aar_upload,赶快试试吧~

0 人点赞