rensawamo / flavor-fastlane

flavor(flutter_flavorizr)とfastlaneをつかった iOS と anoroidの 自動配布

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

flavor(flutter_flavorizr)とfastlaneをつかった iOS と anoroidの 自動配布

fvnを使用

fvm list
fvm use 上記ver

pubspec.yaml の dev_dependencies に以下を追記しプロジェクトに追加

flutter_flavorizr:

pubspec.yamlの下に以下を追加

最近は dart defineに乗り換えているそちらを推奨

flavorizr:
  app:
    android:
      flavorDimensions: "flavor-type"

  flavors:
    development:
      app:
        name: "Development"
      android:
        applicationId: "com.YOURTEAMNAME.fastlane.flavor.dev"
      ios:
        bundleId: "com.YOURTEAMNAME.fastlaneFlavor.dev"

    staging:
      app:
        name: "Staging"
      android:
        applicationId: "com.YOURTEAMNAME.fastlane.flavor.staging"
      ios:
        bundleId: "com.YOURTEAMNAME.fastlaneFlavor.staging"

    production:
      app:
        name: "Production"
      android:
        applicationId: "com.YOURTEAMNAME.fastlane.flavor.prod"
      ios:
        bundleId: "com.YOURTEAMNAME.fastlaneFlavor.prod"

以下コマンドを実行

 flutter pub run flutter_flavorizr

各フレーバーのビルド設定を行う

image

このライブラリの使用により xcodeでもフレーバの設定を自動追加できる image

image

Android

release設定

アップロードkeyの準備

プロジェクトファイルの andoroid/app で以下のコマンドを実行し証明書を作成する

alias_nameは覚えやすい名前にする

keytool -genkey -v -keystore release.jks -alias alias_name -keyalg RSA -keysize 2048 -validity 10000

github actionの環境変数で使うためエンコードしておく

 openssl base64 -in release.jks  -out release.pem 

android/keystore.propertiesを作成(local用)

storePassword=パスワード
keyPassword=パスワード
keyAlias=alias_name
storeFile=release.jks

android/app/build.gradeの編集

// android 設定の上
def keystorePropertiesFile = rootProject.file("keystore.properties")
android {
....
// defalutConfigの下
signingConfigs {
        release {
            if (System.getenv("GITHUB_ACTIONS")) { // gitaction用
                storeFile file("release.jks")
                storePassword System.getenv()["STORE_PASSWORD"]
                keyAlias System.getenv()["KEY_ALIAS"]
                keyPassword System.getenv()["KEY_PASSWORD"]
            } else if (keystorePropertiesFile.exists()) { // local用
                def keystoreProperties = new Properties()
                keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
                keyAlias keystoreProperties['keyAlias']
                keyPassword keystoreProperties['keyPassword']
                storeFile file(keystoreProperties['storeFile'])
                storePassword keystoreProperties['storePassword']
            }
        }
    }

....
// この中に releaseの追加
buildTypes {
        release {
            signingConfig signingConfigs.release

fastlane設定

rubyのバージョンを確認する

 ruby --version

プロジェクトでのrubyのバージョンを固定する

rbenv local 3.3.0(上記ver)

Flutter プロジェクト直下で以下を実行し bundler をインストール

gem install bundler

Gemfile を作成

bundle init

作成された Gemfile の一番下に以下を追加して fastlane を明記

gem 'fastlane'

以下コマンドで fastlane のインストール

bundle config --local path vendor/bundle
bundle install
bundle package
bundle install --local

android ディレクトリに移動して以下のコマンドを実行し、fastlaneディレクトリが作成されていることを確認する

cd android
bundle exec fastlane init

image

Fastlaneファイルを以下に変更

default_platform(:android)

platform :android do

# 内部テスト
  desc "development build apk and aab"
  lane :development do
    flutter_build(
      build_type: "release",
      flavor: "development",
      target: "lib/main_development.dart"
    )
  end
  desc "upload_to_play_store"
      lane :upload_inside do
        upload_to_play_inside(
          track: 'internal',
          release_status: 'draft',
          package_name: "com.YOURNAME.fastlane.flavor.dev",
          track: "internal",
          aab: "../build/app/outputs/bundle/productionRelease/app-development-release.aab"
        )
    end

#  オープンテスト
  desc "staging build apk and aab"
  lane :staging do
    flutter_build(
      build_type: "release",
      flavor: "staging",
      target: "lib/main_staging.dart"
    )
  end
  desc "upload_to_upload_open_test"
  lane :upload_open_test do
    upload_to_play_store(
      track: 'open',
      release_status: 'completed',
      package_name: "com.YOURNAME.fastlane.flavor.staging",
      track: "internal",
      aab: "../build/app/outputs/bundle/stagingRelease/app-staging-release.aab"
  )
  end

#  本番
  desc "production build apk and aab"
  lane :production do
    flutter_build(
      build_type: "release",
      flavor: "production",
      target: "lib/main_production.dart"
    )
  end
  desc "Upload to Play Store"
  lane :upload_production_to_play_store do
    upload_to_play_store(
      track: 'production',
      release_status: 'completed',
      package_name: "com.YOURNAME.fastlane.flavor.prod",
      aab: "../build/app/outputs/bundle/productionRelease/app-production-release.aab"
    )
  end



# Build the above with -- to specify flavor 
  desc "common build"
  private_lane :flutter_build do |options|
    target = options[:target]
    build_type = ["--", options[:build_type].downcase].join
    flavor = options[:flavor].downcase

    gradle(task: "clean")
    sh("fvm", "flutter", "build", "apk", build_type, "--flavor", flavor, "--target", target)
    sh("fvm", "flutter", "build", "appbundle", build_type, "--flavor", flavor, "--target", target)
  end
end

production をビルドしてみる

bundle exec fastlane production

ルートディレクトリ に aabファイルと apkができていることを確認する

image

fastlane アップロード

jsonの作成

https://docs.fastlane.tools/actions/supply/ 以下より jsonファイルをダウンロードする

以下のコマンドで成功と出たら上記のjsonでgoogle storeとのコネクトが可能になるのでプロジェクトに埋め込んでいく

fastlane run validate_play_store_json_key json_key:/path/to/your/downloaded/file.json

image

環境変数の設定

.envを作成

PLAY_STORE_CREDENTIALS_JSON_PATH="path/to/your/play-store-credentials.json"
PACKAGE_NAME="my.package.name"

Appfileを書き換える

json_key_file(ENV["PLAY_STORE_CREDENTIALS_JSON_PATH"])
package_name(ENV["PACKAGE_NAME"])

以下を実行し プロジェクトと GooglePlayStoreを紐付ける

fastlane supply init

エラーの場合は supply/lib/supply/client.rbを変更

def latest_version(track)
     - latest_version = tracks.select { |t| t.track == Supply::Tracks::DEFAULT }.map(&:releases).flatten.reject { |r| r.name.nil? }.max_by(&:name)
     + latest_version = tracks.select { |t| t.track == Supply::Tracks::DEFAULT }.map(&:releases).flatten.reject { |r| (r&.name).nil? }.max_by(&:name)

aab ファイルの作成

bundle exec fastlane development

一度手動でGoogle Developerにアップロード(内部テストへ)

Google play console の内部テストに出来上がった build/app/outputs/bundle/productionRelease/app-production-release.aabをドラッグドロップ

image

ver 変更して自動デプロイ

pubspec.yamlのアプリバージョンを上げる

version: 1.0.0+2

内部テストへアップロード

bundle exec fastlane upload_to_inside

iOS

matchを使用。 githubに本来は情報を格納(このリポジトリにはしていないプライベートにする)

iOSのディレクトリに移動

cd ios
bundle exec fastlane init

Falslaneのファイルを以下に修正

 
 default_platform(:ios)
platform :ios do

# developmentを省略

  default_platform(:ios)
platform :ios do

  desc "テストフライトへ"
  lane :staging_upto_appstore do
    api_key = app_store_connect_api_key(
      key_id: ENV["KEY_ID"],
      issuer_id: ENV["ISSUER_ID"],
      key_filepath: ENV["KEY_FILEPATH"],
      duration: 1200,
      in_house: false
    )
    match(
      api_key: api_key,
      type: "appstore",
      app_identifier: ["com.YOURTEAMNAME.fastlaneFlavor.staging"],
      force_for_new_devices: true
    )
    # match を使用している場合でも証明書の更新は行わずに、リポジトリからの取得のみを行う
    match(type: "appstore", readonly: true)
    gym(
      scheme: "staging",
      export_method: "app-store",
      export_options: {
        provisioningProfiles: {
          "com.YOURTEAMNAME.flavorFastlane.staging" => "match AppStore com.YOURTEAMNAME.fastlaneFlavor.staging"
        }
      }
    )
    # ベータ版をappstoreへアップロード
    upload_to_testflight(
      api_key: api_key,
      skip_waiting_for_build_processing: true, # ビルド処理の完了を待たない
      skip_submission: true # ビルドのレビュー提出をスキップ
    )
  end

  desc "本番環境へ"
  lane :prod_upto_appstore do
    api_key = app_store_connect_api_key(
      key_id: ENV["KEY_ID"],
      issuer_id: ENV["ISSUER_ID"],
      key_filepath: ENV["KEY_FILEPATH"],
      duration: 1200,
      in_house: false
    )
    match(
      api_key: api_key,
      type: "appstore",
      app_identifier: ["com.YOURTEAMNAME.fastlaneFlavor.prod"],
      force_for_new_devices: true
    )
    # match を使用している場合でも証明書の更新は行わずに、リポジトリからの取得のみを行う
    match(type: "appstore", readonly: true)

    gym(
      scheme: "production",
      export_method: "app-store",
      export_options: {
        provisioningProfiles: {
          "com.YOURTEAMNAME.flavorFastlane.prod" => "match AppStore com.YOURTEAMNAME.fastlaneFlavor.prod"
        }
      }
    )
    # 本番製品をappstoreへアップロード
    upload_to_app_store(
      precheck_include_in_app_purchases: false,
      api_key: api_key,
      skip_metadata: true,
      skip_screenshots: true,
      skip_binary_upload: false
    )
  end
end

App Store Connect API Key 作成

apple store connect の 以下ページの Issuer ID、キーID、ダウンロードp8を準備 image

この時、権限を以下に設定

image

.envに情報を入れ込む

# Fastfile
 KEY_ID = "<App Store Connect:キーID>"
 ISSUER_ID = "<App Store Connect: Issuer ID>"
 KEY_FILEPATH = "<p8ファイルの格納Path>"

以下コマンドを実行し、gitを選択しリポジトリに証明書などを埋め込む。

fastlane match init

image

これにより、チームメンバーは以下のコマンドより証明書を取得可能

fastlane match appstore(development)

Apple Developer Programへ移動し、Identifiersを com.YOURTEAMNAME.fastlaneFlavor.staging(flavor)(3種類)作成してapple connect へ移動し、アプリの登録をおこなう

以下でflavorを使ったデプロイが可能になる 例えば本番環境

fastlane ios prod_upto_appstore

appstoreにアップロード image

image (再度コマンド実行したらバージョンが上がる) image

以下のように、

developmentでは 内部テストへ

stagingではテストフライト、

productionでは本番へというように環境を変えた配信を行える

上記flavorでアップロード先を適宜分けることが可能

About

flavor(flutter_flavorizr)とfastlaneをつかった iOS と anoroidの 自動配布

License:Apache License 2.0


Languages

Language:Dart 79.9%Language:Swift 16.1%Language:Kotlin 3.1%Language:Objective-C 0.9%