保羅的學習筆記 / 開發日常 / 如何用 Github Action 建置 Flutter Android App
2021.08.15 · 9 min read
開發日常

如何用 Github Action 建置 Flutter Android App

手動建置與上傳 app 是一件滿麻煩的事情,在最理想的狀況下,我們希望當我們確保程式沒有問題之後,合併回主線就可以開始自動建置並上傳到 google play 上。為了達到這個目的,我使用 Github Action 來幫我建置 flutter app,今天就來分享一下我如何自動化這些麻煩事。

加入建置 Flutter 的 Step

透過使用第三方的 action:subosito/flutter-action,我們就可以使用 flutter 的命令來建置 flutter app。

yaml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-java@v1
        with:
          java-version: '12.x'
 	  - uses: subosito/flutter-action@v1
        with:
          channel: 'stable'
      - run: flutter pub get
      - run: flutter test
      - run: flutter build appbundle

當用這上面這段代碼去建置時,會發現因為缺少 keystore 檔案與 google-service.json 而建置失敗。這些檔案因為需要保密的緣故,所以並沒有上傳到 Github 的 repository 中。為此,我們必須想個辦法讓 Github 可以保存這些保密的檔案。

保密 keystore 與 google-service.json

由於這些 keystore 檔案和 google-service.json 裡面放著重要的資料,不能放在直接 git repository,以防被其他人拿到並盜用你的名義簽署 app 或者使用 google 服務。但是當你建構你的自動化 app 建置流程,這些檔案又是必不可少的,否則就會建置失敗。

為了在 github 上保密這些資料,github 也向其他各式各樣的 CI 工具一樣,提供了 secret 讓我們可以放一些重要的資料,例如:DB 的連線字串、API 的 token ...等等。但是 secret 目前是提供以文字形式的方式儲存這些保密資料,所以我們必須把 keystore 檔案和 google-services.json 檔轉換成文字形式,然後才能放到 secret 中。

  1. 在 local 端把檔案轉換成 base64 的格式
    bash
    openssl base64 -in your-input-file -out your-output-file
  2. 把轉換出來的 base64 文字加到 Github Secret 中,同時也把
    Article image
  3. 把 base64 文字在 step 中轉回檔案,如此一來,建置時就能拿到這些重要檔案
    yaml
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
    	  ...
    	  - run: echo $ANDROID_KEY_STORE | base64 -di > android/app/key.jks
      		env:
        		ANDROID_KEY_STORE: ${{ secrets.ANDROID_KEY_STORE }}
    	  - run: echo $GOOGLE_SERVICE | base64 -di > android/app/google-services.jon
      		env:
        		GOOGLE_SERVICE: ${{ secrets.GOOGLE_SERVICE }}
    	  ...

保密其他重要資料

除了 keystore 外,還有重要的資料,像是 store password, key password, key alias,我們也需要一起放進 secret 中,讓建置時可以從 secret 中拿到這些資料。

Article image

修改 github action,在建置時把這些 secret 放進環境變數中

yaml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      ...
      - run: flutter build appbundle
	  	env:
  		  KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
  		  KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
  		  STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}

最後修改 build.gradle,build.gradle 從環境變數中使用這些資料。

plain text
signingConfigs {
	release {
 		storeFile = file("key.jks")
 		storePassword System.getenv("STORE_PASSWORD")
 		keyAlias System.getenv("KEY_ALIAS")
 		keyPassword System.getenv("KEY_PASSWORD")
 	}
}

當以上都做完之後,Github Action 就能正常的建置出 flutter android app 了。

下載建置出來的 app

當建置完成後,檔案實際上還是存在 Github Action 的 Runner 中。為了拿到最後建置出來的檔案,我們必須再加上一個 step,把檔案上傳到 artifact 中。這樣我們就在建置完成之後,就能從 Github 網頁上下載到剛剛建置的檔案。

yaml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      ...
	  - name: upload appbundle
  		uses: actions/upload-artifact@v2
  		with:
    	  name: app bundle
    	  path: build/app/outputs/bundle/release/app-release.aab

下一步

把 app 建置出來並放到 artifact 後,我們就能從 github 上下載到 app,把這個 app 上傳到 google play 的後台,讓 user 可以下載。可以發現後面我們還是需要手動上傳到 google play,為了也把這段自動化,我會在下一篇中紀錄如何把 app 自動上傳到 google play 上。

參考

讀完了?

如果這篇對你有幫助,可以分享給朋友,或追蹤後續更新。我在 Threads 也會貼一些零碎想法。

Paul Wu

Paul Wu

Driven by a love for figuring things out and creating seamless experiences.
Always curious, exploring — from fresh concepts to unexpected rabbit holes.

看更多 ↗