こんにちは、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で行なっています。
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ファイルをおくことが必須になると思います。
それでは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で書き換えてください。
上記のコマンドをスクリプト化します。(今回は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;
}
これで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://$
上記のSBT credentialsとSetup GitステップをDeployステップより前に設定します。
保管用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"
}
}
上記のコードを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のバージョンごとで問題が発生するかもしれません。 その場合は、今回紹介した方法を選択するのも良いかと思います!
ここまで読んでいただき、ありがとうございました!
興味のある方は 採用ページ も見ていただけると嬉しいです。
Twitter @mot_techtalk のフォローもよろしくお願いします!