서론
요즘 앱을 찍어내는 거에 관심이 부쩍 커졌습니다.
하나의 틀을 만들어두고 컨텐츠만 간단하게 변경할 수 있다면 단시간에 많은 앱들을 만들어낼 수 있지 않을까?라는 생각이 들어서죠😎
이번에는 조금 무리해서 무려 85개의 앱을 찍어내보려고 작업하던중 겪은 삽질기를 공유하고자 합니다. (참고로 포스팅에 어떤 앱인지는 공유하진 않아요 😂) 우선 앱을 출시하는데 있어서 많은 과정들이 필요한데, 애드몹 광고를 추가하여 수익화가 필요한 앱이라면 다음과 같은 과정을 거쳐야합니다.
관련 모든 코드는 Github에 등록해두었습니다 :)
Google Play Console 단계
1. Google Play Console에서 앱을 생성하는 단계
- 앱 이름 언어 정하고, 언어를 정하고, 앱인지 유료인지 무료인지 기타 정책을 선택후 생성합니다.
2. 실질적인 APK 또는 AAB 빌드된 안드로이드 Release 파일을 생성 후 Google Play Console에 업로드합니다.
3. 앱에 관련된 상세 설명들을 적어줍니다. (앱 대표 아이콘, 앱 와이드 이미지, 기기 사이즈별 스크린샷 1~8장, 앱 제목, 짧은 설명, 긴 설명, 출시 버전에 맞는 간략 요약설명, ETC)
4. 각종 정책과 권한, 등급 관련 생성 및 제출
5. 국가별 배포 설정 및 최종 출시
Admob, Adsense 단계
1. Adsense, Admob 계정생성
2. Admob 내가 출시하고자 하는 앱과 매칭할 광고생성
3. 광고 단위 생성 및 키 발급 후 Android App에 키 적용
Firebase 연결 및 추가
1. 앱 추가 및 앱 연결을 위한 json 생성 후 앱에 적용
2. 필요시 Admob과 연동작업 진행
그렇습니다... 단순히 앱을 만드는것도 시간이 오래 걸리는 작업중 하나지만, 앱을 배포와 출시 그리고 광고를 연결하는데 까지 꽤나 많은 작업들이 필요하며 그에 따른 시간들이 소요되는걸 알 수 있습니다.
노가다를 직접하게 되면 얼마나 시간이 걸릴까?
우선 위의 과정중 시간과 노력이 많이 필요한 작업이 무엇일까 곰곰히 생각해보다 아래에 내용을 꼽아보았습니다.
- 앱을 Build하여 APK를 뽑아내는 것
- 85개의 앱을 일일이 실행시켜가며 스크린샷을 찍어내는 과정
1. Build라는것 자체가 내 컴퓨터가 슈퍼 컴퓨터가 아닌 이상에야 앱을 하나하나 빌드하는데 꽤나 오랜 시간이 걸렸고, 앱 개당 평균 1분 이상 소요되었기 때문에 계산적으로 모든앱을 빌드만 하는데 최소 85분 이상 시간이 소요됩니다.. 😇
여기서 한번에 모든 앱이 잘 동작하여 빌드하고 끝낸다면 좋겠지만, 앱에 수정할 부분이라도 발생하게된다면...? 끔직한 사태가 발생하게 되겠죠...
2. 앱을 일일이 실행하며 스크린샷을 찍는것인데, Build > Install > 실행 > 일일이 특정 장면으로 화면 이동하여 스크린샷 촬영이라는 과정을 거쳐야 하기 때문에 정말 빨리해도 앱 하나당 최소 5분 이상은 소요될 것이라 판단되었습니다. (5분 X 85개 = 425분 약 7시간)
단순하게 계산 해봤을때 위의 과정만 약 8시간 이상이 필요할것 처럼 보였습니다. 멍때리며 나는 로봇입니다라고 빙의하여 해낼수 있을것 같지 않았고 그럴빠에 8시간을 들여서 Fastlane을 적용하자는 결론에 다다르게 되었습니다.😇
본론
공식 문서와 공식 Github을 참조하여 환경설정과 Fastlane 설정을 마무리 하였습니다. (OS는 Mac 기준으로 작성하였습니다.)
해당글은 환경설정 > 스크린샷 찍기 > Release빌드 순으로 작성되었습니다.
--------------------------------------- [ 환경설정하기 ] -------------------------------------
1. Fastlane 설치
터미널에서 Homebrew를 사용하여 fastlane을 설치합니다.
brew install fastlane
2. Fastlane 프로젝트에 설정
Fastlane 설치가 완료되었다면 Fastlane을 사용하고자 하는 프로젝트에서 아래의 명령어를 실행합니다.
fastlane init
Package Name (com.krausefx.app): com.dave.fastlanetest (패키지명 적기)
....
Path to the json secret file: (엔터!)
....
Download existing metadata and setup metadata management? (y/n) (n 입력 엔터)
1. 앱의 기본 패키지명을 물어보는데, 프로젝트의 패키지명을 적어줍니다. ex) com.dave.fastlanetest
2. json 시크릿 파일 경로를 물어보는데 일단은 엔터로 넘어갑니다. (나중에 설정하면 됨)
3. 메타데이터 관련 다운로드, 설정을 할 것인가 물어보는데 이것도 일단 n을 입력하고 넘어갑니다. (나중에 설정하면 됨)
이렇게 Fastlane 기본 설정이 완료되면 Project로 변경하여 폴더 경로를 살펴보면 fastlane 폴더와 아래 Appfile, Fastfile이 자동 생성된 것을 볼 수 있습니다.
Appfile
나중에 Google Play Console에 업로드 하기위한 key와, 대표 패키지 명이 입력되어있습니다. 글로벌하게 앱에 적용됩니다.
json_key_file("") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
package_name("com.dave.fastlanetest") # e.g. com.krausefx.app
Fastfile
Fastlane에서 제공하는 다양한 액션들을 생성 및 실행할 수 있습니다. 내용은 Ruby로 작성 되어있습니다.
default_platform(:android)
platform :android do
desc "Runs all the tests"
lane :test do
gradle(task: "test")
end
desc "Submit a new Beta Build to Crashlytics Beta"
lane :beta do
gradle(task: "clean assembleRelease")
crashlytics
end
desc "Deploy a new version to the Google Play"
lane :deploy do
gradle(task: "clean assembleRelease")
upload_to_play_store
end
end
3. Google Play Console에 연동하기
1. Google Play Console로 이동합니다.
2. 설정 > API 엑세스로 선택 > 연결할 프로젝트 선택 > 동의를 누릅니다.
3. 하단에 서비스 계정 > 새 서비스 계정 만들기 > 팝업이 뜨면 Google Cloud Platform으로 이동하기를 선택합니다.
4. Google Cloud Platform 서비스 계정 만들기를 클릭합니다. 저는 적당히 google-play-fastlane 이름으로 생성하도록 하겠습니다.
엑세스 권한 부여 (선택사항)에서는 서비스 계정 > 서비스 계정 사용자를 선택해주세요.
여기까지 완료되었다면 하단에 완료 버튼을 눌러 생성을 마무리합니다.
5. 생성된 서비스 계정 키생성
Fastlane 설정하면서 입력하지 못했던 시크릿 Json을 생성할거예요! 생성된 서비스 계정을 클릭합니다.
키 탭 선택 > 키 추가 > 새 키 만들기 > JSON 유형 선택 > 만들기를 클릭합니다.
Key가 생성되며, 자동으로 다운로드 됩니다. 이 파일을 프로젝트에 이동시켜서 사용하도록 합니다. (저는 fastlane 폴더에 넣어주었습니다)
프로젝트에 fastlane/Appfile에 내용을 수정해주도록 합시다.
json_key_file("./fastlane/play-store-credentials.json")
package_name("com.dave.fastlanetest")
그리고 다시 Google Play Console로 돌아와서 API 엑세스에 서비스 계정란에 서비스 계정 새로고침 해보면 방금 생성한 계정이 잘 반영된 것을 확인할 수 있습니다.
마지막으로 권한만 주면 끝이납니다
보기 액세스 권한을 클릭 > 계정 권한 탭으로 이동하여 관리자(모든 권한)을 클릭후 초대하기(저장)를 누릅니다.
그럼 이제 Google Play Store에 Fastlane을 통하여 액세스 할 수 있는 상태가 되었습니다 🎉
--------------------------------------- [ 스크린샷 찍기 ] ------------------------------------
이제 환경설정은 마쳤으니, 스크린샷을 찍어보도록 하겠습니다. 이 과정에서 정말 삽질을 많이했습니다 😓. 문서에서 찾기 힘든 부분들도 있어서 모르면 정말 많이 삽질할 수 있습니다.
해야할 리스트 요약
1. 테스트 코드를 실행시킬 가상디바이스를 설정한다. (실물 디바이스에서 해도 되지만 가상 디바이스에서 하는게 여러모로 편리합니다.)
2. 앱에서 내가 캡쳐하고 싶은 화면으로 이동하고 캡쳐할수 있도록 Espresso를 사용한 테스트 코드를 작성한다.
3. 테스트용 debug Manifest 작성.
3. Fastlane Ruby 코드를 작성하여 스크린샷 찍는 스크립트를 작성한다.
4. Fastlane 명령어를 통해 내가 작성한 스크립트를 실행하고, 스크린샷이 잘 찍혔는지 확인한다.
1. 가상디바이스 설정
스크린샷을 찍어줄 가상디바이스를 생성합니다.
- 상단 Devices 선택하는 부분을 선택하고 AVD Manager를 클릭합니다.
- Create Virtual Device ...를 클릭하여 가상 디바이스를 생성합니다.
- 마음에 드는 디바이스를 선택하고 Next를 클릭
여기서 중요한데 버전은 아무거나 상관없는데 Target에 버전 오른쪽 (Google APIs)가 적힌 시스템 이미지를 꼭 선택해야 합니다. 다른거 선택할시 정상적으로 동작하지 않음. 그다음 Next를 클릭
만약 Flavor를 활용하여 여러개의 앱에서 스크린샷을 찍어야 한다면 기본값으로 가상디바이스를 생성하게 되면 금방 얼마가지 못해서 용량 부족현상을 겪게 됩니다. 따라서 Flavor를 사용하여 여러 앱을 생성할 예정이라면 Show Advanced Settings를 클릭합니다. (단일앱은 그냥 이대로 Finish 클릭하여 생성해도 무방합니다.)
저는 80개가 넘는 앱을 Flavor로 빌드할 예정이라 RAM, VM heap, Storage 모두 넉넉하게 설정후 생성하였습니다.
(20GB로도 해봤는데 중간에 용량 부족을 겪었습니다 ;; 도대체 얼마나 용량을 드시는거야...)
생성을 완료후 가상디바이스를 실행한 모습입니다. 다 좋은데 스크린샷을 찍게되면 하단부에 존재하는 네비게이션 버튼들이 같이 촬영되기 때문에 상당히 거슬립니다. 저와 같은 기분을 느끼시는 분이라면 하단 버튼 제거를 위해 해당 포스팅을 참고하여 주세요
여기까지 Fastlane 스크린샷을 찍기위한 가상 디바이스 설정이 완료되었습니다.
2. Espresso를 사용한 테스트 코드 작성
프로젝트를 생성하면 기본으로 생성되는 app/src/androidTest/{패키지}/ExampleInstrumentedTest 클래스를 그대로 사용하겠습니다.
우선 스크린샷을 찍기위해 각종 라이브러리들이 필요한데 의존성을 먼저 추가해주도록 합시다.
app/build.gradle 에 Gradle에 아래의 의존성을 추가해주도록 합시다.
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test:rules:1.4.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.4.0'
androidTestImplementation 'tools.fastlane:screengrab:2.1.0'
제가 처음 작업을 할때만해도 2.0.0 버전이 최신 버전이라고 문서에 소개하고 있었는데, 해당 버전은 스크린샷을 찍을때 버그가 있었습니다;; Locale을 구분하는 구분자 값을 쪼개는데 있어 버그가 존재했는데, 문서에 있는 그대로 따라해도 동작하지 않는 이슈가 있었습니다. 에러는 친절하게 알려주지 않고 라이브러리를 한땀한땀 다 까봤더니 해당 버그를 찾게되어 수정한 PR을 올리려고 보니 최근에 반영된 버전이 Maven 저장소에 올라왔더군요 아직 문서에는 최신버전이 반영되어있지 않아서 PR을 올려두었습니다. 과연 반영이될지...🤣
screengrab 라이브러리는 꼭 2.1.0 버전을 사용하세요!
간단한 Activity 두개를 생성하고, 첫번째 화면에서 스크린샷 찍고, 두번째 화면으로 이동하여 스크린샷을 찍고 끝내는 프로그램을 작성해보겠습니다. (Second Activity는 새로추가된 Activity이기 때문에 Manifest에 등록하는거 잊지마세요!)
MainActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val intent = Intent(this, SecondActivity::class.java)
btn_next.setOnClickListener {
startActivity(intent)
}
}
}
SecondActivity
class SecondActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
}
}
Espresso TestCode
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import tools.fastlane.screengrab.Screengrab
import tools.fastlane.screengrab.locale.LocaleTestRule
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Rule
@JvmField
val localeTestRule = LocaleTestRule()
@get:Rule
var activityRule = ActivityScenarioRule(MainActivity::class.java)
@Test
fun useAppContext() {
onView(ViewMatchers.isRoot()).perform(waitFor(Duration.ofSeconds(1)))
Screengrab.screenshot("1")
onView(withId(R.id.btn_next)).perform(click())
Screengrab.screenshot("2")
}
// 스크린샷 찍기전 딜레이가 필요한 경우 사용합니다.(ex. 화면이 아직 로드되기 전 기다릴때)
private fun waitFor(duration: Duration): ViewAction {
return object : ViewAction {
override fun getConstraints(): org.hamcrest.Matcher<View> = ViewMatchers.isRoot()
override fun getDescription(): String = "wait for ${duration.toMillis()} milliseconds"
override fun perform(uiController: UiController, v: View?) {
uiController.loopMainThreadForAtLeast(duration.toMillis())
}
}
}
}
LocaleTestRule
영어버전, 한글버전, 독일버전, 일본버전, ETC... 로 나라를 변경해가면서 테스트가 필요할때 사용됩니다. Fastlane에서 Locale 값을 설정하면 그에 맞춰서 자동으로 Locale을 변경해주는 역할을 합니다.(기본값은 en-US 영어입니다)
ActivityScenarioRule
테스트를 할때 실행할 Activity를 설정합니다.
Screengran.screenshot("문자열")
스크린샷을 찍습니다. 안에 입력된 문자열로 파일명 Prefix를 생성합니다. 촬영된 스크린샷은 문자열 값에 따라 자동 정렬됩니다.
onView(withId(ID)).perform(click())
layout에 ID를 찾아서 클릭해주는 역할을 합니다. 이외에 Espresso 테스트관련 함수를 찾아보면 다양한 동작들을 할 수 있습니다.
ex) RecyclerView 스크롤하기, 특정 position 클릭하기, 일정시간 딜레이 주기, 등등
테스트 동작 예상
1. 앱을 실행후 MainActivity의 화면 스크린샷을 찍는다.
2. MainActivity에 btn_next 버튼을 클릭하여 SecondActivity로 이동한다.
3. SecondActivity 화면 스크린샷을 찍고 종료된다.
3. 테스트용 debug Manifest 작성
테스트를 진행하면 화면을 마음대로 조작하고, Locale도 변경하고 하는 막강한 작업을(?) 하기 때문에 디버깅용 Manifest를 추가로 생성해줘야 합니다. app/src/debug 폴더를 생성하고, AndroidManifest.xml 파일을 생성해줍니다. (편하게 기존 내용을 복사해주도록 해요!)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dave.fastlanetest">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
<uses-feature android:name="tools.fastlane.screengrab.cleanstatusbar"/>
<uses-permission android:name="android.permission.DUMP"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Fastlanetest">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SecondActivity"/>
</application>
</manifest>
기존 Manifest 파일과 다른점이라면 다양한 강력한 권한들이 추가된 점인데요, 화면을 조작하고, Locale을 변경하고, 사진을 촬영하여 디바이스에 사진을 저장하는등의 다양한 작업들을 해야하기 때문에 필요한 권한들입니다.
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
<uses-feature android:name="tools.fastlane.screengrab.cleanstatusbar"/>
<uses-permission android:name="android.permission.DUMP"/>
위의 권한들을 추가해주세요 :) 해당 권한들은 테스트 코드를 돌릴때 사용됩니다.
4. Fastlane Ruby 코드 작성
이제 모든 작성된 테스트를 실제로 실행해볼 차례입니다. 🔥
fastlane/Fastfile을 열어서 아래와 같이 ruby 코드를 작성합니다.
default_platform(:android)
platform :android do
desc "Make Screenshot"
lane :screenshot do # fastlane에서 실행할 액션명입니다. ex) fastlane screenshot
gradle(task: "clean") # 1. Gradle을 초기화 합니다.
gradle( # 2. Gradle 빌드를 돌려서 테스트용 APK를 생성합니다.
task: 'assemble',
build_type: 'Debug'
)
gradle( # 3. Gradle 테스트용 APK를 생성합니다.
task: 'assemble',
build_type: 'DebugAndroidTest'
)
capture_android_screenshots( # 4. 테스트를 돌며, 스크린샷을 찍습니다.
app_package_name: 'com.dave.fastlanetest',
clear_previous_screenshots: true,
locales: ['en-US'],
output_directory: "fastlane/metadata/",
app_apk_path: "app/build/outputs/apk/debug/app-debug.apk",
tests_apk_path: "app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk"
)
end
end
5. Fastlane 명령어를 통해 내가 작성한 스크립트를 실행하고, 스크린샷이 잘 찍혔는지 확인
Ruby 스크립트를 위와 같이 작성하였다면 fastlane 명령어를 입력하여, 실행해봅시다.
lane 명칭을 screenshot으로 설정하였기 때문에 저는 fastlane screenshot을 입력하여 해당 액션을 실행하였습니다.
Gradle clean > build > test build > test 실행 및 스크린샷 촬영 과정을 거치기 때문에 시간이 꽤나 걸립니다.
모든 과정이 마무리 되면 아래와 같이 스크린샷 성공에 대한 결과를 프린터 하는것을 보실 수 있습니다.
캡쳐된 사진은 다음 경로에서 확인이 가능합니다. 그리고 브라우저 창을 자동으로 열어서 캡쳐된 사진 리스트를 정렬해서 보여줍니다.
fastlane/metadata/{Locale}/images/photoScreenshots
에러 관련 추가팁
1. 위와 똑같이 fastlane 명령어를 실행하였는데 동작하지 않는다면, 정확한 이유는 모르겠지만 컴퓨터 재부팅 > fastlane 재설치(brew uninstall fastlane > brew install fastlane) 해야 다시 정상 작동할때가 있었습니다. 😅
2. 디바이스에 애니메이션 설정이 되어있다면 간혹 테스트가 돌다가 애니메이션 관련 에러는 뱉어내는 상황이 발생할 수 있습니다. 화면 전환이나 특정 뷰에 애니메이션을 처리해야되는 경우 스크린샷을 찍어야되는데 애니메이션이 실행되고 있다면 스크린샷이 의도한대로 찍히지 않을수 있으니 그런듯 합니다.
[해결 방법]
가상 디바이스에 개발자 모드를 활성하고, Setting > Developer options에 애니메이션 스케일 값들을 비활성화해야 합니다.
(Window animatiom scale / Transition animation scale / Animator duration scale 각 기본값은 1x > off로 변경)
6. Google Play Console에 스크린샷 업로드하기
이제 필요한 스크린샷이 준비되었으니, Google Play Console에 업로드해봅시다.
우선 Google Play Console로 이동하여 테스트용 앱을 만들어보았습니다. (AAB(APK) 빌드를 하여 추가하고 저장한 상태입니다.)
fastlane/Fastfile에 스크린샷 업로드를 위한 스크립트를 추가합니다.
desc "Upload screenshots to playstore"
lane :playstore_metadata do
supply(
package_name: 'com.dave.fastlanetest',
json_key: './fastlane/play-store-credentials.json',
metadata_path: 'fastlane/metadata/',
version_code: 1
)
end
버전과 함께 출력될 문구도 입력해봅니다.
fastlane/metadata/{Locale}/changelogs/1.txt
fastlane playstore_metadata
위에서 작성한 스크립트를 실행해보면 해당 폴더에 있는 스크린샷들을 업로드하고 완료가 됩니다.
Google Play Console > 앱 정보 > 기본 스토어 등록정보를 확인해보면 짠! 방금 찍은 스크린샷이 업로드 된 것을 확인할 수 있습니다.
몇가지 더 번거로운게 있는데요, 바로 테블릿 영역의 스크린샷들 입니다.
테블릿 영역의 스크린샷도 필수가 되어 꼭 업로드 해줘야 합니다. (저는 번거로워서 휴대전화 스크린샷으로 동일하게 도배하기 신공을 씁니다) 저와 같이 휴대전화 스크린샷을 동일하게 사용하려면 스크린샷을 아래 경로에 각각 넣어주면 됩니다.
7인치 태블릿 스크린샷(필수) : fastlane/metadata/{Locale}/images/sevenInchScreenshots
10인치 태블릿 스크린샷(필수) : fastlane/metadata/{Locale}/images/tenInchScreenshots
이외에도 fastlane에서는 앱 대표 아이콘, 그래픽 이미지, 앱 이름, 간단한 설명, 자세한 설명도 미리 작성해두면 편리합니다.
titie.txt : 앱 이름
short_description.txt : 간단한 설명
full_description.txt : 자세한 설명
video.txt : 동영상 URL
icon.png : 앱 아이콘
featureGraphic.png : 그래픽 이미지
위에 내용들을 모두 채우고 위에서 작성한 스크립트를 실행하면 해당 부분에 알맞게 들어가는 것을 확인할 수 있습니다.
fastlane playstore_metadata
-------------------------------------- [ Release Build ] ------------------------------------
빌드 뽑아내기 + 배포는 정말 너무너무 간단합니다. 우선 앱을 최초 자동으로 배포하기 위해선 어떤 앱이며, 패키지명은 무엇인지 알아야하기 때문에 Google Play Console에 최초 한번은 앱을 생성하고, AAB(APK)업로드 까진 해줘야합니다.
Gradle Build하여 AAB / APK 파일 뽑아내기
desc "Make AAB"
lane :make_aab do
gradle(
task: 'bundle',
build_type: 'Release'
)
end
desc "Make APK"
lane :make_apk do
gradle(
task: 'assemble',
build_type: 'Release'
)
end
AAB, APK 파일 생성후 Play Console에 배포하기 (+@ metadata도 같이 업로드)
desc "Upload to playstore"
lane :playstore do
gradle(task: "clean")
gradle(
task: 'bundle',
flavor: flavor,
build_type: 'Release'
)
supply(
package_name: 'com.dave.fastlanetest',
json_key: './fastlane/play-store-credentials.json',
metadata_path: 'fastlane/metadata', # 이 구문이 있다면 메타데이터 까지 동시에 업로드 됩니다.
aab: '{AAB 파일이 있는 경로}/app/build/outputs/bundle/app-release.aab' # AAB 파일 업로드
)
end
해당 스크립트를 작성하고 fastlane으로 실행하면 정상적으로 AAB 파일과 metadata 동시에 배포되는 것을 확인할 수 있습니다 😊
-------------------------------------- [ Flavor 응용하기 ] -----------------------------------
길고도 머나먼 여정을 함께 해보았습니다.
하나의 앱을 관리한다면 어쩌면 Fastlane은 굳이? 라는 의문이 들수 있습니다. 저라면 1~5개 앱이라면 그냥 손으로 하는게 더 효율적이라 생각합니다. 생각보다 설정해줘야 할 것들이 많고, 번거롭습니다. 하지만 많은 앱을 동시에 관리한다면 이야기가 달라집니다. 엄청난 효율을 느낄수 있게됩니다. 🥰
만약 30개, 50개, 100개의 앱을 관리해야 한다면 과연 손으로 일일이 다 스크린샷찍고, 플레이스토어에 올리고, 빌드까지 돌려서 과연... 인간이 할 수 있을까요? 🧐 실수라도 안하면 다행이라고 생각합니다.
이번에는 Flavor를 어떻게 적용하는지 보여드리도록 하겠습니다.
아래와 같이 gradle에 flavor가 5개, 아니 50개 100개가 된다고 가정해봅시다.
위에 스크립트를 Flavor를 활용하여 동작하는 스크립트로 변경하였습니다.
flavor에 대한 리스트를 정의하고, 루프를 돌며 빌드, 스크린샷, 배포를 진행하는 구조로 변경하면 끝! 코드가 크게 어렵진 않은 코드라
한번 훑어보시면 이해 되실꺼라 생각합니다!
default_platform(:android)
flavors = [
"appone",
"apptwo",
"appthree",
"appfour",
"appfive",
]
platform :android do
desc "Make AABs"
lane :make_aabs do
flavors.each { |flavor|
gradle(
task: 'bundle',
flavor: flavor,
build_type: 'Release'
)
}
end
desc "Upload screenshots to playstore"
lane :playstore_metadata do
flavors.each { |flavor|
supply(
package_name: 'com.dave.fastlanetest.' + flavor,
json_key: './fastlane/play-store-credentials.json',
metadata_path: 'fastlane/metadata/' + flavor,
version_code: 1
)
}
end
desc "Make Screenshot"
lane :screenshot do # fastlane에서 실행할 액션명입니다. ex) fastlane screenshot
flavors.each { |flavor|
gradle(task: "clean") # 1. Gradle을 초기화 합니다.
gradle( # 2. Gradle 빌드를 돌려서 테스트용 APK를 생성합니다.
task: 'assemble',
flavor: flavor,
build_type: 'Debug'
)
gradle( # 3. Gradle 테스트용 APK를 생성합니다.
task: 'assemble',
flavor: flavor,
build_type: 'DebugAndroidTest'
)
capture_android_screenshots( # 4. 테스트를 돌며, 스크린샷을 찍습니다.
app_package_name: 'com.dave.fastlanetest.' + flavor,
clear_previous_screenshots: true,
locales: ['en-US'],
output_directory: "fastlane/metadata/" + flavor,
app_apk_path: "app/build/outputs/apk/" + flavor + "debug/app-" + flavor + "-debug.apk",
tests_apk_path: "app/build/outputs/apk/androidTest/" + flavor + "/debug/app-" + flavor + "-debug-androidTest.apk"
)
}
end
end
누군가 Android Flavor + Fastlane 조합을 적용하실때 도움이 되셨으면 좋겠습니다!
이상으로 마치도록 하겠습니다 긴글 읽어주셔서 감사합니다 :)
참조
https://github.com/fastlane/fastlane
https://github.com/kalaspuffar/multideploy/blob/master/fastlane/Fastfile
https://www.youtube.com/watch?v=bYDlgzhMSOQ
작업 샘플코드
'개발 공부 기록하기 > - Android' 카테고리의 다른 글
[Android] Intent, Bundle, SavedStateHandle 객체 쉽게 전달하기. (0) | 2023.11.26 |
---|---|
Android Kotlin EditText 콤마 붙히기 (feat. Extension) (0) | 2021.09.05 |
Android Virtual Device 하단 버튼 제거 (0) | 2021.07.21 |
안드로이드 - 배경 투명도 조절하기 (0) | 2021.06.15 |
FCM Push Notification(HTTP v1) with OAuth 2.0 Playground / Postman / Terminal - Part2 (9) | 2021.01.19 |