들어가며

모바일에서 버튼 텍스트좀 변경해주세요. 얼마나 걸릴까요?

정말 간단한 요청 사항이지만, 얼마의 시간이 소요될 지 알 수 없습니다. Play Store의 앱 검수 시간을 예측 할 수 없기 때문입니다. React Native를 이용해서 앱 개발을 하면서 가장 답답했던 부분입니다. 이런 답답한 부분을 긁어주었던 Code Push, Musma에서 Code Push를 사용하고 달라진 부분을 이야기 해보려 합니다.


Code Push란?

사용자의 장치에 직접 배포하는데 대응할 수 있도록 해주는 Microsoft에서 만든 App Center 클라우드 서비스 입니다. JS, HTML, CSS 및 이미지 변경등의 특정 업데이트를 게시할 수 있는 중앙 저장소 역할을 하며, 앱은 제공된 SDK를 사용하여 즉각 최신 업데이트를 불러올 수 있습니다.

Code Push에 대해서 보다 자세한 내용이 궁금하신 분은 Microsoft에서 제공하는 공식 문서를 참고해 주세요.


Code Push 사용하기

1. appcenter-cli 설치 및 로그인

우선 Code Push를 사용하기 위해서는 appcenter-cli가 필요합니다. appcenter-cli를 설치하고 login을 진행해 줍니다.

$ yarn global add appcenter-cli # appcenter cli 설치
$ appcenter login # login appcenter

2. appcenter app 등록 하기

appcenter에 code push를 적용할 app을 등록합니다.

$ appcenter apps create -d mcas-react-native-lsp-aos -o Android -p React-Native

옵션 설명

  • d: display name 으로 변경이 가능
  • o: OS
  • p: Platform

등록 된 app 확인

$ appcenter apps list # developer-musma.net/mcas-react-native-lsp-aos

3. 등록한 app에 Staging Production 배포 단계 추가하기

등록한 app에 StagingProduction 배포 단계를 추가합니다. Staging 단계는 테스트를 위해서, Production은 실제 앱 배포시에 사용됩니다.

$ appcenter codepush deployment add -a developer-musma.net/mcas-react-native-lsp-aos Staging
$ appcenter codepush deployment add -a developer-musma.net/mcas-react-native-lsp-aos Production

옵션 설명

  • a: 배포 단계를 추가할 app 을 지정합니다.

Tip

appcenter apps set-current {AppName}을 통해서 기본 앱을 지정할 수 있습니다. 위와 같은 방법으로 기본 앱을 지정하면 -a 옵션으로 앱을 지정할 필요가 없어집니다.

배포 상태 확인

$ appcenter apps set-current developer-musma.net/mcas-react-native-lsp-aos # current app을 지정
$ appcenter codepush deployment list # 각 배포 단계에 따른 상태 확인

CodePushList

4. 배포 키 확인

아래의 명령어를 이용해서 각 배포 단계에 따른 key값을 확인할 수 있습니다. 해당 key 값은 SDK와 App Cetenr의 App을 연결하는데 사용됩니다.

$ appcenter codepush deployment list -k

React Native 설정

1. 설치

$ yarn add react-native-code-push

2. App.jsx

App.jsx를 code push로 감싸줍니다.

import codePush from 'react-native-code-push'
...
export default codePush(App)

3. android/gradle.properties 배포키 추가

...
CODEPUSH_DEPLOYMENT_KEY_DEBUG=
CODEPUSH_DEPLOYMENT_KEY_STAGING=???
CODEPUSH_DEPLOYMENT_KEY_PRODUCTION=???

4. android/setting.gradle

...
include ':app', ':react-native-code-push'
project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')

5. android/app/build.gradle

...
apply from: "../../node_modules/react-native/react.gradle"
+ apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"

...
buildTypes {
   debug {
      ...
+      resValue "string", "CodePushDeploymentKey", CODEPUSH_DEPLOYMENT_KEY_DEBUG
   }
   release {
      ...
+      resValue "string", "CodePushDeploymentKey", CODEPUSH_DEPLOYMENT_KEY_PRODUCTION
   }
+   releaseStaging {
+      initWith release
+      resValue "string", "CodePushDeploymentKey", CODEPUSH_DEPLOYMENT_KEY_STAGING
+      matchingFallbacks = ['release']
   }
}


...
if (enableHermes) {
 ...
+  releaseStagingImplementation files(hermesPath + "hermes-release.aar")
}

6. src/com/mcasreactnative/MainApplication.java

...
// 1. Import the plugin class.
import com.microsoft.codepush.react.CodePush;

public class MainApplication extends Application implements ReactApplication {

    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
        ...

        // 2. Override the getJSBundleFile method in order to let
        // the CodePush runtime determine where to get the JS
        // bundle location from on each app start
        @Override
        protected String getJSBundleFile() {
            return CodePush.getJSBundleFile();
        }
    };
}

드디어 Code Push를 사용하기 위한 모든 준비가 끝났습니다.

배포 테스트

지금까지 설정한 Code Push가 제대로 동작하는지 테스트해봅니다.

1. android/gradle.properties

우선 android/gradle.propertiesverName을 최신 버전으로 맞춰 줍니다.

Musma에서는 github action을 이용한 Play Store 배포 자동화를 사용하고 있습니다. vx.x.x의 형식으로 tag를 push 하면 tagNameverName으로 Play Store에 자동으로 게시됩니다. 하지만, Code Pushandroid/gradle.propertiesverName을 참조하기에 verName을 수정해줘야하는 약간의 번거로움이 생겼습니다. 이 부분은 추후에 개선해 볼 과제입니다.

- verName=1.0.0
+ verName=1.0.28

2. StagingAPK 생성

*.aab는 바로 디바이스에 설치할 수 없기 때문에 apk파일을 생성해서 테스트를 진행합니다.

$ cd android
$ ./gradlew assembleLspReleaseStaging # apk 파일 생성

해당 명령어를 실행하면 android/app/build/outputs/apk/lsp/releaseStaging 디렉토리에 app-lsp-releaseStaging-unsigned.apk 파일이 만들어 집니다.

3. App 서명하기

$ $ANDROID_HOME/build-tools/28.0.3/apksigner sign --ks mcas-upload-key.keystore
app-lsp-releaseStaging-unsigned.apk

4. 서명 된 앱을 기기에 설치

$ adb install app-lsp-releaseStaging-unsigned.apk

5. Code Push를 이용해 Staging 단계 배포하기

변경사항을 추가하고 추가한 변경사항을 Code Push를 이용해서 배포합니다.

$ appcenter codepush release-react -d Staging --mandatory # 해당 명령어는 project root 디렉토리에서 실행해야 합니다.

Tip

–mendatory 옵션을 주지 않으면, 2번 재시작 해야지 변경사항이 적용됩니다. InstallMode의 기본 값이 ON_NEXT_RESTART로 설정되어 있기 때문입니다. 보다 자세한 설정은 라이브러리 문서를 참고해 주세요.

6. 확인 하기

$ appcenter codepush deployment list # 배포 상태를 출력합니다.

CodePushList

Staging에 새로운 버전이 출시 된 것을 확인 할 수 있습니다.

APK를 설치한 앱을 실행 시킵니다.

$ appcenter codepush deployment list

CodePushList

Staing 단계에서 새로운 기기에 앱이 설치되었다는 정보를 확인해 볼 수 있습니다.

업데이트 내용이 디바이스에서 정상적으로 동작하는것이 확인 되면 staging 단계를 production으로 승격시켜서 배포를 완료합니다.

7. Staging 단계를 Production으로 승격하기

아래의 명령어를 실행하면 Staging 단계 업데이트를 Production에 반영할 수 있습니다.

$ appcenter codepush promote -s Staging -d Production # Staging을 Production으로 올리기
$ appcenter codepush deployment history Production # Production 단계 릴리즈 기록보기

정리

지금까지 Code Push를 이용해서 Musma에서 App을 배포하는 과정을 함께 진행해보았습니다.

물론 Code Push는 만능이 아닙니다. 라이브러리 업데이트 등의 네이티브 코드를 변경하는 경우는 Play Store를 통한 배포가 필요합니다. Musma에서 1년간 react-nativeApp을 개발했던 경험에 따르면 초기 설정만 잘 되어있다면 Play Store로 앱을 배포해야하는 빈도는 생각보다 그리 높지 않았습니다. 따라서 두 가지 방법을 적절히 잘 사용한다면 보다 나은 사용자 경험을 제공할 수 있을 것 이라 생각합니다.