Flutter实战:Github Actions自动构建APK,分发到Github Release

是什么

Github Actions

GitHub Actions 是 GitHub 的持续集成和持续部署(CI/CD)平台,允许用户自动化他们的构建、测试和部署工作流程。通过在 GitHub 仓库中创建工作流程,开发者可以在每次提交代码、创建拉取请求(PR)、或者定义的其他事件发生时自动运行这些工作流程。

GitHub Actions 的工作流程是通过 YAML 文件定义的,这些文件位于仓库的 .github/workflows 目录中。

Github Release

GitHub Release 是 GitHub 提供的一个功能,它允许项目维护者和开发者将软件的特定状态作为"发布版"(Release)标记和管理。这通常用于分发项目的特定版本给最终用户,包括编译好的二进制文件、源代码压缩包和其他相关资料。

正常github代码托管和版本控制,仓库不上传保存构建产物,原因有体积大、diff不了、构建产物多变等。所以提供了Release的方式发布构建产物。对于静态网站,github还提供了github page托管。

触发条件

Release作为稳定的分发版本,建议与Tag相对应。

打tag才算是完整的版号。v1.0.0, v0.1.0-beta.1, v0.1.0-alpha.1

yaml 复制代码
on:
  push:
    tags:
      - 'v*.*.*-*' # This will match tags like v1.0.0, v0.1.0-beta.1, v0.1.0-alpha.1

构建环境设置

运行环境设置为ubuntu-latest 通过 java --version 获取本地构建的JDK版本。

yaml 复制代码
jobs:
  build:
    # This job will run on ubuntu virtual machine
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'adopt'

创建依赖文件

一些不允许公开的信息(比如:远端服务器的Key、jks文件的密码),yml文件如何获取。可以预先维护在Github > settings > Secrets and variables > Actions > * secrets 中,就可以通过 ${{ secrets.* }} 获取。

yaml 复制代码
#...
      - name: Create Keystore Properties
        run: |
          echo "storePassword=${{ secrets.STORE_PASSWORD }}" > key.properties
          echo "keyPassword=${{ secrets.KEY_PASSWORD }}" >> key.properties
          echo "keyAlias=${{ secrets.KEY_ALIAS }}" >> key.properties
          echo "storeFile=../upload-keystore.jks" >> key.properties
          ls -laq
          cat key.properties
        working-directory: android
#...

JKS文件则,将文件转换成base64格式,使用时候decode成文件即可。

yaml 复制代码
#...
      - name: Decode Keystore
        run: echo ${{ secrets.KEY_STORE_BASE64 }} | base64 --decode > android/upload-keystore.jks
#...

构建

至此,前置的依赖设置完毕。正常执行 flutter build apk --split-per-abi 后,就能在该环境下看到构建的产物,而后我们需要发布到Github Release上。

创建Release

后续针对Github openapi进行调用,需要申请Github 授权token才有权限操作。

申请 Github token 个人头像 > settings > developer settings > personal access tokens

使用tag name作为release name,方便对应版本。release有是否存为draft 和设置pre字段,就直接发布不存draft,pre可以根据是否包含-beta等字段判断。body作为release发布的描述,由于获取tag msg较麻烦,直接使用当前tag commit msg,如果是feature功能合入main,再打tag,commit msg也合适作为release更新信息。

通过id将操作返回提供给下一个步骤。

yaml 复制代码
#...
      - name: Create Release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.AUTH_TOKEN }}
        with:
          tag_name: ${{ github.ref_name }}
          release_name: ${{ github.ref_name }}
          draft: false
          prerelease: ${{ contains(github.ref, '-alpha') || contains(github.ref, '-beta') }}
          body: ${{ github.event.head_commit.message }}
#...

上传到Release

这里只给出了一个apk的上传。

yaml 复制代码
      - name: Upload arm64-v8a Release Asset 
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.AUTH_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./build/app/outputs/flutter-apk/app-arm64-v8a-release.apk
          asset_name: app-arm64-v8a-release.apk
          asset_content_type: application/vnd.android.package-archive

最终代码文件

yaml 复制代码
name: Flutter CI

# This workflow is triggered on pushes to the repository.

on:
  push:
    tags:
      - 'v*.*.*-*' # This will match tags like v1.0.0, v0.1.0-beta.1, v0.1.0-alpha.1, etc.
    
# on: push    # Default will running for every branch.
    
jobs:
  build:
    # This job will run on ubuntu virtual machine
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'adopt'

      - name: Create Keystore Properties
        run: |
          echo "storePassword=${{ secrets.STORE_PASSWORD }}" > key.properties
          echo "keyPassword=${{ secrets.KEY_PASSWORD }}" >> key.properties
          echo "keyAlias=${{ secrets.KEY_ALIAS }}" >> key.properties
          echo "storeFile=../upload-keystore.jks" >> key.properties
          ls -laq
          cat key.properties
        working-directory: android

      - name: Decode Keystore
        run: echo ${{ secrets.KEY_STORE_BASE64 }} | base64 --decode > android/upload-keystore.jks
      
      - name: Ls Android Directory
        run: ls -laq
        working-directory: android
      
      - name: Install Flutter
        uses: subosito/flutter-action@v1
        with:
          flutter-version: '3.19.0'
          
      - name: Get dependencies
        run: flutter pub get
   
      - name: Build APK
        run: flutter build apk --split-per-abi

      - name: Ls output directory
        run: ls -laq build/app/outputs/flutter-apk/

      - name: Create Release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.AUTH_TOKEN }}
        with:
          tag_name: ${{ github.ref_name }}
          release_name: ${{ github.ref_name }}
          draft: false
          prerelease: ${{ contains(github.ref, '-alpha') || contains(github.ref, '-beta') }}
          body: ${{ github.event.head_commit.message }}

      - name: Upload arm64-v8a Release Asset 
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.AUTH_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./build/app/outputs/flutter-apk/app-arm64-v8a-release.apk
          asset_name: app-arm64-v8a-release.apk
          asset_content_type: application/vnd.android.package-archive
      
      - name: Upload armeabi-v7a Release Asset 
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.AUTH_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk
          asset_name: app-armeabi-v7a-release.apk
          asset_content_type: application/vnd.android.package-archive

      - name: Upload x86_64 Release Asset 
        uses: actions/upload-release-asset@v1
        env:
          GITHUB_TOKEN: ${{ secrets.AUTH_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./build/app/outputs/flutter-apk/app-x86_64-release.apk
          asset_name: app-x86_64-release.apk
          asset_content_type: application/vnd.android.package-archive
  
  
相关推荐
王哈哈^_^1 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie1 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic2 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿2 小时前
webWorker基本用法
前端·javascript·vue.js
cy玩具3 小时前
点击评论详情,跳到评论页面,携带对象参数写法:
前端
qq_390161773 小时前
防抖函数--应用场景及示例
前端·javascript
John.liu_Test4 小时前
js下载excel示例demo
前端·javascript·excel
Yaml44 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事4 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro
哟哟耶耶4 小时前
js-将JavaScript对象或值转换为JSON字符串 JSON.stringify(this.SelectDataListCourse)
前端·javascript·json