こんにちは、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のバージョンごとで問題が発生するかもしれません。 その場合は、今回紹介した方法を選択するのも良いかと思います!
ここまで読んでいただき、ありがとうございました!