Fastlane을 사용해 React native 앱 버전 넘버 관리하기

Published on

여러분은 React Native로 앱을 개발하고 있습니다. 열심히 개발을 해서 유저를 팔로잉 할 수 있는 어썸한 기능을 만들었습니다. 수많은 버그 픽스가 있있고 새로운 api도 추가되었으므로 앱의 버전을 1.0.0에서 1.1.3으로 올릴 차례입니다. 어떻게 해야 할까요?

가장 쉬운 방법은 물론 직접 수기로 버전을 기입하는 것입니다.

  • package.json 에 적혀 있는 버전을 1.1.3으로 바꿉니다.
  • build.gradle 에서 versionCode를 1.1.3 으로 바꿉니다.
  • xcodeCFBundleShortVersionString 을 1.1.3으로 바꿉니다.
  • 각 앱 스토어에 올릴 릴리즈 노트를 씁니다.

직관적이고 가장 쉬운 방법이지만 만약 버전 업데이트가 빠른 앱인 경우 위와 같은 일을 버전 업 때마다 해야 할 것입니다. 귀찮죠. 만약에 버전을 적다가 실수라도 한다면 어떻게 될까요?

따라서 이번 글에서는 휴먼 에러를 최소한으로 하면서 동시에 이러한 귀찮음을 효과적으로 해결 할 수 있도록 하는 버저닝 프로세스를 알아보도록 하겠습니다.

React Native 는 양쪽 플랫폼에 같은 소스코드를 공유하기 때문에 이상적인 버저닝의 흐름은 소스 코드의 버전에 따라 각 플랫폼의 버전이 맞춰지는 것일 것입니다. 따라서 우리가 할 버저닝 자동화의 대략적인 흐름은 다음과 같습니다.

  • package.json 에서 버전을 올립니다.
  • iOS의 버전을 package.json 의 버전으로 올립니다.
  • 안드로이드의 버전을 package.json 의 버전으로 올립니다.
  • 버전 변경사항을 커밋하고, 태그를 단 뒤 저장소에 올립니다.

그러면 하나씩 알아보도록 합시다.

패키지 버저닝

npm 혹은 yarn 모두 패키지 버전을 매우 쉽게 관리할 수 있는 기능을 제공합니다. 저는 yarn을 선호하므로 yarn을 사용하지만 npm을 쓰더라도 전혀 상관 없습니다. 해야 할 일은 매우 간단합니다.

yarn version
default

터미널에 yarn version 혹은 npm version 을 입력하면 현재 버전을 보여줍니다. 새로운 버전을 입력하면 패키지 버저닝은 끝입니다.

각 플랫폼의 버전 맞추기 — iOS

다음으로는 소스 코드의 버전에 맞춰서 양쪽 플랫폼의 버전을 올릴 차례입니다. 먼저 iOS부터 보도록 하겠습니다.

  desc "Increase Version Name"
  lane :increase_version_name_iOS do
    package = load_json(json_path: "../package.json")
    package_version = package['version']
    increment_version_number(
      version_number: package_version
    )
  end

fastlane에 추가할 lane은 다음과 같습니다. 하나하나 살펴보도록 하겠습니다.

load_json

먼저 package.json 에 맞춰서 버전 업을 하기 위해서는 fastlane으로 패키지의 버전을 가져와야 합니다. 따라서 fastlane에서 json 파일을 파싱할 수 있게 해 주는 load_json_plugin 을 설치하도록 합시다.

설치 후에는 패키지의 버전을 다음과 같이 가져올 수 있습니다.

package = load_json(json_path: "../package.json")
package_version = package['version']

increment_version_number

fastlane이 제공해 주는 기본 액션입니다. iOS 앱의 버전을 간편하게 올리게 해 줍니다. 인자로는 위에서 가져온 패키지 버전 넘버를 넣어 주면 됩니다.

increment_version_number(version_number: package_version)

각 플랫폼의 버전 맞추기 — Android

  desc "Increase Version Name"
  lane :increase_version_name_Android do
    package = load_json(json_path: "../package.json")
    package_version = package['version']

    path = '../app/build.gradle'
    regexVersionName = /versionName\s+("\d+.\d+.\d+")/
    gradleScript = File.read(path)

    increasedGradleScript = gradleScript.gsub(regexVersionName, "versionName \"#{package_version}\"")

    f = File.new(path, 'w')
    f.write(increasedGradleScript)
    f.close
  end

안드로이드는 아쉽게도 fastlane에서 iOS의 increment_version_number와 같은 액션을 기본적으로 제공해 주지 않습니다. 따라서 직접 build.gradle 파일에 접근해서 버전을 바꾸어 주어야 합니다.

fastlane은 루비 기반이므로 문자인 gradleScript에서 gsub을 통해 versionName을 모두 패키지 버전으로 바꿔주도록 합시다.

한줄로 실행하기

이제 소스 코드의 버전 업과 각 플랫폼의 버전 싱크를 맞추는 작업을 하나로 엮어 봅시다.

"bump": "yarn version --no-git-tag-version
&& cd ios
&& bundle exec fastlane increase_version_name_iOS
&& cd ..
&& cd android
&& bundle exec fastlane increase_version_name_Android
&& cd ..",

package.json 에서 다음과 같이 명령어를 추가해 줍시다. 이제 yarn bump 한 줄이면 해당 버전 넘버로 소스코드와 플랫폼의 버전이 모두 바뀌게 됩니다.

저장소에 올리기 + 태그 달기

각 플랫폼의 버전을 바꾸었으므로 해당 변경 사항을 커밋하고 푸쉬해야 합니다. 푸쉬할때 해당 버전이름으로 태그를 남긴다면 더욱 쉽게 버전을 관리할 수 있습니다.

git add .
git commit -m "<bump> v1.0.3"
git push origin main // 혹은 PR
git tag v1.0.3
git push origin v1.0.3
default

이제 CICD 툴이 해당 태그를 감지해서 빌드까지 해준다면 완벽할 것입니다.

마치며

이렇게 해서 React Native 에서 패키지 버전을 사용해 버저닝을 자동화 하는 법을 살펴보았습니다. 이 글이 도움이 조금이라도 되었기를 바라며 마치도록 하겠습니다. 읽어주셔서 감사합니다.