How-To's Qodana

Android 프로젝트용 CI/CD 파이프라인을 구축하는 방법

Read this post in other languages:

draft.dev의 Kumar Harsh의 객원 작성 글입니다.

릴리스가 잦은 Android 앱을 출시한 분이라면 잘 정의된 빌드, 테스트, 배포 워크플로가 얼마나 중요한지 이미 알고 계실 겁니다. 복원력이 높은 자동화된 DevOps 워크플로가 없다면 릴리스의 빠른 속도를 유지하기가 어렵습니다. 지속적 통합 및 지속적 배포(CI/CD)를 통해 이런 과정을 자동화한다면 업무를 더 쉽게 처리하고, 버그를 더 빠르게 탐지하여 더 빠르게 릴리스할 수 있습니다.

JetBrains TeamCity는 강력한 파이프라인을 만들어주는 CI/CD 플랫폼입니다. 인기 있는 Android 개발 도구와 원활하게 통합되며, 빌드 및 테스트 단계를 구성할 때 사용자 친화적인 인터페이스를 제공합니다.

이 글에서는 JetBrains TeamCity를 사용하여 Android 프로젝트용 CI/CD 파이프라인을 설정하는 방법을 보여 드립니다. 여러분은 Android CI/CD 파이프라인의 핵심 구성 요소를 살펴보고 TeamCity로 몇 가지 샘플 파이프라인을 구성하는 방법을 자세히 알아보실 수 있습니다.

Android CI/CD 파이프라인의 이해

Android 개발을 위한 효과적인 CI/CD 파이프라인은 표준 DevOps 파이프라인에 있는 모든 단계를 포함하며, 이를 아티팩트 서명 및 Google Play Store 내부 트랙으로의 자동 배포와 같은 추가 프로세스로 강화합니다. 아래는 일반적인 Android CI/CD 파이프라인에 포함되는 모든 단계입니다.

1. 코드 체크아웃 및 버전 관리 통합: 파이프라인은 Git과 같은 버전 관리 시스템(VCS)에서 최신 코드를 가져오는 것에서 시작합니다. TeamCity를 사용 중이라면 인기 버전 관리 도구와의 통합 기능과 코드 커밋 및 병합 시 파이프라인이 자동으로 트리거되는 기능을 활용할 수 있습니다.

2. Gradle로 빌드 자동화: Android 프로젝트에 사용되는 표준 빌드 도구인 Gradle은 이 단계의 핵심입니다. TeamCity는 Gradle 명령어를 실행하여 사용자의 코드를 컴파일링하고, 리소스를 모으고, 빌드 아티팩트를 생성합니다. TeamCity의 빌드 러너는 다양한 Gradle 버전과 호환되며 빌드 구성을 위해 사용자가 설정할 수 있는 환경을 제공합니다.

3. 여러 Android 버전/플랫폼에 대한 유닛 테스트 및 통합 테스트: 다음 단계는 개별 코드 모듈을 검증하는 유닛 테스트 실행과 서로 다른 구성 요소가 어떻게 상호 작용하는지 확인하는 통합 테스트(UI 테스트 포함) 실행입니다. TeamCity에서는 다수의 테스트 러너와 프레임워크(예: JUnit, Espresso)를 구성하고 에뮬레이터나 기기 랩을 활용하여 다양한 Android 버전과 플랫폼을 대상으로 테스트를 실행할 수 있습니다.

4. 정적 코드 분석(JetBrains Qodana 활용) 및 코드 커버리지 보고: 정적 코드 분석으로 잠재적인 버그, 보안 취약점 및 코드 스타일 일관성 문제를 초기에 식별할 수 있습니다. TeamCity는 코드 스멜 탐지, 복잡한 코드 분석 및 다양한 프로그래밍 언어와의 통합을 지원하는 정적 코드 분석 도구인 JetBrains Qodana와 통합되어 있으므로 광범위한 코드 품질 검사를 수행할 수 있습니다. 또한, TeamCity에서는 사용자 코드 중에 어떤 부분이 유닛 테스트로 검사되는지 보여주는 코드 커버리지 보고서도 생성할 수 있습니다. 이 보고서는 개발자가 테스트에 포함되지 않는 부분을 집중해서 살펴볼 수 있도록 도와줍니다.

5. 아티팩트 생성 및 서명(APK 및 AAB): 빌드와 테스트가 성공한 다음의 단계는 배포 가능한 아티팩트를 생성하는 것입니다. Android 앱의 경우 보통 이 단계에서 서명된 Android Package Kit(APK) 또는 Android App Bundle(AAB)을 생성합니다. TeamCity는 빌드 단계를 사용하여 서명 프로세스를 파이프라인 내에서 자동화합니다.

6. 내부 테스트 및 프로덕션 환경으로 배포(Google Play, 베타 채널): CI/CD 파이프라인은 다양한 환경으로 앱을 배포하는 과정을 자동화할 수 있습니다. TeamCity에서는 내부 테스트 플랫폼으로 배포하거나 Google Play의 프로덕션 채널로 바로 배포하도록 구성할 수 있습니다.

7. 지속적인 모니터링과 피드백 루프: 강력한 CI/CD 파이프라인은 배포에서 끝나지 않습니다. TeamCity는 모니터링 도구와도 통합되어 있으므로 앱 성능을 추적하고, 충돌을 식별하고, 사용자의 피드백을 수집할 수 있습니다. 이러한 피드백 루프를 통해 개발자는 문제에 빠르게 대응하고 지속적으로 앱의 품질을 개선할 수 있습니다.

TeamCity로 CI/CD 파이프라인 구축

일반적인 CI/CD 파이프라인 구조를 살펴보았으니 이제 TeamCity로 파이프라인을 구축하는 방법을 알아보겠습니다. 아래의 섹션에서는 TeamCity를 설정하고, 사용자의 Android 프로젝트에 맞는 빌드 구성을 생성하고, 자동화 테스팅과 통합한 다음 마지막으로 앱을 패키지화하고 배포하는 방법을 안내합니다.

간단한 설명을 위해 이번 튜토리얼에서는 14일 무료 평가판으로 제공되는 TeamCity의 클라우드 호스팅 버전을 사용합니다. GitHub, GitLab, Bitbucket 또는 Google 계정을 사용하거나 기존의 방식대로 이메일 주소와 비밀번호를 조합해서 가입할 수 있습니다. 다음 단계로 넘어가기 전에 평가판 또는 구독을 활성화해 주세요.

하지만 이번 튜토리얼에서 TeamCity Cloud를 자체 호스팅 빌드 에이전트TeamCity On-Premises와 함께 사용할 수도 있습니다. 자체 호스팅 빌드 에이전트나 TeamCity On-Premises를 사용할 때는 Android SDK를 사용자의 에이전트에 별도로 설치해야 한다는 점에 유의하세요.

TeamCity 설정

TeamCity Cloud 인스턴스에 액세스한 후 초기 화면은 아래와 같습니다.

TeamCity Cloud 대시보드

Android 프로젝트를 시작하려면 페이지 중간에 있는 Create project(프로젝트 만들기)를 클릭하세요. 그러면 프로젝트의 소스 코드가 있는 링크를 입력하라는 요청을 받게 됩니다. Git 호스트 제공자(예: GitHub 또는 Bitbucket Cloud)를 사용하여 가입한 경우 해당 섹션을 확인하여 이에 맞는 프로젝트 생성 과정을 따라 주세요.

저장소 URL을 갖고 있는 경우에는 From a repository URL(저장소 URL로부터) 탭에서 URL을 바로 사용하면 됩니다. TeamCity는 자동으로 Git 호스트 제공자를 탐지하여 프로젝트를 가져옵니다.

프로젝트 만들기 페이지

Android 프로젝트가 없는 경우에는 다음의 저장소를 사용하여 튜토리얼을 진행할 수 있습니다.

bash
https://github.com/krharsh17/android-app-teamcity

액세스하려는 저장소가 비공개이거나 사용자 이름 및 비밀번호 조합으로 보호된 경우 TeamCity가 액세스할 수 있도록 이 단계에서 해당 정보를 입력하세요. 저장소 URL(필요한 경우 상세 정보 포함)을 입력한 후 Proceed(계속하기)를 클릭하세요.

다음 페이지에서는 TeamCity Cloud가 VCS 저장소와의 연결을 검증합니다. 연결에 성공하면 TeamCity가 프로젝트 이름, 디폴트 브랜치 등과 같은 프로젝트와 관련된 일부 메타데이터를 가져옵니다. 이러한 값은 TeamCity 프로젝트에 저장되기 전에 수정할 수 있습니다.

프로젝트 생성 시 연결 검증

이 페이지의 정보가 정확하게 입력되었다면 Proceed(계속하기) 버튼을 클릭하세요. TeamCity가 저장소에서 이용 가능한 구성 파일을 기반으로 저장소에 적용할 수 있는 빌드 단계를 자동으로 탐지합니다. 이 저장소에는 Gradle 기반의 구성 파일이 있기 때문에 사용자가 저장소에서 앱을 빌드할 때 사용할 수 있는 Gradle 작업 모음을 TeamCity가 자동으로 제안합니다(이 경우 cleanbuild).

Gradle 빌드 단계 옆의 확인란을 선택한 다음 Use selected(선택 항목 사용)를 클릭하세요.

자동으로 제안된 빌드 단계 선택

완료되면 작은 배너가 나타나 프로젝트의 첫 빌드를 실행할 수 있다고 알려줍니다. 오른쪽 상단에서 Run(실행)을 클릭하여 첫 빌드를 시작하세요.

첫 빌드 시작

버튼을 클릭하면 빌드가 대기열에 놓이며 빌드 에이전트를 사용할 수 있을 때까지 대기하게 됩니다. 상단 탐색 패널에서 Projects(프로젝트)를 클릭해서 실행 중인 빌드를 선택하면 프로퍼티와 상태를 확인할 수 있습니다.

실행 중인 빌드의 상세 정보

빌드는 약 5~6분 이내에 완료됩니다. 축하합니다! TeamCity에서 첫 Android CI/CD 파이프라인을 설정하셨습니다. 또한, 이 파이프라인을 설정하기 위해 VCS 저장소 URL을 사용하였기 때문에 자동으로 저장소 URL을 일정한 간격마다 확인하여 저장소에 새로운 변경 사항이 푸시되었는지 확인하도록 구성되었습니다. 새로운 변경 사항이 발견되면 파이프라인이 자동으로 최신 커밋을 가져오고 빌드를 다시 실행합니다.

플랫폼에 맞는 웹훅을 설정해서 더욱 개선할 수도 있습니다. 예를 들어 방금 설정한 저장소는 GitHub에 호스팅되어 있습니다. TeamCity에서는 편리하게 GitHub 웹훅을 설치하여 저장소에 특정 활동이 있을 때마다 GitHub가 자동으로 TeamCity에 알림을 보내게 할 수 있습니다.

GitHub 웹훅 설치

원하는 경우 위의 작업을 수행해도 됩니다. 그러나 이번 튜토리얼에서는 필수가 아닙니다.

빌드 아티팩트 구성

설정된 저장소에는 두 가지 옵션이 있습니다(FreePaid). 두 옵션에는 두 가지 빌드 변형이 있습니다(debugrelease). 이는 build 작업의 결과에 각 버전과 변형의 가능한 조합에 따라 네 가지 바이너리 파일이 포함된다는 의미입니다. 파이프라인 실행이 완료된 후에 이러한 아티팩트를 추출하고 액세스 가능하도록 파이프라인을 구성해 보겠습니다.

이를 위해 상단 탐색 패널에서 Projects(프로젝트)를 클릭하고 Android App Teamcity(Android 앱 Teamcity) 하단의 Build(빌드)를 클릭하여 제목이 Build인 빌드 구성 상세 페이지를 여세요.

빌드 구성 페이지로 이동

여기에서 화면의 오른쪽 상단 모서리에 있는 Edit configuration(구성 편집) 버튼을 클릭하세요.

빌드 구성 편집

여기에서 빌드 구성의 일반적인 설정을 변경할 수 있습니다. 목록의 하단에 Artifact paths(아티팩트 경로)라는 필드가 있습니다. 빌드 실행이 완료된 후에 추출하고 유지하고자 하는 아티팩트의 경로를 이곳에 정의해야 합니다.

아티팩트 경로 설정

Gradle build 작업을 실행할 때 Gradle이 생성하는 아티팩트는 app/build/outputs/apk에 저장됩니다. 따라서 다음을 Artifact paths(아티팩트 경로) 아래에 입력하세요.

app/build/outputs/apk/*/*/* => output

빌드 후에 생성되는 APK 바이너리의 완전한 경로는 app/build/outputs/apk///app---unsigned.apk와 같으므로 app/build/outputs/apk 뒤에 /*/*/*를 추가합니다.

, 및 바이너리 파일 이름의 가능한 값을 모두 반영하기 위해 와일드카드 *를 사용하였습니다.

=> 이는 Ant 스타일 경로의 기능이며 출력 및 입력 디렉터리를 구분할 때 사용됩니다. output은 최종 바이너리가 저장될 폴더의 이름입니다.

이를 추가한 다음 페이지의 하단에서 Save(저장) 버튼을 클릭하세요. 변경 사항이 저장되었다는 노란색 배너가 표시됩니다.

빌드 구성의 변경 사항 저장

이제 페이지의 오른쪽 상단에서 Run(실행) 버튼을 누르고 파이프라인을 다시 실행하여 빌드가 완료된 후 생성된 아티팩트를 볼 수 있습니다.

생성된 아티팩트 확인

저장소의 메인 브랜치에 커밋이 푸시될 때마다 트리거되는 파이프라인이 이제 설정되었습니다. 이 파이프라인은 프로젝트에서 가능한 모든 옵션 및 변형 조합에 대해 서명되지 않은 빌드 아티팩트를 생성하고, 유닛 테스트를 실행하며, 빌드 아티팩트를 읽을 수 있도록 설정합니다.

다음으로는 테스트를 사용자화하는 방법을 알아보겠습니다.

테스트 사용자화

앞서 언급된 것과 같이 build Gradle 작업은 생성된 모든 빌드 아티팩트에 대해 유닛 테스트를 실행합니다. 그러나 앱에 있는 일부 변형에 대해서만 테스트를 실행하고 싶은 상황이 있을 수 있습니다. 이러한 경우에는 clean build 작업을 사용자의 사용 사례에 맞는 적절한 작업으로 대체해야 합니다.

예를 들어 무료 버전 앱의 릴리스 변형에 대해 서명되지 않은 APK를 생성하고 유닛 테스트를 실행하려는 경우 clean buildassembleFreeRelease testFreeReleaseUnitTest로 대체해야 합니다. 그렇게 하려면 상단 탐색 패널에서 Projects(프로젝트)를 클릭한 다음 Android App Teamcity(Android 앱 Teamcity) 아래의 Build(빌드)를 클릭하세요. 이전 단계와 마찬가지로 다음 페이지의 오른쪽 상단에서 Edit configuration(구성 편집) 버튼을 클릭하세요.

이전에 아티팩트 경로를 구성할 때 액세스했던 빌드 구성의 General Settings(일반 설정) 페이지로 이동합니다. 왼쪽 탐색 패널에서 Build Step: Gradle(빌드 단계: Gradle)을 클릭하세요.

빌드 설정으로 이동

그러면 Build Steps(빌드 단계) 페이지가 열리며, 여기서 이 빌드 구성의 빌드 단계를 수정할 수 있습니다. 첫 빌드 단계(제목: Gradle)의 오른쪽에 있는 Edit(편집)을 클릭하세요.

Gradle 빌드 단계 편집

이제 Gradle tasks(Gradle 작업) 필드를 업데이트하여 이 빌드의 일환으로 실행될 작업을 변경할 수 있습니다. clean buildassembleFreeRelease testFreeReleaseUnitTest로 바꾸세요.

Gradle 작업 업데이트

이제 하단에서 Save(저장)를 누르세요. 변경 사항이 저장되면 오른쪽 상단에서 Run(실행) 버튼을 클릭하세요. 이 빌드 구성이 추가로 실행됩니다.

빌드 실행이 완료되면 빌드 실행 상세 정보 페이지의 Tests(테스트) 탭에서 TeamCity가 생성한 보고서를 볼 수 있습니다.

테스트 결과 확인

유닛 테스트마다 실행하는 데 걸린 시간과 테스트 완료 후 남은 스택 추적을 확인할 수 있습니다. 또한, 테스트의 오른쪽 끝에 있는 점 세 개를 클릭한 다음 Show test history(테스트 기록 표시)를 선택하면 현재의 테스트 실행과 이전 실행의 성능 차이를 비교할 수 있습니다.

테스트 실행 기록 비교

테스트 조사를 팀원에게 할당하고 조사 기록을 TeamCity 내에서 추적할 수 있습니다. 원하는 경우 테스트 개요 페이지에서 Download(다운로드) 링크를 클릭하여 테스트 결과를 다운로드할 수도 있습니다.

이 저장소는 테스트 개수가 적기 때문에 빌드 실행이 수 분 만에 완료되었습니다. 그러나 실제 프로젝트에서는 수천 개까지는 아니더라도 수백 개의 유닛 테스트가 있습니다. 그러한 상황에서 동일한 러너 에이전트로 모든 테스트를 순차적으로 실행하면 많은 시간이 소요됩니다. 이 문제는 TeamCity의 병렬 테스트 빌드 기능을 사용하면 해결됩니다.

TeamCity는 테스트 실행을 나누어 다수의 빌드 에이전트에 할당하여 병렬화할 수 있기 때문에 테스트를 모두 실행하는 데 걸리는 시간을 최소화할 수 있습니다. 이를 설정하기 위해 빌드 실행 상세 정보 페이지에서 Edit configuration(구성 편집) 버튼을 클릭한 다음 왼쪽 탐색 패널에서 Build Features(빌드 기능)를 클릭하세요.

빌드 기능 페이지로 이동

Build Features 페이지에서 + Add build feature(빌드 기능 추가) 버튼을 클릭하세요. 대화상자가 열리면 드롭다운 메뉴에서 Parallel tests(병렬 테스트)를 선택하세요.

병렬 테스트 검색

병렬로 테스트를 실행할 때 사용할 최대 배치 개수를 입력해야 합니다. 병렬화의 이점을 최대한 활용하려면 4에서 8 사이의 값을 입력하세요.

병렬 빌드 배치 설정

완료한 후 Save(저장) 버튼을 클릭하세요. 이제 테스트 사례가 풍부한 저장소의 테스트를 실행하여 성능 차이를 직접 확인해 볼 수 있습니다!

다수의 빌드 관리

앱에 여러 설정과 변형이 있기 때문에 TeamCity의 매트릭스 빌드를 활용하여 각 설정 및 변형 조합을 별도의 실행 인스턴스로 나눠서 빌드 파이프라인의 속도를 높이는 게 좋습니다. 또한, 모든 조합을 빌드하거나 하나의 조합만 빌드하는 것이 아닌, 애플리케이션의 특정 조합을 빌드할 수도 있습니다.

이를 위해서는 새로운 빌드 구성을 생성해야 합니다. 상단 탐색 패널에서 Projects(프로젝트)를 클릭한 다음 Android App Teamcity(Android 앱 Teamcity)를 클릭하세요. 프로젝트 상세 정보 페이지의 오른쪽 상단 모서리에서 Edit project…(프로젝트 편집…)를 클릭하세요.

프로젝트 구성으로 이동

General Settings(일반 설정) 페이지의 Build Configurations(빌드 구성) 섹션에서 + Create build configuration(빌드 구성 만들기) 버튼을 클릭하세요.

새 빌드 구성 만들기

그러면 Create Build Configuration 마법사가 열립니다. Repository URL(저장소 URL) 필드에 이전과 같은 저장소 URL(https://github.com/krharsh17/android-app-teamcity)을 입력하고 Proceed(계속하기)를 클릭하세요.

저장소 URL 입력

Matrix Builds(매트릭스 빌드) 옆의 페이지에서 Build configuration name(빌드 구성 이름)을 설정하고 다른 필드는 모두 디폴트 값으로 두세요. 그런 다음 Proceed(계속하기) 버튼을 클릭하세요.

빌드 구성 상세 정보 설정

유사한 VCS 루트가 발견되었다고 TeamCity가 알려줍니다. 대화상자에서 Use this(이 항목 사용) 버튼을 클릭하세요.

기존의 VCS 루트 선택

이러면 TeamCity가 두 빌드 구성에 대해 VCS URL을 한 번만 폴링하기 때문에 추가적인 성능 오버헤드를 피할 수 있습니다.

빌드 구성이 완료되면 빌드 구성이 생성되었다는 알림을 받게 됩니다.

새 빌드 생성 완료

이번에는 clean build Gradle 작업을 설정할 필요가 없으므로 이 페이지에서는 어떤 확인란도 선택하지 마세요. 대신 테이블 위에 있는 configure build steps manually(수동으로 빌드 단계 구성) 링크를 클릭하세요.

그러면 New Build Step(새 빌드 단계) 페이지로 이동되며 이곳에서 빌드 단계에 사용할 선호하는 러너를 선택할 수 있습니다.

빌드 러너 선택

목록에서 Gradle을 선택하세요. 다음 페이지가 열리면 Gradle tasks(Gradle 작업) 필드에 clean test%env.FLAVOR%%env.VARIANT%를 입력하세요.

Gradle 작업 입력

이렇게 하면 러너가 먼저 빌드 폴더를 비운 다음 환경 변수에 입력된 설정과 변형에 대해 테스트 작업을 실행합니다. 예를 들어 무료 앱의 릴리스 변형의 경우 작업의 이름이 clean testFreeRelease로 지정됩니다.

아래로 스크롤한 다음 Save(저장) 버튼을 클릭하세요. 그러면 Build Steps(빌드 단계) 페이지로 이동됩니다.

새로운 빌드 단계 추가

+ Add build step(빌드 단계 추가) 버튼을 클릭한 다음 assemble%env.FLAVOR%%env.VARIANT% 작업을 포함한 Gradle 빌드 단계를 추가하세요. 이 단계는 앱의 옵션 및 변형에 따라 빌드 아티팩트를 생성합니다.

완료한 후 Build Steps(빌드 단계) 페이지에는 생성한 두 개의 Gradle 기반 빌드 단계와 더불어 빌드 단계의 일부로 실행되는 Gradle 작업의 빠른 요약이 목록으로 표시됩니다.

업데이트된 빌드 단계

이제는 사용한 두 환경 변수의 값을 정의하고 아티팩트 경로를 구성하는 등 두 가지 절차를 더 수행해야 합니다.

빌드 구성의 아티팩트 경로를 설정하는 방법은 이미 알고 계실겁니다. 이 빌드 구성에서는 Artifact paths(아티팩트 경로) 필드의 값을 이전과 마찬가지로 app/build/outputs/apk/*/*/* => output으로 설정하세요.

옵션 및 변형 필드의 매트릭스 값을 설정하려면 왼쪽 탐색 패널에서 Build Features(빌드 기능)를 클릭하세요. Build Features 페이지에서 + Add build feature(빌드 기능 추가) 버튼을 클릭한 다음 대화상자의 드롭다운 메뉴에서 Matrix Build(매트릭스 빌드)를 검색하세요.

Build Features 페이지에서 Matrix Build 검색

드롭다운 목록에서 Matrix Build 옵션을 선택하면 매트릭스 빌드의 매개변수와 값을 입력하도록 요청받게 됩니다. 매개변수의 이름에는 env.FLAVOR를, 값에는 Free를 입력합니다. env.VARIANT라는 다른 매개변수를 추가하고 두 개의 값으로 ReleaseDebug를 추가합니다.

매트릭스 빌드 구성

이제 Save(저장) 버튼을 클릭하세요. 이로써 파이프라인에 매트릭스 빌드가 설정되었습니다. 페이지의 오른쪽 상단 모서리에서 Run(실행) 버튼을 클릭하여 테스트해 볼 수 있습니다.

이제 각 실행의 결과를 별도의 빌드 아티팩트 및 테스트 결과와 함께 볼 수 있습니다.

매트릭스 빌드 결과

Dependencies(종속성) 탭을 클릭하여 각 실행의 빌드 실행 상세 정보를 확인할 수 있습니다.

각 빌드 실행의 상세 정보 확인

이전에 보았던 것처럼 각 항목을 독립적이며 완전한 빌드 실행으로 간주하고 탐색할 수 있습니다.

패키지 제작 및 배포

Android CI/CD 파이프라인에서 중요한 요소 중 하나는 릴리스 바이너리가 사용자에게 게시될 수 있도록 Google Play로 푸시하는 것입니다. TeamCity와 Gradle Play Publisher(GPP)를 사용하여 이 과정도 자동화할 수 있습니다.

이 프로세스를 시작하기 전에 몇 가지 전제 조건이 있습니다.

1. Android 프로젝트의 첫 번째 APK/AAB를 Google Play Console로 수동으로 업로드했는지 확인하세요.

2. 유효한 서명 구성이 있어야 합니다.

3. Google Cloud Platform 서비스 계정을 생성해야 Google Play 개발자 API를 사용하여 JSON 자격 증명 파일을 받아올 수 있습니다. 이를 위해 다음 단계로 넘어가기 전에 이 단계를 따라주세요.

위의 링크에 설명된 단계를 완료한 후 Android 프로젝트에 GPP를 설치하고 구성해야 합니다. 이를 위해 앱 수준의 build.gradle.kts 파일에 있는 플러그인 블록에 다음의 코드를 추가하세요.

kt
id("com.github.triplet.play") version "3.9.1"

그런 다음 이 파일의 루트 수준에 다음의 콘텐츠를 포함한 play {} 블록을 새로 추가하세요.

kt
play {
    serviceAccountCredentials.set(file("play_config.json"))
    track.set("internal")
    releaseStatus.set(ReleaseStatus.DRAFT)
    defaultToAppBundles.set(true)
}

이는 GPP를 구성하여 이름이 play_config.json인 파일의 서비스 계정 자격 증명을 사용하고, 트랙을 internal로 설정하고 바이너리를 Play Console로 푸시할 때 상태를 DRAFT로 릴리스하며, 기본적으로 APK 대신에 앱 번들을 사용합니다.

이로써 Android 프로젝트에 필요한 구성 과정이 완료되었습니다. 진행하기 전에 이러한 변경 사항을 GitHub 저장소로 커밋하고 푸시하세요.

이제 TeamCity에서 Google Play로 바이너리를 푸시하기 위해 새로운 빌드 구성을 생성해야 합니다. 새로운 빌드 구성을 생성하기 전에 같은 단계를 수행해 주세요. Gradle을 러너로 사용하고 bundleFreeRelease를 실행할 Gradle 작업으로 사용하도록 첫 번째 빌드 단계를 설정하세요.

빌드 단계

이 빌드 구성에 단계를 하나 추가하여, 이번에는 빌드 러너로 Command Line(명령줄)을 선택하세요.

명령줄 빌드 단계 구성

명령줄 러너를 위한 새로운 빌드 단계 페이지가 열립니다. 앱 번들을 서명하고 Google Play로 게시하는 맞춤형 스크립트를 입력해야 합니다. Custom script(맞춤형 스크립트) 필드에 다음의 코드를 입력하세요.

# Create the keystore file from the environment variables
echo %env.ANDROID_KEYSTORE_FILE% > keystore.jks.b64
base64 -d -i keystore.jks.b64 > app/keystore.jks

# Sign the AAB using the keystore and credentials retrieved from the environment variables
jarsigner 
-keystore app/keystore.jks 
-storepass %env.KEYSTORE_STORE_PASSWORD% 
-keypass %env.KEYSTORE_KEY_PASSWORD% 
-signedjar release.aab 
app/build/outputs/bundle/freeRelease/app-free-release.aab 
%env.KEYSTORE_KEY_ALIAS%

# Create the GCP service account credentials file from the environment variables
echo %env.PLAY_CONFIG_JSON% > play_config.json.b64
base64 -d -i play_config.json.b64 > app/play_config.json

# Use GPP to publish the app bundle
./gradlew publishFreeBundle --artifact-dir release.aab

해당 코드에는 각 줄을 설명하는 인라인 주석이 포함되어 있습니다. 완료한 후에 페이지의 하단에서 Save(저장) 버튼을 클릭하세요.

명령줄 스크립트 구성

또한, 다음의 환경 변수를 정의하여 앱을 서명하고 게시할 때 사용할 적절한 자격 증명을 스크립트에 입력해야 합니다.

bash
ANDROID_KEYSTORE_FILE
KEYSTORE_KEY_ALIAS
KEYSTORE_KEY_PASSWORD
KEYSTORE_STORE_PASSWORD
PLAY_CONFIG_JSON

왼쪽 탐색 패널에서 Parameters(매개변수)를 클릭하여 환경 변수를 정의할 수 있는 페이지로 이동하세요. TeamCity가 이미 이 페이지의 필수 변수 목록을 채워놓은 것을 확인할 수 있습니다.

새로 인식된 환경 변수 표시

KEYSTORE_KEY_ALIAS, KEYSTORE_KEY_PASSWORDKEYSTORE_STORE_PASSWORD의 경우 Edit(편집)을 클릭하고 표시되는 대화상자에서 값을 입력하세요.

환경 변수 구성

ANDROID_KEYSTORE_FILEPLAY_CONFIG_JSON의 경우 먼저 파일을 openssl과 같은 도구를 사용하여 Base64로 변환해야 하며, Base64로 인코딩된 내용을 각 변수의 값 필드에 붙여넣으세요.

이를 통해 사용자의 애플리케이션 중 무료 버전의 서명된 릴리스를 빌드하고 게시하도록 파이프라인이 설정됩니다. 페이지의 오른쪽 상단에 있는 Run(실행) 버튼을 클릭해서 실행하면 실제로 동작하는 것을 확인할 수 있습니다.

성공적으로 실행되면 로그에서 BUILD SUCCESSFUL 메시지를 확인할 수 있습니다.

성공한 빌드의 결과 로그

앱의 최신 릴리스를 Google Play Console의 내부 트랙에서 볼 수 있으며, 사용자가 편집 및 홍보할 수 있습니다.

Play Console 내부 테스트 페이지

새로운 릴리스도 이전 릴리스와 같은 개발자용 이름(“2.0”)을 사용하는 것을 확인할 수 있습니다. 이는 GPP의 구성에 이름이 지정되지 않았기 때문입니다. 이름을 사용자가 지정하는 방법을 알아보려면 GPP 문서를 참조하세요.

모범 사례와 팁

이제 TeamCity을 사용하여 나만의 Android 파이프라인을 설정할 수 있게 되었으니 파이프라인의 효율성과 속도를 높이기 위해 고려할 만한 주요 모범 사례를 소개해 드리겠습니다.

1. 버전 관리 및 버전 관리 모범 사례: 효율적인 CI/CD 파이프라인에는 Git과 같은 강력한 버전 관리 시스템(VCS)이 필요합니다. 팀이 명확한 버전 관리 모범 사례를 따르고 일관적인 브랜치 전략(예: 피처 브랜치)을 구현하는지 확인하세요. 예를 들어 WIP 코드에 불필요한 단계가 실행되지 않도록 하기 위해 각 브랜치마다 맞춤형 파이프라인을 개발하세요.

2. 명확한 통과/실패 기준 및 임곗값: 빌드 및 테스트 실행 성공 기준을 명확하게 정의하세요. 여기에는 유닛 테스트 커버리지의 임곗값을 설정하거나 다른 코드 검사에서 그린 라이트를 받도록 하는 등의 조치가 포함됩니다. 파이프라인의 각 단계에 통과/실패 기준을 적용하도록 TeamCity을 구성하여 안정적인 빌드를 만들고 개발자들이 더 나은 품질의 코드를 작성하도록 장려하세요.

3. TeamCity의 알림 및 경고 활용: TeamCity에는 웹 브라우저, 이메일, Slack 및 IDE에서 발생하는 파이프라인 이벤트에 관해서 사용자에게 알려주는 상세한 알림 시스템이 있습니다. 빌드 실패와 중요한 테스트 실패에 대한 경고를 설정하여 개발 팀이 항상 상황을 인식하고 빠르게 문제를 해결할 수 있도록 하세요.

4. 공동 작업 및 피드백 루프: 효율적인 CI/CD 파이프라인은 개발 팀 내의 공동 작업을 강화합니다. 개발자들이 전체 빌드 및 테스트 프로세스를 명확하게 이해할 수 있도록 TeamCity 내의 파이프라인 시각화 기능을 사용하세요. 또한, 테스트 및 빌드 조사를 사용하여 TeamCity 내에서 바로 빌드 또는 테스트의 실패 원인에 대한 조사를 할당하고 협업할 수 있습니다. 그리고 팀원이 빌드 실패와 코드 커버리지 보고서를 검토하여 개선 영역을 파악하도록 장려하세요. 이를 통해 코드 품질 추구하고 지속적으로 개선하는 문화를 만들 수 있습니다.

5. 보안 조치(코드 서명 및 액세스 제어): TeamCity 인스턴스를 구성할 때 적절하게 액세스를 제어하여 서명 키와 같은 민감한 정보에 대한 액세스는 해당 정보에 액세스해야 하는 사용자만 가능하도록 제한하세요. HashiCorp Vault와 같은 도구를 사용하여 빌드에 사용할 수 있는 모든 중요한 자격 증명을 관리하고 로테이션을 실시하는 것도 고려해야 합니다. TeamCity의 주요 보안 추천 사항은 여기에서 확인할 수 있습니다.

결론

이 글에서 여러분은 JetBrains TeamCity를 사용하는 Android 개발 프로젝트에서 상세한 CI/CD 파이프라인을 만들고 관리하는 방법을 알아보았습니다. 코드 체크아웃과 버전 관리 통합에서부터 서명, 배포 및 모니터링에 이르는 Android CI/CD 파이프라인의 주요 단계를 살펴보았습니다. 또한 TeamCity가 각 단계를 지원하고 개발 워크플로를 간소화하는 방법을 알아보았습니다. 마지막에는 파이프라인 운영 효율성을 보장하는 주요 모범 사례도 배웠습니다.

TeamCity로 Android 파이프라인을 설정하면 워크플로의 효율성을 크게 높일 수 있습니다. 이를 통해 릴리스 주기를 단축하고, 버그는 줄이고, 궁극적으로 고품질의 Android 앱을 더 효율적으로 배포할 수 있습니다. 지금 개발 프로세스를 더 간소화하기 위한 첫 걸음을 내딛고 CI/CD 파이프라인을 직접 만들어 보세요!

게시물 원문 작성자

image description