Fastlane ?
다양한 작업을 자동화해주는 라이브러리로 iOS / Android 앱 개발에서 배포 및 빌드 자동화 가능
'Fastfile'이라는 설정 파일을 통해 워크플로우를 정의할 수 있음
Fastlane 설치
$ brew install fastlane
Android Fastlane 적용
Google Play Android API 허용
[ENABLE] 을 눌러 사용 설정을 해준다.
서비스 계정 생성
구글 API를 사용해서 배포를 하기 때문에 계정을 새로 생성해줘야 한다.
https://console.cloud.google.com/iam-admin/serviceaccounts
위 링크에 접속하고
좌측 메뉴에서 [서비스 계정] 을 클릭하고 상단의 [CREATE SERVICE ACCOUNT] 를 클릭한다.
Service account ID는 대충 입력해준다.
권한은 [Service Account User]로 부여해주고, 계정을 생성해준다.
생성하고 나면
다시 이전의 서비스 계정 목록으로 돌아오게 되는데
생성한 계정 이메일을 클릭한다.
[KEYS] 탭애서 [ADD KEY] 를 클릭해서
JSON 키를 다운로드 받는다.
다운로드 받은 파일을
flutter 루트 폴더/android 에 넣어준다
(key 파일이니 gitignore에 추가해야함!!)
출시 권한 부여
https://play.google.com/console/u/0/developers
구글 플레이 콘솔에 접속한 뒤,
좌측 메뉴에서 [사용자 및 권한] 을 클릭하고 상단의 [신규 사용자 초대]를 클릭한다.
이메일 주소는 위의 서비스 계정 이메일 주소를 입력하고 권한 만료는 체크하지 않는다.
자동화할 앱을 선택한 뒤,
출시에 모든 항목을 클릭하고 [적용] 후 [사용자 초대]를 마무리 한다.
Fastlane 초기화
$ cd android
$ fastlane init
초기화 명령어를 실행하고
패키지 이름, 위 json 파일 링크와 n 입력한다.
완료되면
'fastlane' 이라는 폴더와 Gemfile이 생성 된다.
Fastlane 작성을 위한 셋팅
배포할 때 릴리즈 노트를 작성해야하는데 (물론, 배포 옵션에 릴리즈 노트를 skip할 수도 있음)
위와 같이 폴더 구조를 생성하면
fastlane이 알아서 인식해서 배포할 때 가지고 가게 된다.
위와 같이 언어에 따라 설정할 수도 있고
changelogs 폴더 밑에 버전 코드 명으로 txt 파일을 생성하거나 버전 코드명이 없으면 default.txt 파일을 읽게 된다.
추가로
배포 여부에 따라 Slack 알림이 가는데 이 Slack 웹훅 URL을 가지고 있을 .env 파일을 fastlane 폴더 안에 생성한다.
(.env파일도 gitignore에 추가 필요)
이런 식으로 정의하면 된다.
Fastlane 작성
fastlane/Fastfile에 아래와 같이 작성한다.
default_platform(:android)
# build.gradle 파일에서 현재 versionName 가져오기
def get_version_name
build_gradle_path = "../app/build.gradle"
# 해당 파일에 versionName 변수가 많아 앞 뒤로 띄어써서 찾기
version_name_line = File.readlines(build_gradle_path).find { |line| line.include? " versionName " }
version_name = version_name_line.match(/versionName\s+["'](.+?)["']/)[1]
version_name
end
# build.gradle 파일에서 versionCode 가져오기
def get_version_code
build_gradle_path = "../app/build.gradle"
version_code_line = File.readlines(build_gradle_path).find { |line| line.include? " versionCode " }
# versionCode 값 추출
version_code = version_code_line.match(/\d+/)[0].to_i
version_code
end
# 사용자가 선택한 버전 타입에 따라 버전 증가
def increment_version(version_name, version_type)
return version_name if version_type == 4 # 4인 경우 현재 버전을 그대로 반환
version_numbers = version_name.split('.').map(&:to_i)
case version_type
when 1
version_numbers[0] += 1
version_numbers[1] = 0
version_numbers[2] = 0
when 2
version_numbers[1] += 1
version_numbers[2] = 0
when 3
version_numbers[2] += 1
else
UI.user_error!("올바르지 않은 버전 유형입니다.")
end
version_numbers.join('.')
end
# 사용자로부터 버전 증가 유형을 숫자로 입력받기
def get_version_type_from_user
version_type = UI.input("증가할 버전 유형을 입력하세요: 1은 Major, 2는 Minor, 3은 Patch, 4는 버전 유지").to_i
# 유효성 검사
unless [1, 2, 3, 4].include?(version_type)
UI.user_error!("잘못된 입력입니다. 1, 2, 3 또는 4를 입력하세요.")
end
version_type
end
# versionCode를 1씩 증가시키기
def increment_version_code
get_version_code + 1
end
# build.gradle 파일에서 특정 키 값 업데이트
def update_gradle_property(key:, value:)
build_gradle_path = "../app/build.gradle"
gradle_content = File.read(build_gradle_path)
# 해당 키 값만 찾아서 업데이트
updated_content = gradle_content.gsub(/#{key}\s+["']?.+?["']?$/, "#{key} #{value.is_a?(String) ? "\"#{value}\"" : value}")
# 업데이트된 내용을 다시 build.gradle 파일에 작성
File.open(build_gradle_path, "w") { |file| file.puts updated_content }
UI.message("Updated #{key} to #{value} in build.gradle")
end
# Android 앱을 빌드하고 Google Play에 배포하기
def build_and_deploy(new_version_name, new_version_code)
# versionName 및 versionCode 업데이트
update_gradle_property(key: "versionName", value: new_version_name)
update_gradle_property(key: "versionCode", value: new_version_code)
# 빌드 및 Google Play 배포
sh("flutter build appbundle")
upload_to_play_store(
track: 'production', # internal 일 경우, 내부 테스터 출시
aab: '../build/app/outputs/bundle/release/app-release.aab',
)
end
# Slack 메시지를 전송하는 함수
def send_slack_message(success:, app_name:, version_name:, version_code:, error_message: nil)
# 성공 또는 실패에 따른 메시지 구성
message = if success
"✅ *#{app_name}* 배포 완료!\n*버전*: #{version_name} (#{version_code})\n\n"
else
"❌ *#{app_name}* 배포 실패\n*버전*: #{version_name} (#{version_code})\n*에러 메시지*: #{error_message}"
end
UI.message(ENV['SLACK_URL'])
# Slack 알림 전송
slack(
message: message,
success: success,
slack_url: ENV['SLACK_URL']
)
end
# Main lane 정의
platform :android do
desc "배포"
lane :deploy do
begin
app_name = "앱 이름"
# 현재 버전 가져오기
current_version_name = get_version_name
current_version_code = get_version_code
version_type = get_version_type_from_user
# 버전 증가
new_version_name = increment_version(current_version_name, version_type)
new_version_code = increment_version_code
# 빌드 및 배포
build_and_deploy(new_version_name, new_version_code)
# 성공 시 Slack 메시지 전송
send_slack_message(
success: true,
app_name: app_name,
version_name: new_version_name,
version_code: new_version_code
)
rescue => e
# 실패 시 버전 되돌리기
update_gradle_property(key: "versionName", value: current_version_name)
update_gradle_property(key: "versionCode", value: current_version_code)
# 실패 시 Slack 메시지 전송
send_slack_message(
success: false,
app_name: app_name,
version_name: new_version_name,
version_code: new_version_code,
error_message: e.message
)
UI.user_error!("배포 중 오류가 발생했습니다.")
end
end
end
과정은
- android/app/build.gradle에서 versionName, versionCode 가져오기
- 사용자에게 major, minor, patch 업데이트 여부를 프롬프트로 입력 받아 android/app/build.gradle에 업데이트하기
- 빌드하기
- google play console 에 배포하기 (upload_to_play_store의 track에서 'production'이면 바로 출시 심사, 'internal' 이면 내부 테스트)
- 성공하거나 실패할 경우 slack 메시지 알람
실행
안드로이드 폴더에서 아래 명령어를 실행하면 위 과정이 자동으로 실행된다.
$ fastlane deploy
중간에 위와 같이 버전 업데이트 어떤 걸 할 건지 물어보는 프롬프트가 뜨는데
원하는 숫자를 입력하면 그 밑에 업데이트될 버전을 출력해준다.
조금 기다리면 성공했다는 메시지가 뜨고
google play console의 게시 개요에 들어가면 검토 중인 걸 확인할 수 있다!
굿굿
'💻 개발IT > Flutter' 카테고리의 다른 글
Flutter 앱 배포 자동화하기 ② (with. Fastlane) (0) | 2024.11.11 |
---|---|
[Flutter] .pub-cache/hosted/pub.dev/http-0.13.5/lib/src/io_client.dart 에러 (0) | 2023.03.30 |
[Flutter] 앱 배포 전 설정 정리! (ios, android) (0) | 2023.03.19 |
[Flutter] hot reload 안 될 때 (0) | 2023.03.12 |
[Flutter] Unable to boot the simulator 에러 (0) | 2023.03.10 |
[Flutter] main.dart 구조 분석 (0) | 2023.01.25 |
Flutter 프로젝트 폴더 구조 (0) | 2023.01.24 |