회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
AWS 이용 중이라면 최대 700만 원 지원받으세요
국내 유명 IT 기업은 한국을 넘어 세계를 무대로 할 정도로 뛰어난 기술과 아이디어를 자랑합니다. 이들은 기업 블로그를 통해 이러한 정보를 공개하고 있습니다. 요즘IT는 각 기업의 특색 있고 유익한 콘텐츠를 소개하는 시리즈를 준비했습니다. 이들은 어떻게 사고하고, 어떤 방식으로 일하는 걸까요?
회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!
확인
국내 유명 IT 기업은 한국을 넘어 세계를 무대로 할 정도로 뛰어난 기술과 아이디어를 자랑합니다. 이들은 기업 블로그를 통해 이러한 정보를 공개하고 있습니다. 요즘IT는 각 기업의 특색 있고 유익한 콘텐츠를 소개하는 시리즈를 준비했습니다. 이들은 어떻게 사고하고, 어떤 방식으로 일하는 걸까요?
이번 글은 딥러닝 기술을 활용해 사람처럼 친근한 대화를 할 수 있는 관계 지향형 AI 챗봇을 개발하는 AI 스타트업 '스캐터랩' Engineering 팀의 이야기입니다. 자체 메신저 앱 개발을 결정한 스캐터랩이 지속적인 업데이트를 위해 어떤 효율적인 방식을 구상했는지 알아보겠습니다.
핑퐁팀은 2022년 상반기에 루다와 유저를 만나게 하는 수단으로 더 이상 페이스북 메신저를 사용하지 않고 자체 메신저 앱을 개발하기로 결정했습니다. 저희는 빠르게 MVP 형식의 메신저 앱을 완성하여 배포한 후 지속적인 업데이트를 통해 앱의 완성도를 올리자는 계획을 세웠고, 이를 위해 앱을 빌드하고 배포하는 과정이 번거롭지 않도록 최대한 자동화하였습니다. 덕분에 메신저 앱 ‘너티’를 안정적으로 배포하고 빠른 속도로 발전시켜 나갈 수 있었습니다.
본 포스트에서는 루다와 함께 사용하는 메신저 ‘너티’의 빌드와 배포를 자동화하는 과정을 설명해 보겠습니다.
자동화를 고려하지 않고 안드로이드와 iOS 앱을 빌드할 때는 각각 안드로이드 스튜디오와 Xcode에 있는 빌드 버튼을 눌러서 빌드하게 됩니다. 그렇게 빌드된 결과물을 Google Play 스토어와 App Store에 올리기 위해서는 각 플랫폼에서 업로드 버튼도 눌러줘야 합니다. 이러한 수고스러움을 덜기 위해 fastlane
을 사용하여 각 작업이 버튼의 클릭이 아닌 스크립트의 실행으로 처리되도록 자동화했습니다.
fastlane은 앱을 빌드하고 배포하는 과정에서의 여러 작업을 처리하는 스크립트를 제공해줍니다. 또한, 스크립트를 조합해서 새로운 스크립트를 Fastfile
에 정의할 수 있습니다. 공식 문서에 따라 fastlane의 설치 및 설정을 진행한 후 아래와 같이 Fastfile
을 작성하면, 한 줄의 명령어(fastlane release
)로 안드로이드 앱을 빌드하고 스토어에 업로드까지 할 수 있습니다.
default_platform(:android)
platform :android do
lane :release do
sh "./pre_build.sh" # 미리 작성한 shell 커맨드를 실행할 수도 있습니다.
gradle(task: "clean bundleRelease")
upload_to_play_store(
track: "internal",
release_status: 'draft'
)
end
end
앱을 빌드하고 그 결과물(.aab, .ipa)을 스토어에 배포하기 위해서는 다음의 인증 정보가 필요합니다.
iOS | 안드로이드 | |
서명을 위한 인증서 | Provisioning Profile 인증서 | App Upload key |
스토어에 올리기 위한 API key | App Store Connect API key | Google Play Console IAM (Service Account User) key |
안드로이드 플랫폼에서의 인증 정보들과 App Store Connect API Key는 링크되어 있는 문서를 따라서 한 번만 설정하면 추가로 관리할 필요가 없습니다. 하지만, Provisioning Profile 인증서는 앱의 Capabilities가 추가되거나, 등록된 Devices가 변경되는 경우 재발급을 받아야하기 때문에 지속적으로 관리해야 합니다. fastlane은 이 문제를 해결하기 위해 match라는 솔루션을 제공합니다.
match는 지속해서 변할 수 있는 Provisioning Profile 인증서를 프라이빗 GitHub 레포지토리를 통해 동기화할 수 있는 솔루션을 제공해줍니다. 가이드에 따라 match를 설정한 후 fastlane match appstore
명령어를 실행하면 다음의 순서에 따라 AppStore 배포를 위한 인증서를 관리해 줍니다.
Matchfile
에 설정한 GitHub 레포지토리에 Appfile
에 정의된 App Identifier를 AppStore에 배포할 수 있는 Provisioning Profile 인증서가 저장되어 있는지 확인합니다.
Fastfile
에 match 스크립트를 포함해서 아래와 같이 스크립트를 작성하면 편리하게 인증서를 관리하면서 iOS 앱을 빌드하고 Testflight에 배포까지 할 수 있습니다.
platform :ios do
lane :release do
# 인증서를 저장할 키체인을 만듭니다.
# 로컬 컴퓨터에서 스크립트가 실행되는 경우에는 별도로 만들지 않고 내장되어 있는 키체인을 사용하는 것을 권장합니다.
create_keychain(
name: ENV["MATCH_KEYCHAIN_NAME"],
password: ENV["MATCH_KEYCHAIN_PASSWORD"],
timeout: 3600,
)
match(
keychain_name: ENV["MATCH_KEYCHAIN_NAME"],
keychain_password: ENV["MATCH_KEYCHAIN_PASSWORD"],
type: 'appstore',
# readonly를 설정하면 유효한 인증서가 레포지토리에 없는 경우 인증서를 새로 발급 받지 않고 스크립트 실행을 중단합니다.
readonly: true,
)
build_app(
scheme: "PingpongMessenger",
export_method: "app-store",
)
app_store_connect_api_key(
key_id: ENV["API_KEY_ID"],
issuer_id: ENV["ISSUER_ID"],
key_filepath: ENV["API_KEY_FILE_PATH"],
duration: 1200,
in_house: false,
)
upload_to_testflight(
skip_waiting_for_build_processing: true
)
delete_keychain(name: ENV["MATCH_KEYCHAIN_NAME"])
end
end
fastlane을 통해 앱을 빌드하고 이를 스토어에 업로드하는 것을 간단한 명령어로 가능하게 하였지만, 여전히 문제는 남아있습니다. 스크립트의 실행이 모든 인증 정보와 환경이 설정되어 있는 개발자의 로컬 컴퓨터에서만 가능하다는 것입니다.
저희는 로컬 환경과 상관없이 GitHub으로 앱을 릴리즈하면 자동으로 배포 스크립트를 실행할 방법을 고민했습니다. 가장 먼저 생각할 것은 iOS 앱을 빌드하는 스크립트의 실행이 Mac에서만 가능하다는 것입니다. GitHub-hosted macOS runner를 사용할 수도 있지만, Linux Runner에 비해 10배 비싼 가격을 과금하기 때문에 저희는 스캐터랩 블림프팀이 내부에 구축해놓은 self-hosted macOS runner를 사용하였습니다.
스크립트를 실행시킬 Runner도 구했으니 이제 스크립트가 정상적으로 실행되도록 개발자의 컴퓨터에 설정되어있던 인증 정보와 그 밖의 환경 변수들을 Runner에 똑같이 설정하기만 하면 됩니다.
일반적으로 GitHub에서 CI/CD 스크립트를 작성할 때 소스 코드에 노출되면 안 되는 값은 GitHub Secrets로 관리하고 GitHub Actions workflow를 정의하는 YAML 파일에서 환경 변수로 주입해 사용합니다. 하지만, 앱을 빌드하고 배포하는 과정에서의 인증 정보들은 대부분 길거나 사람이 읽을 수 없는 파일 형태이기 때문에 Github Secrets에 저장되어 있는 문자열을 적절한 형태의 인증 정보로 변환시킬 필요가 있습니다.
아래의 Shell 스크립트는 안드로이드 앱 서명을 위한 App Upload Key를 저장하고 있는 .keystore
파일과 빌드 결과물을 스토어에 올리기 위한 API Key 파일(.json
)을 압축하고 암호화해두었던 encrypted.tar.gz
파일을 복호화한 후 /android/app
디렉토리에 압축을 푸는 스크립트입니다. GitHub Secrets에서 가지고 온 $SECRET_KEY
를 사용해서 미리 암호화해놓은 파일을 다시 복호화하는 방식으로 노출되면 안 되는 인증 정보를 담고 있는 파일을 알맞은 디렉터리에 추가할 수 있습니다.
openssl aes-256-cbc -d -k $SECRET_KEY -in encrypted.tar.gz -out ./android/app/secrets.tar.gz
cd android/app
tar -zxvf secrets.tar.gz
위의 스크립트로 추가한 .keystore
파일을 열어서 앱 서명을 위한 key를 얻기 위해선 gradle의 property에 keystore 파일의 비밀번호를 설정해야 합니다. 아래 스크립트는 gradle.properties
파일에 설정되어 있는 변수 중에 노출되면 안 되는 keystore 비밀번호 변수를 sed
명령어를 활용하여 GitHub Secrets에서 가지고 온 $KEYSTORE_PASSWORD
로 replace 하는 Shell 스크립트입니다.
if [[ "$OSTYPE" == "darwin"* ]]; then
sed -i "" 's/###KEYSTORE_PASSWORD###/'"$KEYSTORE_PASSWORD"'/' android/gradle.properties
else
sed -i 's/###KEYSTORE_PASSWORD###/'"$KEYSTORE_PASSWORD"'/' android/gradle.properties
fi
App Store Connect Key처럼 용량이 크지 않은 파일은 별도로 암호화해서 레포지토리에 커밋해놓지 않아도 다른 방법이 있습니다. 파일 전체를 base64로 인코딩해서 GitHub Secrets에 적어놓고 아래의 명령어를 통해 디코딩한 결과물을 알맞은 디렉터리에 알맞은 확장자(.p8
)로 내보낼 수 있습니다.
echo $APPSTORE_CONNECT_API_CERT | base64 -d > ios/fastlane/AppStoreConnectAPI_$KEY_ID.p8
이제 이러한 스크립트들을 활용하여 인증 정보와 환경 변수들을 설정한 후에 위에서 정의한 fastlane 스크립트를 실행하는 GitHub Actions 워크플로우를 작성하면 됩니다.
이번 포스트를 통해 fastlane을 이용하여 배포 자동화 스크립트를 작성할 수 있는 것, 앱을 빌드하고 그 결과물을 스토어에 업로드하기 위해 필요한 인증 정보들을 관리하는 법 등을 알 수 있었습니다. 그리고 이를 활용하여 앱을 빌드해서 스토어에 업로드하기 위한 스크립트를 실행하는 GitHub Action을 설정 방법까지 알아보았습니다.
혹시, 본인의 로컬 컴퓨터에서 앱을 수동으로 빌드하고 계시다면 배포 자동화 설정을 해서 자신의 컴퓨터와 함께 기능 개발에만 집중할 수 있는 자유를 찾으셨으면 좋겠습니다.
‘너티’는 React Native를 이용하여 개발했기 때문에 크로스 플랫폼(iOS, Android)으로 배포가 가능하고, 앱 전체를 빌드해서 스토어에 올리는 바이너리 배포와 JS 번들만 새로 갈아 끼우는 Codepush 배포가 가능합니다. 그뿐만 아니라 테스트 환경 구축을 위해 다양한 Config와 배포 트랙을 관리하고 있습니다. 다음 포스트에서는 Codepush 배포, 다양한 Configuration 관리, 사내 테스트 환경 구축(adhoc 배포) 등 다양한 배포 파이프라인을 구축하는 방법에 대해서 알아보도록 하겠습니다.
<원문>