$ npm i -g appcenter-cli
$ appcenter login
해당 명령어를 입력하면 appcenter 홈페이지가 열리는데 여기서 로그인을 하면 보여주는 토큰값을 복사해서 터미널에 입력하면 됩니다.
같은 프로젝트라도 안드로이드용, ios용 따로 등록해야 하면 됩니다.
myapp 이라는 react native 프로젝트를 등록할때: myapp_aos, myapp_ios
아래 2개명령어 모두 실행
$ appcenter apps create -d myapp_aos -o Android -p React-Native
$ appcenter apps crate -d myapp_ios -o iOS -p React-Native
등록된 앱마다 Staging 키와 Production 키를 등록합니다.
저의 경우 깃허브계정으로 appcenter 로그인을 했기 때문에 사용자이름이 eoss7777-naver.com
입니다.
사용자이름이 eoss7777-naver.com인 경우 아래 4개 명령어 모두 실행
$ appcenter codepush deployment add -a eoss7777-naver.com/myapp_aos Staging
$ appcenter codepush deployment add -a eoss7777-naver.com/myapp_ios Production
$ appcenter codepush deployment add -a eoss7777-naver.com/myapp_aos Staging
$ appcenter codepush deployment add -a eoss7777-naver.com/myapp_ios Production
$ appcenter codepush deployment list -a eoss7777-naver.com/myapp_aos -k
$ appcenter codepush deployment list -a eoss7777-naver.com/myapp_ios -k
하나의 리액트 네이티브 프로젝트여도 aos와 ios 두개의 앱이 등록되어있기 때문에
각각의 앱의 배포상태를 확인하기 위해서는 current app을 지정할 필요가 있습니다.
만약 지정하지 않고 배포상태를 확인하려고 하면 터미널에서 current app을 지정하라고 나올겁니다.
$ appcenter apps set-current eoss7777-naver.com/myapp_aos
$ appcenter apps set-current eoss7777-naver.com/myapp_ios
$ appcenter codepush deployment list
프로젝트에서 코드푸시 적용하는 방법은 React Native에서 CodePush 사용하기 블로그를 참고하면 좋습니다.
프로젝트에 코드푸시를 적용한 다음 테스트를 하기위해서는 버전을 변경해주고, (안드로이드의 경우) apk파일을 생성해야 합니다.
android/app/build.gradle 파일에서 versionName 변경
예) 1.0(초기값) → 1.0.1 // 1.0.1 → 1.0.2
android {
...
defaultConfig {
...
versionName "x.x.x"
}
}
APK를 생성하기 위해서는 앱 서명 작업을 해줘야 합니다.
안드로이드 스튜디오에서도 ketstore 파일을 생성할 수도 있지만 저는 명령어로 생성했습니다.
// myapp 이라는 이름의 키스토어와 alias 생성
$ keytool -genkey -v -keystore myapp.keystore -alias myapp_alias -keyalg RSA -keysize 2048 -validity 10000
위 명령어를 실행하면 C드라이브/[사용자]
/.android/ 디렉터리에서 myapp.keystore
파일을 찾을 수 있을건데 → 이 파일을 프로젝트내부 android 루트파일에 저장하면 됩니다.
3-1. gradle/properties
파일에서 생성한 키스토어와 alias를 등록합니다.
// 키스토어 생성할 때 터미널에서 입력한 비밀번호를 입력해주면 됩니다.
MYAPP_UPLOAD_STORE_FILE=myapp.keystore
MYAPP_UPLOAD_KEY_ALIAS=myapp_alias
MYAPP_UPLOAD_STORE_PASSWORD=password123
MYAPP_UPLOAD_KEY_PASSWORD=password123
3-2. android/app/build.gradle
release 추가
android {
defaultConfig { ... }
signingConfigs {
release {
if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
storeFile file(MYAPP_UPLOAD_STORE_FILE)
storePassword MYAPP_UPLOAD_STORE_PASSWORD
keyAlias MYAPP_UPLOAD_KEY_ALIAS
keyPassword MYAPP_UPLOAD_KEY_PASSWORD
}
}
}
buildTypes {
release {
...
signingConfig signingConfigs.release
}
}
}
Production 인지 Staging인지에 따라 2개 명령어를 실행해주면 됩니다.
$ appcenter codepush release-react -a eoss7777-naver.com/myapp_aos -d Production
$ appcenter codepush release-react -a eoss7777-naver.com/myapp_ios -d Production
$ appcenter codepush release-react -a eoss7777-naver.com/myapp_aos -d Staging
$ appcenter codepush release-react -a eoss7777-naver.com/myapp_ios -d Staging
$ cd android && ./gradlew app:assembleRelease
해당 명령어를 실행하면 android/app/build/outputs/apk/release
경로에 app-release.apk
파일이 생성됩니다.
이렇게 생성된 apk를 안드로이드 실제 기기에 설치하면 테스트 준비 완료!
4-1. StagingApk 생성
위 명령어로 실행하면 release상태의 apk가 생성되기 때문에 Production 타입의 codepush 명령어를 실행해야 적용됩니다.
다만, 저의 경우 회사 프로젝트에서 실제 코드푸시가 나가면 안되고 staging 타입의 코드푸시로 테스트를 할 필요가 있기 때문에 StagingApk를 생성할 필요가 있었습니다.
$ cd android && ./gradlew app:assembleReleaseStaging
./gradlew app:assembleReleaseStaging
명령어나 안드로이드 스튜디오를 통해 StagingAPK를 생성하지 못한경우 다음과 같은 방법으로 코드푸시가 적용되는지 테스트했습니다.
- 코드푸시테스트
문구를 추가- 코드푸시테스트
문구 삭제)- 코드푸시테스트
코드가 있으면 코드푸시서버에서 코드 불러옴 성공- 코드푸시테스트
코드가 없으면 코드푸시서버에서 코드 불러오지 못함 실패주의점
android/app/build.gradle
파일 내부의 versionNameios/프로젝트명.xcworkspace
파일을 xcode로 열었을때 general 탭의 identity 항목의 Version (애플 개발자 등록을 하지 않아 캡처본은 없습니다...)ios/프로젝트명.xcworkspace
파일을 xcode로 열고 맨상단 Product > Scheme > Choose Scheme > Edit Scheme > Build configuration
옵션에서./gradlew app:assembleRelease
명령어 중에 아래와 같은 이유로 빌드가 실패되었을때
java.lang.StackOverflowError (no error message)
gradle/properties
파일에서 org.gradle.jvmargs
옵션을 아래처럼 변경했습니다.
org.gradle.jvmargs=-Xmx2048m -Xms2048m -XX:ThreadStackSize=4096 -XX:CompilerThreadStackSize=4096
Task :app:checkReleaseStagingAarMetadata FAILED
* What went wrong:
Execution failed for task ':app:checkReleaseStagingAarMetadata'.
> Could not resolve all files for configuration ':app:releaseStagingRuntimeClasspath'.
> Failed to transform hermes-release.aar to match attributes {artifactType=android-aar-metadata}.
> Execution failed for JetifyTransform: D:\eunjeong\react-playground\RN\node_modules\hermes-engine\android\hermes-release.aar.
> Transform's input file does not exist: D:\eunjeong\react-playground\RN\node_modules\hermes-engine\android\hermes-release.aar. (See https://issuetracker.google.com/issues/158753935)
2: Task failed with an exception.
-----------
* What went wrong:
java.lang.StackOverflowError (no error message)
해석을 하자면 아래와 같은데
app:checkReleaseStagingAarMetadata
작업이 실패했다는건데
:app:releaseStagingRuntimeClasspath
구성을 위한 모든 파일을 확인할 수 없음
hermes-release.aar
파일을{artifactType=android-aar-metadata}
속성과 일치하도록 변환하지 못함
JetifyTransform: node_modules/hermes-engine/android/hermes-release.aar
에 대한 실행 실패함
node_modules/hermes-engine/android/hermes-release.aar
경로에 트랜스폼 파일이 존재하지 않음
node_modules/hermes-engine/android/hermes-release.aar
경로에 트랜스폼 파일이 존재하지 않음가 원인이기 때문에 왜 없지 보면... 정말 그 패키지가 설치되지 않아서 발생한거란걸 알았습니다...
$ npm i hermes-engine
와이라노....
* What went wrong:
Execution failed for task ':app:mergeReleaseStagingNativeLibs'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.MergeNativeLibsTask$MergeNativeLibsTaskWorkAction
> 2 files found with path 'lib/arm64-v8a/libhermes.so' from inputs:
- C:\Users\mileverse\.gradle\caches\transforms-3\ac097555541fbf0c83690d5cbcc53d71\transformed\jetified-hermes-release\jni\arm64-v8a\libhermes.so
- C:\Users\mileverse\.gradle\caches\transforms-3\74fcbc2563fbdd765ac4d6afc6fd1f80\transformed\jetified-hermes-engine-0.70.6-release\jni\arm64-v8a\libhermes.so
If you are using jniLibs and CMake IMPORTED targets, see
https://developer.android.com/r/tools/jniLibs-vs-imported-targets