Flutter 使用 Github Action 來 Build APK、AAB


#Github Action#Github#Flutter#APK#AAB#Android

使用原因


因為個人 Mac 是 M1 記憶體也只有 8G,空間又不足,每次 Build 都會跑到電腦很 Lag,所以轉用 Github Action 來 Build,避免電腦一堆垃圾與佔用記憶體。

Guthub 免費提供每月 2000 分鐘的額度,可以從 Actions Usage Metrics 觀看使用量。

Plan Artifact storage Minutes (per month) Cache storage
GitHub Free 500 MB 2,000 10 GB
GitHub Pro 1 GB 3,000 10 GB
GitHub Free for organizations 500 MB 2,000 10 GB
GitHub Team 2 GB 3,000 10 GB
GitHub Enterprise Cloud 50 GB 50,000 10 GB

Workflow


路徑

.github/workflows/xxx.yml ,一個 xxx.yml 檔,就是一個工作流程,一個專案可以一次設定多個 workflow。


GitHub Personal Access Token 設定

要使用 Action 上傳到 Github Release 就必須先設定一組 Token,產生方式為 右上角點你的頭像 > Settings > Developer settings > Personal access tokens > Tokens (classic) > Generate new token (classic),勾選 repowrite:packages 產生。


Secrets 設定

Secrets 是用來將 .jks、Token、等機敏資料加密存在 Github,使用到時再讀出來使用,避免把機敏資料上到 Git Commit。
一個 Secret 可從 GitHub Repository > Settings > Secrets and variables > Actions > New repository secret 新增即可在 .yml 內使用 ${{ secrets.KEY }} 替代。

Secret 名稱 用途說明
ID_RSA SFTP SSH Key
KEYSTORE_BASE64 Android keystore 的 Base64
KEY_ALIAS Keystore 的 Alias
KEY_PASSWORD Key 的密碼
STORE_PASSWORD Keystore 的密碼
PERSONAL_ACCESS_TOKEN GitHub Personal Access Token

yml 設定


  1. 設定觸發條件,有四位數 Tag 才觸發,避免每次 git push 就跑。
on:
  push:
    tags:
      - '*.*.*.*'
  1. 使用 ubuntu。
runs-on: ubuntu-latest
  1. 將用不到的東西移除,避免 build 空間不足。
- name: Free disk space
    run: |
        echo "Before cleanup"
        df -h

        sudo swapoff -a || true
        sudo rm -f /swapfile
        sudo rm -rf /usr/share/dotnet
        sudo rm -rf /opt/ghc
        sudo rm -rf /opt/hostedtoolcache

        sudo apt clean

        docker system prune -af || true

        echo "After cleanup"
        df -h
  1. 把 Source code 載入到 Runner
- name: Checkout code
    uses: actions/checkout@v4
  1. 安裝 Java
- name: Setup Java
    uses: actions/setup-java@v4
    with:
        distribution: 'temurin'
        java-version: '17'
  1. 安裝 Flutter
- name: Setup Flutter
    uses: subosito/flutter-action@v2
    with:
        flutter-version: '3.38.5'
  1. run flutter pub get
- name: Install dependencies
    run: flutter pub get
  1. 把存在 GitHub Secrets 的 keystore(Base64)還原成 .jks 檔
- name: Decode keystore
    run: |
    echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > android/app/upload-keystore.jks
  1. 建立 key.properties 設定檔
- name: Create key.properties
    run: |
    echo "storePassword=${{ secrets.STORE_PASSWORD }}" > android/key.properties
    echo "keyPassword=${{ secrets.KEY_PASSWORD }}" >> android/key.properties
    echo "keyAlias=${{ secrets.KEY_ALIAS }}" >> android/key.properties
    echo "storeFile=android/app/upload-keystore.jks" >> android/key.properties
  1. Build APK
- name: Build APK
    run: flutter build apk --release
  1. 將 APK 重新命名為 Git Tag 名稱,方便管理
- name: Rename APK
    run: mv build/app/outputs/flutter-apk/app-release.apk build/app/outputs/flutter-apk/${{ github.ref_name }}.apk
  1. 將 APK 上傳到 GitHub Release,發佈檔案,就可以在 Github Release 看到頁面看到:https://github.com/MTsung/{repository_name}/releases/tag/{x.x.x.x}
- name: Upload to GitHub Release
    uses: softprops/action-gh-release@v1
    with:
        tag_name: ${{ github.ref_name }}
        name: Release ${{ github.ref_name }}
        files: |
            build/app/outputs/flutter-apk/${{ github.ref_name }}.apk
    env:
        GITHUB_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
  1. 若有 SFTP 上傳需求可加上
- name: SFTP to Server
    uses: appleboy/scp-action@v1
    with:
        host: exexample.com.tw
        port: 2222
        username: git
        key: ${{ secrets.ID_RSA }}
        source: "build/app/outputs/flutter-apk/${{ github.ref_name }}.apk"
        strip_components: 4
        target: "/home/web/your-path"
  • 若要 build aab 只要把第 10 步改成 flutter build appbundle --release,重新命名、上傳附檔名都改 .aab 即可。

參考:
https://docs.github.com/en/billing/concepts/product-billing/github-actions