🎶

FlutterとGitHub Actionsでマルチビルドやってみた

2022/11/10に公開

お約束

この記事はmediba Advent Calendar 2022の二日目にエントリされた記事です

medibaのテクノロジーセンターでアプリエンジニア(という名の雑用)をやっています、佐藤よしあきです
最近は殆どコード書かずに調査や調整ばっかりやってます

何を作ったの

社内のちょっとした要求で[すごい量のURLをまとめてQRCodeにしたい]と言われまして、どうせなら(※)デスクトップアプリとして閉じた環境で使えたらいいなーと思い、Flutterで作成しました
※ 一回だけでいいなら npx qrcode をぶん回すスクリプト書いて結果だけ渡してたと思うけど、継続して使う用途だったので

せっかくならと、GitHub Actionsでバイナリをデプロイする仕組みを作りました

んでMac向けのバイナリ作って渡そうとしたら「Windowsです」
んでWindows向けバイナリ作って渡そうとしたら「セキュリティ要件で .exe 実行できません」
最終的にWebアプリにしてデプロイすることになりました

結果として、Windows/Mac/Webビルドを生成するGitHub Actionsが残りました
もったいないので公開します

成果物

Flutterプロジェクトの作り方

簡単で、 flutter create --platforms=windows,macos,web . として始めればいいだけです
あとから足すときも flutter create --platforms=<<足したいプラットフォーム名>> . とかすればいいらしいですが、こちらは試してないのでやるなら慎重にお願いします

コードの書き方とかはスマホ向け開発と全部同じです
Android Studioで開発していましたが、特に出力先環境の差異とかで引っかかったり挙動の違いを踏んだりはしませんでした
※ ネイティブに近い領域やプラグインなどを殆ど使わず、簡単なStateProviderを使ってるくらいなものなので、引っかかるような要素が存在しなかっただけかもしれない

GitHub Actions

下記にActionsの .yaml を引用します、今実際に使ってるものです
それぞれのビルドが生成されるのはリリースが作られたタイミングなので、タグを打った時に動きます
生成される .zip のファイル名を直接書いているので、出来るものに合わせて適当に変えてやって下さい

# https://angeloavv.medium.com/how-to-distribute-flutter-desktop-app-binaries-using-github-actions-f8d0f9be4d6b

name: make release packages

on: push

jobs:

  build-and-release-windows:
    runs-on: windows-latest

    steps:
      - uses: actions/checkout@v3
      - uses: subosito/flutter-action@v2
        with:
          channel: 'stable'
          cache: true
      - name: Install project dependencies
        run: flutter pub get
      - name: Generate intermediates
        run: flutter pub run build_runner build --delete-conflicting-outputs
      - name: Enable windows build
        run: flutter config --enable-windows-desktop
      - name: Build artifacts
        run: flutter build windows --release
      - name: Make windows release zip
        if: startsWith(github.ref, 'refs/tags/')
        uses: thedoctor0/zip-release@master
        with:
          type: 'zip'
          filename: qrmaker-windows.zip
          directory: build/windows/runner/Release
      - name: Windows Release
        uses: softprops/action-gh-release@v1
        if: startsWith(github.ref, 'refs/tags/')
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          files: build/windows/runner/Release/qrmaker-windows.zip

  build-and-release-macos:
    runs-on: macos-latest

    steps:
      - uses: actions/checkout@v3
      - uses: subosito/flutter-action@v2
        with:
          channel: 'stable'
          cache: true
      - name: Install project dependencies
        run: flutter pub get
      - name: Generate intermediates
        run: flutter pub run build_runner build --delete-conflicting-outputs
      - name: Enable macOS build
        run: flutter config --enable-macos-desktop
      - name: Build artifacts
        run: flutter build macos --release
      - name: Make macos release zip
        if: startsWith(github.ref, 'refs/tags/')
        uses: thedoctor0/zip-release@master
        with:
          type: 'zip'
          filename: qrmaker-macos.zip
          directory: build/macos/Build/Products/Release
      - name: macOS Release
        uses: softprops/action-gh-release@v1
        if: startsWith(github.ref, 'refs/tags/')
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          files: build/macos/Build/Products/Release/qrmaker-macos.zip

  build-and-release-web:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - uses: subosito/flutter-action@v2
        with:
          channel: 'stable'
          cache: true
      - name: Install project dependencies
        run: flutter pub get
      - name: Generate intermediates
        run: flutter pub run build_runner build --delete-conflicting-outputs
      - name: Enable web build
        run: flutter config --enable-web
      - name: Build artifacts
        run: flutter build web --release
      - name: Make web release zip
        if: startsWith(github.ref, 'refs/tags/')
        uses: thedoctor0/zip-release@master
        with:
          type: 'zip'
          filename: qrmaker-web.zip
          directory: build/web/
      - name: Web Release
        uses: softprops/action-gh-release@v1
        if: startsWith(github.ref, 'refs/tags/')
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          files: build/web/qrmaker-web.zip

コメントにある通り、 How to distribute Flutter Desktop app binaries using GitHub Actions を参考に作っています

お約束

medibaでは事業の拡大や多角化に当たって、幅広い職種を募集中です
様々なフィールドがありますので、一度お話を聞きに来てみて下さい
https://hrmos.co/pages/mediba/jobs

明日の担当は?

全分野を見れるテックリード、菅原さん です
二年前の菅原さんのアドカレ担当記事が、ちょうどGitHub Actions黎明期の記事だったりします
※ そういえばアクションがFailだった場合はどうする、みたいなの、書いたこと無いや

Discussion