こんにちは、Mobility TechnologiesでFlutterエンジニアとして働いているTomiと申します。
以前ブログで書いた「Flutter moduleのAARをMaven + GitHub ActionsでGitHub Packagesにデプロイする」ではFlutter v3.3.0より前のバージョンで動作する方法を紹介しました。
今回はFlutter v3.3.0以降でも動作するFlutter moduleのAARをGitHubのレポジトリにデプロイする方法を解説します。
※ 今回の検証はFlutter v3.3.5で行なっています。
単語定義
事前準備
- AARを保存する保管用GitHubレポジトリを作っておく
- Personal access token発行する
- 発行方法(公式ドキュメント)
repo
権限が必要です
流れ
1. AARを生成する
Flutter moduleをAndroid側に組み込むためにAARを生成します。
flutter build aar
上のコマンドで実行すると/build/host/outputs/repo
に下記が生成されます。
. └── com └── example └── moduleproject ├── flutter │ ├── 1.0 │ │ ├── flutter-1.0-debug.aar │ │ ├── flutter-1.0-debug.aar.md5 │ │ ├── flutter-1.0-debug.aar.sha1 │ │ ├── flutter-1.0-debug.aar.sha256 │ │ ├── flutter-1.0-debug.aar.sha512 │ │ ├── flutter-1.0-profile.aar │ │ ├── flutter-1.0-profile.aar.md5 │ │ ├── flutter-1.0-profile.aar.sha1 │ │ ├── flutter-1.0-profile.aar.sha256 │ │ ├── flutter-1.0-profile.aar.sha512 │ │ ├── flutter-1.0-release.aar │ │ ├── flutter-1.0-release.aar.md5 │ │ ├── flutter-1.0-release.aar.sha1 │ │ ├── flutter-1.0-release.aar.sha256 │ │ ├── flutter-1.0-release.aar.sha512 │ │ ├── flutter-1.0.module │ │ ├── flutter-1.0.module.md5 │ │ ├── flutter-1.0.module.sha1 │ │ ├── flutter-1.0.module.sha256 │ │ ├── flutter-1.0.module.sha512 │ │ ├── flutter-1.0.pom │ │ ├── flutter-1.0.pom.md5 │ │ ├── flutter-1.0.pom.sha1 │ │ ├── flutter-1.0.pom.sha256 │ │ └── flutter-1.0.pom.sha512 │ ├── maven-metadata.xml │ ├── maven-metadata.xml.md5 │ ├── maven-metadata.xml.sha1 │ ├── maven-metadata.xml.sha256 │ └── maven-metadata.xml.sha512 ├── flutter_debug │ ├── 1.0 │ │ ├── flutter_debug-1.0.aar │ │ ├── flutter_debug-1.0.aar.md5 │ │ ├── flutter_debug-1.0.aar.sha1 │ │ ├── flutter_debug-1.0.aar.sha256 │ │ ├── flutter_debug-1.0.aar.sha512 │ │ ├── flutter_debug-1.0.module │ │ ├── flutter_debug-1.0.module.md5 │ │ ├── flutter_debug-1.0.module.sha1 │ │ ├── flutter_debug-1.0.module.sha256 │ │ ├── flutter_debug-1.0.module.sha512 │ │ ├── flutter_debug-1.0.pom │ │ ├── flutter_debug-1.0.pom.md5 │ │ ├── flutter_debug-1.0.pom.sha1 │ │ ├── flutter_debug-1.0.pom.sha256 │ │ └── flutter_debug-1.0.pom.sha512 │ ├── maven-metadata.xml │ ├── maven-metadata.xml.md5 │ ├── maven-metadata.xml.sha1 │ ├── maven-metadata.xml.sha256 │ └── maven-metadata.xml.sha512 ├── flutter_profile │ ├── 1.0 │ │ ├── flutter_profile-1.0.aar │ │ ├── flutter_profile-1.0.aar.md5 │ │ ├── flutter_profile-1.0.aar.sha1 │ │ ├── flutter_profile-1.0.aar.sha256 │ │ ├── flutter_profile-1.0.aar.sha512 │ │ ├── flutter_profile-1.0.module │ │ ├── flutter_profile-1.0.module.md5 │ │ ├── flutter_profile-1.0.module.sha1 │ │ ├── flutter_profile-1.0.module.sha256 │ │ ├── flutter_profile-1.0.module.sha512 │ │ ├── flutter_profile-1.0.pom │ │ ├── flutter_profile-1.0.pom.md5 │ │ ├── flutter_profile-1.0.pom.sha1 │ │ ├── flutter_profile-1.0.pom.sha256 │ │ └── flutter_profile-1.0.pom.sha512 │ ├── maven-metadata.xml │ ├── maven-metadata.xml.md5 │ ├── maven-metadata.xml.sha1 │ ├── maven-metadata.xml.sha256 │ └── maven-metadata.xml.sha512 └── flutter_release ├── 1.0 │ ├── flutter_release-1.0.aar │ ├── flutter_release-1.0.aar.md5 │ ├── flutter_release-1.0.aar.sha1 │ ├── flutter_release-1.0.aar.sha256 │ ├── flutter_release-1.0.aar.sha512 │ ├── flutter_release-1.0.module │ ├── flutter_release-1.0.module.md5 │ ├── flutter_release-1.0.module.sha1 │ ├── flutter_release-1.0.module.sha256 │ ├── flutter_release-1.0.module.sha512 │ ├── flutter_release-1.0.pom │ ├── flutter_release-1.0.pom.md5 │ ├── flutter_release-1.0.pom.sha1 │ ├── flutter_release-1.0.pom.sha256 │ └── flutter_release-1.0.pom.sha512 ├── maven-metadata.xml ├── maven-metadata.xml.md5 ├── maven-metadata.xml.sha1 ├── maven-metadata.xml.sha256 └── maven-metadata.xml.sha512
Androidプロジェクトのbuild.gradle
に記載することで、生成されたAARを組み込むことができます。
repositories { maven { url '/Users/username/project_path/build/host/outputs/repo' } maven { url '$storageUrl/download.flutter.io' } }
1人で開発するならローカルにあるAARファイルを使うこともありですが、チーム単位で開発する場合は、リモートにAARファイルをおくことが必須になると思います。
2. AARをpushする
それではAARファイルをリモート(保管用GitHubレポジトリ)にデプロイします。
// [1.] maven-repoディレクトリに既存にあるAARを持ってくる $ git clone --depth 1 https://gitHub.com/{owner}/{repository name}.git maven-repo // [2.] 既存にあるAAR(maven-repo)と新しく作ったAAR(build/host/outputs/repo/)を同期化する $ rsync -a build/host/outputs/repo/ maven-repo/ // [3.] 同期化されたAARをpushする $ cd maven-repo $ git add . $ git commit -m update $ git pull --rebase $ git push
※ https://github.com/{owner}/{repository name}.git
: 保管用GitHubレポジトのURLで書き換えてください。
maven-repo
というディレクトリを作っておいて保管用GitHubレポジトリをclone
しておきます。clone
したディレクトリ(push
したことがあれば)に新しくビルドしたAARを書き換えします。- 書き換えたAARを保管用Githubレポジトリに
push
します。
上記のコマンドをスクリプト化します。(今回はFlutterの記事なのでDartでスクリプトを書きました)
import 'dart:io'; const _githubUrl = 'https://github.com/{owner}/{repository name}.git'; const _directory = 'maven-repo'; const _repoPath = 'build/host/outputs/repo/'; void main(List<String> arguments) async { await _process('git clone --depth 1 $_githubUrl $_directory'); await _process('rsync -a $_repoPath $_directory/'); await _process('git add .', workingDirectory: _directory); // 変更がある場合 if (await _hasChanged()) { await _process('git commit -m update', workingDirectory: _directory); await _process('git pull --rebase', workingDirectory: _directory); await _process('git push', workingDirectory: _directory); } } Future<bool> _hasChanged() async { final gitDiffProgress = await _process( 'git diff --quiet HEAD', shouldIgnoreError: true, workingDirectory: _directory, ); return gitDiffProgress.exitCode != 0; } Future<ProcessResult> _process(String command, { String? workingDirectory, bool shouldIgnoreError = false, }) async { final splitCommands = command.split(' '); final executable = splitCommands.first; final arguments = splitCommands.length > 1 ? splitCommands.sublist(1) : < String>[]; final process = await Process.run( executable, arguments, workingDirectory: workingDirectory, ); if (!shouldIgnoreError && process.exitCode != 0) { throw Exception(process.stderr); } return process; }
_githubUrl
: こちらに保管用GitHubレポジトリのURLを入れてください。
これでGitHub Actionsで使用するものの準備が整いました。
3. GitHub Actionsを使って自動化する
name: deploy on: push: branches: - main jobs: build-and-deploy: runs-on: ubuntu-latest timeout-minutes: 10 permissions: contents: read packages: write steps: - name: Checkout code uses: actions/checkout@v3 - name: flutter action uses: subosito/flutter-action@v2 - name: Add path run: echo "$(pwd)/flutter/bin" >> $GITHUB_PATH - name: Get dependencies run: flutter pub get - name: build aar run: | flutter build aar - name: SBT credentials run: | mkdir -p ~/.sbt cat > ~/.sbt/.credentials <<EOL realm= host=raw.githubusercontent.com user=_ password=${{ secrets.MACHINE_USER_PAT }} EOL - name: Setup git run: | git config --global user.name github-actions git config --global user.email github-actions@github.com git config --global url."https://${{ secrets.MACHINE_USER_PAT }}:x-oauth-basic@github.com/".insteadOf "https://github.com/" - name: Deploy to maven-repo run: | dart run bin/deploy_script.dart
上記のyaml
ファイルを設定しておくとmain
ブランチをpush
した際に、GitHub Actionsが動いてAARが生成され、保管用GitHubレポジトリにpush
されます。
- name: Deploy run: | dart run bin/deploy_script.dart
こちらは「2. AARをpushする」で作成したスクリプトを実行するstepです。このスクリプトにはGitを使ってリモートにpush
するコマンドが含まれているため、Gitの認証情報が必要です。
- name: SBT credentials run: | mkdir -p ~/.sbt cat > ~/.sbt/.credentials <<EOL realm= host=raw.githubusercontent.com user=_ password=${{ secrets.MACHINE_USER_PAT }} EOL - name: Setup git run: | git config --global user.name username git config --global user.email github-actions@github.com git config --global url."https://$
secrets.MACHINE_USER_PAT
- 事前準備で生成した
Personal access token
です。
- 事前準備で生成した
上記のSBT credentialsとSetup GitステップをDeployステップより前に設定します。
4. Android側で保管用GitHubレポジトリを参照して依存性を取得する
保管用GitHubレポジトリから依存性を取得する前にMavenの設定が必要です。
String storageUrl = System.env.FLUTTER_STORAGE_BASE_URL ?: "https://storage.googleapis.com" repositories { maven { name = "GitHubPackages" url = uri("https://raw.githubusercontent.com/{owner}/{保管用レポジトリ名}/{brunch名}/") credentials { username = {owner} password = {token} } authentication { basic(BasicAuthentication) } } maven { url "$storageUrl/download.flutter.io" } }
https://raw.githubusercontent.com/{owner}/{保管用レポジトリ名}/{brunch}/
保管用GitHubレポジトリのURLを入力してください。
{owner}
- GitHubのOwner名
{token}
- 事前に準備したPersonal access tokenを入力してください。
上記のコードをandroidプロジェクトのapp/build.gradle
に記載しておくと、保管用GitHubレポジトリにあるAARを取得することができます。
dependencies { debugImplementation 'com.example.app:flutter_debug:1.0.0' profileImplementation 'com.example.app:flutter_profile:1.0.0' releaseImplementation 'com.example.app:flutter_release:1.0.0' }
Android側で依存性を取得してFlutter moduleを使うことができるようになりました。
おわり
今回解説した方法はFlutterバージョンの影響を受けないメリットがありますが、バージョンが増えるほどデプロイ時間が伸びるデメリットもあります。
個人的にはGitHub Packagesにデプロイする方が良いと思います。 しかしながら、Add-to-appの機能に関しては、Flutter側の優先順位が高くなさそうなので、引き続きFlutterのバージョンごとで問題が発生するかもしれません。 その場合は、今回紹介した方法を選択するのも良いかと思います!
ここまで読んでいただき、ありがとうございました!