前言
这段时间用 Flutter 做了一个开源的项目 VVEX, 因为需要打包 apk,在此之前一直是手动 flutter build apk,再把文件上传到 release,每次发布新版本确实有点繁琐。趁着有空来使用 Github Action 做个持续化集成,自动打包 apk。
最后完成的自动化构建脚本如下:
更新: 5月谷歌发布了Flutter stable 3.10.0 版本,可能会出现插件不兼容情况,需要将 yml 文件中flutter对应 channel
改为 any
,flutter-version
需要指定为某一版本,以确保打包环境正常。
为了方便阅读,部分 step 的 name 都使用了中文命名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
| name: build_apk
on: push: tag: - v*
jobs: build_apk: runs-on: ubuntu-latest
steps: - name: 代码迁出 uses: actions/checkout@v3
- name: 构建Java环境 uses: actions/setup-java@v3 with: distribution: "zulu" java-version: "17" token: ${{secrets.GIT_TOKEN}}
- name: 检查缓存 uses: actions/cache@v2 id: cache-flutter with: path: /root/flutter-sdk key: ${{ runner.os }}-flutter-${{ hashFiles('**/pubspec.lock') }}
- name: 安装Flutter if: steps.cache-flutter.outputs.cache-hit != 'true' uses: subosito/flutter-action@v2 with: flutter-version: 3.7.7 channel: any
- name: 下载项目依赖 run: flutter pub get
- name: 解码生成 jks run: echo $KEYSTORE_BASE64 | base64 -di > android/app/vvex.jks env: KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }}
- name: flutter build apk run: flutter build apk --release --split-per-abi env: KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} KEY_ALIAS: ${{ secrets.KEY_ALIAS }} KEY_PASSWORD: ${{ secrets.KEY_PASSWORD}}
- name: 发布 uses: ncipollo/release-action@v1 with: artifacts: "build/app/outputs/flutter-apk/app-*.apk" token: ${{ secrets.GIT_TOKEN }} allowUpdates: true
|
在此处有两点需要特别注意一下:
无签名打包
在使用 GitHub 完成自动化构建之前,一直使用的是无签名打包,很简单,不需要额外配置什么
无签名打包的脚本需要去掉上面的这部分内容
1 2 3 4 5 6 7 8 9 10 11
| - name: 解码生成 jks run: echo $KEYSTORE_BASE64 | base64 -di > android/app/vvex.jks env: KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }}
- name: flutter build apk run: flutter build apk --release --split-per-abi env: KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} KEY_ALIAS: ${{ secrets.KEY_ALIAS }} KEY_PASSWORD: ${{ secrets.KEY_PASSWORD}}
|
以下部分需要保留
1 2
| - name: flutter build apk run: flutter build apk --release --split-per-abi
|
带签名打包
签名文件 xxx.js 跟 xxx.properties 文件不要提交至公共仓库
主要分下面几步
- 生成签名 jks 文件:比如 vvex.jks
- 创建 key.properties 文件
- 修改 build.gradle 文件
- Github 配置 action secrets
生成签名文件
此处及以下以 VVEX 举例 Mac 环境
1 2 3 4 5 6 7
| cd desktop
mkdir jks cd jks
keytool -genkeypair -alias vvex -keyalg RSA -keysize 2048 -keypass password -keystore vvex.jks -storepass password -validity 10000
|
说明:
- -alias vvex 此处的 vvex 可以自定义修改为任意
- -keystore vvex.jks 此处的 vvex 可以自定义修改为任,建议与别名相同
- 建议以上 vvex 为相同内容
- -keypass password 此处的 password 设置密钥密码
- -storepass password 此处的 password 设置密钥库密码
- 建议以上 password 为相同内容
vvex.jks 文件生成完成后,复制至 android/app 目录下
至此,第一步完成
创建 key.properties 文件
1 2 3 4 5 6 7 8 9
|
storePassword = password
keyPassword = password
keyAlias = vvex
storeFile = vvex.jks
|
key.properties 文件生成完成后,复制至 android 目录下
至此,第一步完成
修改 build.gradle 文件
android/app 目录下的 build.gradle 文件增加以下内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| def keystorePropertiesFile = rootProject.file('key.properties') def keystoreProperties = new Properties() if (keystorePropertiesFile.exists()) { keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) }
def _storeFile = file(System.getenv("KEYSTORE") ?: keystoreProperties["storeFile"] ?: "vvex.jks") def _storePassword = System.getenv("KEYSTORE_PASSWORD") ?: keystoreProperties["storePassword"] def _keyAlias = System.getenv("KEY_ALIAS") ?: keystoreProperties["keyAlias"] def _keyPassword = System.getenv("KEY_PASSWORD") ?: keystoreProperties["keyPassword"]
android { ... ... signingConfigs { release { storeFile _storeFile storePassword _storePassword keyAlias _keyAlias keyPassword _keyPassword v1SigningEnabled true v2SigningEnabled true } }
buildTypes { release { signingConfig signingConfigs.release } } }
|
其中 大写字符 KEYSTORE_PASSWORD、KEY_ALIAS、KEY_PASSWORD 在 github 设置secrets时会用到
Github 配置 action secrets
- 打开远程仓库的设置页面(用户名及仓库名记得替换为自己的)
1
| https://github.com/guozhigq/flutter_test/settings/secrets/actions
|
- 点击右上方 【New repository secret】
- 依次创建 Actions secrets
name |
Secret |
说明 |
KEYSTORE_BASE64 |
base64 |
vvex.jks base64 编码 |
KEY_ALIAS |
vvex |
-alias vvex处的 vvex |
KEY_PASSWORD |
password |
-keypass password处的 password |
KEYSTORE_PASSWORD |
password |
-storepass password处的 password |
KEY_PROPERTIES |
base64 |
key.properties base64 编码 |
GIT_TOKEN |
字符串 |
github 设置中生成 |
如何对 vvex.jks、key.properties 进行 base64 编码
方便起见,将 key.properties 复制到 desktop/jks 文件夹下
1 2 3
| base64 vvex.jks | pbcopy base64 key.properties | pbcopy
|
如何生成 GIT_TOKEN
打开 tokens 设置页面