Flutter Fastlane Firebase Distribution Lane [iOS, AOS]

석상우·2022년 11월 17일
0
post-thumbnail

Overview

iOS, AOS 각 플랫폼의 Firebase Distribution Lane 을 작성 후 Firebase 에 배포하는 과정을 살펴봅시다.

Fastlane 구축은 아래 포스팅에서 봐주세요 :)

  • iOS 로 구축
  • AOS 로 구축



iOS

1. Flutter 버전 가져오기

저는 Pubspec.yaml 파일의 version 을 가져와 해당 버전으로 Firebase Distribution 배포를 할 생각입니다. 따라서 Pubspec.yaml 파일에 작성되어있는 version 정보를 가져올 필요가 있습니다.

desc "Get Flutter version from pubspec.yaml"
private_lane :get_version_info do
  yaml_file_path = ENV["YAML_FILE_PATH"]
  data = YAML.load_file(yaml_file_path)
  version = data["version"]
  
  version_number = version.split("+")[0]
  build_number = version.split("+")[1]

  {version_number: version_number, build_number: build_number}
end

YAML.load_file(filePath) 를 이용해 yaml 파일을 가져올 수 있습니다. 그럼 가져온 yaml 파일에서 version 에 해당하는 값을 가져올 수 있을 것입니다. private_lane 으로 외부에서 접근할 수 없는 Lane 으로 생성해줍시다.



2. Distribution Version Setting

버전 정보를 불러왔으니, 이제 Ditribution 에 올릴 버전을 설정해줍시다.

desc "Version Setting"
private_lane :set_version do
  version_info = get_version_info
  version_number = version_info[:version_number]
  build_number = version_info[:build_number]

  increment_version_number(
    version_number: version_number 
  )

  increment_build_number(
      build_number: build_number
  )
end

앞서 구한 버전을 통해 버전업을 해줍시다. increment_version_number, increment_build_number 은 Fastlane 내에 존재하는 action 의 한 종류입니다. 더 많은 action 을 보려면 공식문서 를 확인해주세요!



3. Build

버전을 올렸으니, 빌드를 해야겠죠? build 커맨드로 빌드를 해줍시다.

desc "Build"
private_lane :build do |options|
  build_app(
    workspace: "Runner.xcworkspace", 
    scheme: "Runner",
    configuration: "Release"
  )
end

Firebase 에 올릴것이기 때문에 기본적인 설정만 해주고, Release Config 로 설정해줍시다. (ad-hoc 으로 배포 할 것이기 때문)



4. Firebase Upload

마지막으로, Firebase 에 업로드 해봅시다.

desc "Upload Firebase"
private_lane :firebase_upload do |options|
  firebase_app_distribution(
    app: ENV["IOS_FIREBASE_APP_DISTRIBUTION_APP"],
    groups: "ollacare-qa-list",
    release_notes: options[:release_note]
  )
end

더 많은 필드 정보는 Firebase Fastlane 공식문서 에 있습니다.



5. Full Code

default_platform(:ios)

desc "Upload Debug IPA fo Firebase Distribution"
lane :firebase_debug do
  puts "Set kDebugMode to True"
  sh("sed -i '' 's/kDebugMode/true/g' ../../lib/core/constants/constants.dart")

  match(type:"adhoc")
  set_version
  build
  firebase_upload

  puts "Set kDebugMode to False"
  sh("sed -i '' 's/true/kDebugMode/g' ../../lib/core/constants/constants.dart")
end

desc "Upload Release IPA fo Firebase Distribution"
lane :firebase_release do
  match(type:"adhoc")
  set_version
  build
  firebase_upload(release: true)
end

desc "Upload Firebase"
private_lane :firebase_upload do |options|
  firebase_app_distribution(
    app: ENV["IOS_FIREBASE_APP_DISTRIBUTION_APP"],
    groups: "ollacare-qa-list",
    release_notes: options[:release_note]
  )
end

desc "Get Flutter version from pubspec.yaml"
lane :get_version_info do
  yaml_file_path = ENV["YAML_FILE_PATH"]
  data = YAML.load_file(yaml_file_path)
  version = data["version"]
  
  version_number = version.split("+")[0]
  build_number = version.split("+")[1]

  {version_number: version_number, build_number: build_number}
end

desc "Version Setting"
private_lane :set_version do
  version_info = get_version_info
  version_number = version_info[:version_number]
  build_number = version_info[:build_number]

  increment_version_number(
    version_number: version_number 
  )

  increment_build_number(
      build_number: build_number
  )
end

desc "Build"
private_lane :build do |options|
  build_app(
    workspace: "Runner.xcworkspace", 
    scheme: "Runner",
    configuration: "Release"
  )
end

firebase_upload lane 을 보시면, match 를 통해 코드 사이닝을 하고, 버전을 세팅하고, 빌드하고, Firebase 에 올리는 과정을 거칩니다.



Android

1. Flutter 버전 가져오기

iOS 와 마찬가지로 Flutter 버전을 가져옵시다.

desc "Get Flutter version from pubspec.yaml"
private_lane :get_version_info do
  yaml_file_path = ENV["YAML_FILE_PATH"]
  data = YAML.load_file(yaml_file_path)
  version = data["version"]
  
  version_name = version.split("+")[0]
  version_code = version.split("+")[1].to_i

  {version_name: version_name, version_code: version_code}
end

헷갈릴까봐 iOS 랑은 네이밍을 다르게 적용했습니다.



2. Distribution Version Setting & build

안드로이드는 버전 정보를 가져오는 동시에, gradle_build 로 해당 버전 정보를 넣어서 바로 build 했습니다.

private_lane :gradle_build do |options|
  version = get_version_info
  version_name = version[:version_name]
  version_code = version[:version_code]

  gradle(
    task: "assemble",
    build_type: options[:release] ? "Release" : "Debug",
    properties: {
      "android.injected.version.name" => version_name,
      "android.injected.version.code" => version_code
    }
  )
end



3. Firebase Upload

private_lane :firebase_upload do |options|
  firebase_app_distribution(
    app: ENV['AOS_FIREBASE_APP_DISTRIBUTION_APP'],
    firebase_cli_token: ENV['FIREBASE_TOKEN'],
    groups: "test",
    debug: options[:release],
    android_artifact_type: "APK",
    release_notes: options[:release_note],
    apk_path: options[:release] ? ENV['RELEASE_APK_PATH'] : ENV['DEBUG_APK_PATH']
  )
end

AOS 는 Option 을 통해 Debug | Release 를 구분했습니다. 자세한 옵션은 Fastlane Firebase AOS 를 참조해주세요!



Full Code

default_platform(:android)

desc "Create Debug APK"
lane :apk_debug do
  version = get_version_info
  version_name = version[:version_name]
  version_code = version[:version_code]

  sh "flutter build apk --debug"
  sh "mkdir -p #{ENV['DESKTOP_PATH']}#{version_name}+#{version_code}"
  sh "mv #{ENV['DEBUG_APK_PATH']} #{ENV['DESKTOP_PATH']}#{version_name}+#{version_code}"
end

desc "Create Release APK"
lane :apk_release do
  sh "flutter build apk"
  version = get_version_info
  version_name = version[:version_name]
  version_code = version[:version_code]

  sh "flutter build apk"
  sh "mkdir -p #{ENV['DESKTOP_PATH']}#{version_name}+#{version_code}"
  sh "mv #{ENV['RELEASE_APK_PATH']} #{ENV['DESKTOP_PATH']}#{version_name}+#{version_code}"
end

desc "Upload Debug APK to Firebase Distribution"
lane :firebase_debug do |options|
  gradle_build
  firebase_upload(release_note: options[:release_note])
end

desc "Upload Release APK to Firebase Distribution"
lane :firebase_release do
  gradle_build(release: true)
  firebase_upload(release: true)
end

desc "Get Flutter version from pubspec.yaml"
private_lane :get_version_info do
  yaml_file_path = ENV["YAML_FILE_PATH"]
  data = YAML.load_file(yaml_file_path)
  version = data["version"]
  
  version_name = version.split("+")[0]
  version_code = version.split("+")[1].to_i

  {version_name: version_name, version_code: version_code}
end

private_lane :gradle_build do |options|
  version = get_version_info
  version_name = version[:version_name]
  version_code = version[:version_code]

  gradle(
    task: "assemble",
    build_type: options[:release] ? "Release" : "Debug",
    properties: {
      "android.injected.version.name" => version_name,
      "android.injected.version.code" => version_code
    }
  )
end

private_lane :firebase_upload do |options|
  firebase_app_distribution(
    app: ENV['AOS_FIREBASE_APP_DISTRIBUTION_APP'],
    firebase_cli_token: ENV['FIREBASE_TOKEN'],
    groups: "test",
    debug: options[:release],
    android_artifact_type: "APK",
    release_notes: options[:release_note],
    apk_path: options[:release] ? ENV['RELEASE_APK_PATH'] : ENV['DEBUG_APK_PATH']
  )
end

Android 는 회사 QA 부서나 기획, 사업부 까지도 APK 를 요청하는 일이 잦아서, APK 파일 생성도 따로 Lane 으로 생성했습니다. 맨 위에 보시면 APK 생성 Lane 이 있는데, 과정은 다음과 같습니다.

  1. flutter build 로 apk 생성,
  2. Desktop 에 해당 버전으로 폴더 생성
  3. 생성한 폴더에 apk 이동
profile
Mobile App Developer

0개의 댓글