Android 앱 배포 자동화 완벽 가이드 — GitHub Actions, APK·AAB 빌드, 서명과 Google Play 내부 테스트

Android 앱을 개발하다 보면 기능 구현보다 배포 과정이 더 번거롭게 느껴질 때가 있습니다.

특히 여러 개의 앱을 운영한다면 다음 작업을 반복하게 됩니다.

  • Android Studio에서 릴리스 빌드 실행

  • versionCode와 versionName 수정

  • APK 또는 AAB 생성

  • 서명 키와 비밀번호 확인

  • Google Play Console 접속

  • 새로운 AAB 업로드

  • 출시 노트 작성

  • 내부 테스트 트랙에 배포

  • 빌드 실패 시 원인 확인

앱이 한 개라면 수동으로 관리할 수 있지만, 앱이 여러 개이거나 업데이트가 잦다면 반복 작업이 부담이 됩니다.

이러한 과정을 자동화하는 방법 중 하나가 GitHub Actions를 이용한 CI/CD 구성입니다.

이번 글에서는 Android 프로젝트에서 GitHub Actions를 이용해 테스트, 릴리스 빌드, AAB 서명, Google Play 내부 테스트 업로드를 자동화하는 방법을 알아보겠습니다.

작성 기준: 2026년 10월. GitHub Actions, Android Gradle Plugin, Google Play Developer API 및 서드파티 Action의 설정은 변경될 수 있으므로 적용 시 공식 문서를 확인해야 합니다.


1. Android CI/CD란?

CI/CD는 소프트웨어의 빌드, 테스트, 배포 과정을 자동화하는 방식입니다.

CI는 Continuous Integration의 약자로, 코드를 통합할 때 자동으로 빌드와 테스트를 실행하는 것을 의미합니다.

CD는 Continuous Delivery 또는 Continuous Deployment를 의미하며, 빌드 결과물을 배포 가능한 상태로 만들거나 실제 배포하는 과정을 자동화합니다.

Android 프로젝트에서는 다음과 같은 구조를 만들 수 있습니다.

개발자
   │
   ▼
GitHub Repository
   │
   ▼
GitHub Actions
   │
   ├── JDK 설정
   ├── Android SDK 준비
   ├── Gradle 빌드
   ├── 테스트 실행
   ├── APK / AAB 생성
   ├── 서명 처리
   └── 빌드 결과물 보관
           │
           ▼
Google Play Developer API
           │
           ▼
내부 테스트 트랙

이렇게 구성하면 개발자가 매번 Android Studio에서 수동으로 빌드하지 않아도 됩니다.

다만 자동 배포는 실제 Google Play에 변경사항을 제출하는 작업이므로, 처음에는 내부 테스트 트랙만 대상으로 구성하는 것이 안전합니다.

2. GitHub Actions를 사용하는 이유

GitHub Actions는 GitHub 저장소에서 제공하는 자동화 기능입니다.

저장소에 코드를 Push하거나 Pull Request를 생성했을 때 워크플로를 실행할 수 있습니다.

Android 개발에서는 다음과 같은 작업에 활용할 수 있습니다.

기능활용 방법
자동 빌드Push할 때마다 Gradle 빌드
자동 테스트Unit Test 실행
APK 생성디버그 또는 릴리스 APK 생성
AAB 생성Google Play 배포용 번들 생성
서명암호화된 Secrets를 이용한 키 관리
버전 관리GitHub Actions 실행 번호 활용
배포Google Play 내부 테스트 업로드
결과 보관빌드 파일을 Artifact로 저장

GitHub Actions에는 사용량 제한과 과금 정책이 있으므로 저장소 공개 여부와 요금제를 확인해야 합니다.

3. Android 프로젝트 준비

먼저 GitHub 저장소에 Android 프로젝트를 업로드해야 합니다.

일반적인 프로젝트 구조는 다음과 같습니다.

MyAndroidApp/
├── .github/
│   └── workflows/
│       └── android.yml
├── app/
│   ├── build.gradle.kts
│   ├── src/
│   └── proguard-rules.pro
├── gradle/
│   └── wrapper/
├── build.gradle.kts
├── settings.gradle.kts
├── gradlew
└── gradlew.bat

GitHub Actions는 .github/workflows/ 디렉터리의 YAML 파일을 읽어 자동화 작업을 실행합니다.

중요한 점은 다음 파일을 저장소에 포함해야 한다는 것입니다.

  • Gradle Wrapper

  • Gradle 설정 파일

  • 앱 소스 코드

  • 필요한 리소스 및 Assets

  • 빌드에 필요한 공개 설정 파일

반대로 서명 키와 비밀번호 등 민감한 정보는 저장소에 올리지 않아야 합니다.

4. GitHub에 올리면 안 되는 파일

Android 프로젝트를 GitHub에 업로드할 때 다음 파일을 주의해야 합니다.

local.properties
*.jks
*.keystore
service-account.json

일반적으로 .gitignore에 추가할 수 있습니다.

/local.properties
*.jks
*.keystore
service-account.json

하지만 .gitignore에 추가했다고 이미 Git에 등록된 파일이 자동으로 제거되는 것은 아닙니다.

민감한 파일을 과거에 커밋했다면 Git 기록에 남아 있을 수 있습니다.

특히 서명 키나 서비스 계정 키가 외부에 노출되었다면 단순히 파일을 삭제하는 것만으로 충분하지 않을 수 있습니다.

키 교체와 접근 권한 검토가 필요합니다.

5. 가장 간단한 Android 자동 빌드 구성

먼저 GitHub Actions로 디버그 APK를 빌드해 보겠습니다.

.github/workflows/android.yml

name: Android CI

on:
  push:
    branches:
      - main

  pull_request:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest

    permissions:
      contents: read

    steps:
      - name: Checkout source
        uses: actions/checkout@v4

      - name: Set up JDK
        uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: '17'
          cache: gradle

      - name: Grant Gradle permission
        run: chmod +x gradlew

      - name: Build debug APK
        run: ./gradlew assembleDebug

      - name: Upload APK
        uses: actions/upload-artifact@v4
        with:
          name: android-debug-apk
          path: app/build/outputs/apk/debug/*.apk

이 워크플로는 다음과 같이 동작합니다.

  1. main 브랜치에 코드가 Push됩니다.

  2. GitHub Actions가 Ubuntu 환경을 준비합니다.

  3. JDK를 설치합니다.

  4. Gradle Wrapper에 실행 권한을 부여합니다.

  5. 디버그 APK를 생성합니다.

  6. 생성된 APK를 Artifact로 보관합니다.

java-version은 프로젝트에서 사용하는 Android Gradle Plugin의 요구사항에 맞춰 설정해야 합니다.

예제에서는 JDK 17을 사용했지만, AGP 버전에 따라 더 높은 JDK가 필요할 수 있습니다.

6. Gradle 빌드 명령어 이해하기

Android 프로젝트에서는 Gradle 명령어를 이용해 다양한 빌드를 실행할 수 있습니다.

명령어설명
assembleDebug디버그 APK 생성
assembleRelease릴리스 APK 생성
bundleRelease릴리스 AAB 생성
testDebugUnitTest디버그 Unit Test 실행
lintAndroid Lint 검사
clean빌드 결과 정리

예를 들어 Google Play에 업로드할 AAB를 생성하려면 다음 명령어를 사용할 수 있습니다.

./gradlew bundleRelease

생성된 파일은 일반적으로 다음 경로에 위치합니다.

app/build/outputs/bundle/release/

단, Product Flavor를 사용하는 프로젝트에서는 출력 경로가 달라질 수 있습니다.

7. Product Flavor가 있는 프로젝트의 빌드

하나의 Android 프로젝트에서 여러 앱을 관리한다면 Product Flavor를 사용할 수 있습니다.

예를 들어 다음과 같은 구조입니다.

android {

    flavorDimensions += "animal"

    productFlavors {

        create("bird") {
            dimension = "animal"
            applicationId = "com.example.birds"
        }

        create("fish") {
            dimension = "animal"
            applicationId = "com.example.fish"
        }
    }
}

이 경우 빌드 명령어는 다음과 같이 변경됩니다.

./gradlew assembleBirdDebug
./gradlew assembleFishDebug

./gradlew bundleBirdRelease
./gradlew bundleFishRelease

출력 경로도 Flavor별로 구분됩니다.

app/build/outputs/bundle/birdRelease/
app/build/outputs/bundle/fishRelease/

이 구조를 이용하면 하나의 저장소에서 여러 앱을 자동으로 빌드할 수 있습니다.

다만 서로 다른 앱은 Google Play의 패키지 이름과 서명 설정을 각각 관리해야 합니다.

8. GitHub Actions에서 Unit Test 실행

자동 빌드에 테스트를 추가하면 코드 변경으로 인한 오류를 더 빨리 발견할 수 있습니다.

- name: Run unit tests
  run: ./gradlew testDebugUnitTest

Product Flavor가 있다면 다음과 같이 실행할 수 있습니다.

- name: Run bird unit tests
  run: ./gradlew testBirdDebugUnitTest

테스트가 실패하면 일반적으로 해당 Job이 실패 상태로 종료됩니다.

따라서 릴리스 AAB를 생성하기 전에 테스트를 실행하는 구조를 추천합니다.

단, Android 기기 또는 에뮬레이터가 필요한 Instrumentation Test는 별도의 테스트 환경이 필요합니다.

9. Android Lint 자동 검사

Android Lint는 잠재적인 오류와 성능·보안 문제를 확인하는 정적 분석 도구입니다.

- name: Run Android Lint
  run: ./gradlew lint

Lint에서는 다음과 같은 항목을 확인할 수 있습니다.

  • 잘못된 리소스 사용

  • API 호환성 문제

  • 잠재적인 보안 문제

  • 불필요한 코드

  • 접근성 관련 문제

다만 모든 Lint 경고가 즉시 앱 오류를 의미하는 것은 아닙니다.

프로젝트의 요구사항에 따라 경고를 검토하고 필요한 규칙을 조정해야 합니다.

10. 릴리스 APK와 AAB의 차이

Android 앱을 배포할 때는 APK와 AAB를 구분해야 합니다.

구분APKAAB
확장자.apk.aab
직접 설치가능일반적으로 직접 설치 불가
Google Play 신규 앱 배포일반적으로 AAB 필요표준 배포 형식
주요 용도테스트·직접 설치Google Play 배포
기기별 최적화APK 구성에 따름Google Play에서 최적화된 APK 제공

Google Play 배포를 자동화하려면 일반적으로 AAB 생성이 필요합니다.

11. Android 앱 서명 이해하기

Android 앱은 서명되어야 설치하거나 배포할 수 있습니다.

서명에는 다음과 같은 정보가 사용됩니다.

  • Keystore 파일

  • Key Alias

  • Keystore Password

  • Key Password

Google Play App Signing을 사용하는 경우에는 업로드 키와 앱 서명 키의 역할을 구분해야 합니다.

일반적으로 개발자는 업로드 키로 AAB에 서명하고, Google Play가 배포용 APK 서명을 관리합니다.

따라서 GitHub Actions에는 해당 앱의 업로드 키를 안전하게 제공해야 합니다.

서명 키 파일을 GitHub 저장소에 직접 커밋해서는 안 됩니다.

12. GitHub Secrets에 서명 정보 등록

GitHub 저장소에서 다음 메뉴로 이동합니다.

Repository
   │
   ▼
Settings
   │
   ▼
Secrets and variables
   │
   ▼
Actions

다음 Secrets를 등록할 수 있습니다.

Secret 이름내용
KEYSTORE_BASE64Base64로 인코딩한 업로드 키
KEYSTORE_PASSWORDKeystore 비밀번호
KEY_ALIAS키 별칭
KEY_PASSWORD키 비밀번호

Keystore 파일은 로컬 환경에서 Base64로 인코딩할 수 있습니다.

macOS에서는 다음 명령어를 사용할 수 있습니다.

base64 -i upload-key.jks | tr -d '\n' > keystore.base64

생성된 문자열을 GitHub Secret에 등록합니다.

Base64는 암호화가 아니라 인코딩입니다.

따라서 Base64로 변환했다고 해서 키 파일이 안전해지는 것은 아닙니다.

GitHub Secrets의 접근 권한과 워크플로 실행 조건을 함께 관리해야 합니다.

13. GitHub Actions에서 Keystore 복원하기

GitHub Actions 실행 환경에서는 Secrets를 이용해 Keystore 파일을 복원할 수 있습니다.

- name: Restore keystore
  env:
    KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }}
  run: |
    printf '%s' "$KEYSTORE_BASE64" \
      | base64 --decode > "$RUNNER_TEMP/upload-key.jks"

이렇게 하면 실행 환경에 임시 Keystore 파일을 생성할 수 있습니다.

실제 릴리스 빌드에서는 이 파일 경로를 Gradle 서명 설정에 전달해야 합니다.

14. Gradle 서명 설정

app/build.gradle.kts에서 환경변수를 읽도록 구성할 수 있습니다.

android {

    signingConfigs {

        create("release") {

            val keystorePath =
                System.getenv("KEYSTORE_PATH")

            if (!keystorePath.isNullOrBlank()) {

                storeFile = file(keystorePath)

                storePassword =
                    System.getenv("KEYSTORE_PASSWORD")

                keyAlias =
                    System.getenv("KEY_ALIAS")

                keyPassword =
                    System.getenv("KEY_PASSWORD")
            }
        }
    }

    buildTypes {

        release {

            signingConfig =
                signingConfigs.getByName("release")

            isMinifyEnabled = true

            isShrinkResources = true
        }
    }
}

이 코드는 환경변수 기반 서명 설정의 기본 구조입니다.

실제 프로젝트에서는 로컬 개발 환경과 CI 환경의 서명 설정을 구분하고, 필수 값이 누락되었을 때 명확한 오류가 발생하도록 검증하는 것이 좋습니다.

또한 기존에 사용하던 업로드 키가 있다면 새로운 키를 임의로 생성하지 말고 해당 앱의 업로드 키를 사용해야 합니다.

15. GitHub Actions에서 서명된 AAB 생성

다음과 같이 환경변수를 전달해 릴리스 AAB를 생성할 수 있습니다.

- name: Build signed AAB
  env:
    KEYSTORE_PATH: ${{ runner.temp }}/upload-key.jks
    KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
    KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
    KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
  run: ./gradlew bundleRelease

빌드가 성공하면 AAB 파일이 생성됩니다.

- name: Upload release AAB
  uses: actions/upload-artifact@v4
  with:
    name: android-release-aab
    path: app/build/outputs/bundle/release/*.aab

단, 서명 설정이 올바르게 적용되었는지 확인해야 합니다.

또한 GitHub Actions의 Artifact에 서명된 AAB가 저장되므로 Artifact 접근 권한과 보관 기간을 관리하는 것이 좋습니다.

16. versionCode 자동 관리

Google Play에 새 버전을 업로드하려면 이전에 사용한 버전보다 큰 versionCode가 필요합니다.

매번 수동으로 변경하는 대신 GitHub Actions 실행 번호를 활용할 수 있습니다.

예를 들어 다음과 같은 방식입니다.

android {

    defaultConfig {

        val ciVersionCode =
            System.getenv("CI_VERSION_CODE")
                ?.toIntOrNull()

        versionCode = ciVersionCode ?: 1

        versionName = "1.0"
    }
}

GitHub Actions에서는 다음과 같이 전달할 수 있습니다.

- name: Build AAB
  env:
    CI_VERSION_CODE: ${{ github.run_number }}
  run: ./gradlew bundleRelease

하지만 이 방법에는 주의할 점이 있습니다.

github.run_number는 해당 워크플로의 실행 번호입니다.

이미 Google Play에 더 높은 versionCode를 업로드한 적이 있다면 값이 충돌할 수 있습니다.

또한 여러 앱이나 Flavor를 운영하는 경우 각 앱의 버전 코드 이력을 별도로 관리해야 합니다.

따라서 실제 운영에서는 기존 Google Play versionCode보다 항상 큰 값을 사용하도록 설계해야 합니다.

17. Google Play Developer API란?

Google Play Developer API를 사용하면 Google Play Console의 일부 작업을 자동화할 수 있습니다.

예를 들어 다음과 같은 작업을 수행할 수 있습니다.

  • AAB 업로드

  • 테스트 트랙 릴리스 생성

  • 출시 노트 설정

  • 릴리스 상태 관리

하지만 Google Play Developer API를 사용하려면 사전 설정이 필요합니다.

대표적으로 다음 사항을 준비해야 합니다.

  1. Google Play Console 개발자 계정

  2. Google Cloud 프로젝트

  3. Google Play Developer API 활성화

  4. 서비스 계정 또는 적절한 인증 구성

  5. Google Play Console에서 필요한 앱 권한 부여

서비스 계정에 불필요하게 높은 권한을 부여하지 않는 것이 좋습니다.

특히 운영 배포 권한과 내부 테스트 배포 권한을 구분할 수 있다면 최소 권한 원칙을 적용해야 합니다.

18. Google Play 서비스 계정 설정

Google Play 자동 배포를 위해서는 Google Cloud와 Google Play Console의 권한 구성이 필요합니다.

일반적인 설정 흐름은 다음과 같습니다.

Google Cloud
     │
     ├── 프로젝트 준비
     ├── Google Play Developer API 활성화
     └── 서비스 계정 생성
              │
              ▼
Google Play Console
     │
     ├── API 접근 설정
     └── 서비스 계정 권한 부여
              │
              ▼
GitHub Actions
     │
     └── 인증 후 내부 테스트 업로드

Google Play Console의 메뉴 이름과 권한 설정 화면은 변경될 수 있습니다.

따라서 현재 공식 문서를 기준으로 설정해야 합니다.

서비스 계정 JSON 키를 사용하는 경우에는 파일을 저장소에 포함하지 말고 GitHub Secrets를 통해 관리해야 합니다.

가능하다면 장기 보관되는 JSON 키를 줄이는 인증 방식도 검토하는 것이 좋습니다.

19. Google Play 내부 테스트 자동 업로드

Google Play 내부 테스트 트랙은 앱을 제한된 테스터에게 배포할 때 사용할 수 있습니다.

GitHub Actions에서 Google Play 업로드를 자동화하는 방법 중 하나는 서드파티 Action을 사용하는 것입니다.

예를 들어 r0adkll/upload-google-play와 같은 Action을 사용할 수 있습니다.

- name: Upload to Google Play Internal Testing
  uses: r0adkll/upload-google-play@v1
  with:
    serviceAccountJsonPlainText: ${{ secrets.PLAY_SERVICE_ACCOUNT_JSON }}
    packageName: com.example.birds
    releaseFiles: app/build/outputs/bundle/birdRelease/*.aab
    track: internal
    status: completed

위 코드는 설정 구조를 보여주는 예시입니다.

실제 적용 전에는 해당 Action의 유지보수 상태, 지원 입력값, 인증 방식, Google Play Developer API와의 호환성을 확인해야 합니다.

특히 status: completed는 실제 테스트 트랙 릴리스 상태에 영향을 주므로 자동 실행 조건을 신중하게 설정해야 합니다.

서드파티 Action을 사용할 때는 단순한 버전 태그보다 검증된 커밋 SHA로 고정하는 것이 공급망 보안 측면에서 더 안전합니다.

20. Push할 때마다 자동 배포하지 않기

모든 코드 변경을 Google Play에 자동 업로드하는 것은 권장하지 않습니다.

예를 들어 다음과 같이 역할을 분리할 수 있습니다.

이벤트실행 작업
Pull Request빌드 및 테스트
main 브랜치 Push빌드 및 테스트
수동 실행릴리스 AAB 생성
승인된 릴리스 실행내부 테스트 업로드
운영 배포별도 승인 절차

이렇게 하면 코드 검증과 실제 배포를 분리할 수 있습니다.

특히 Google Play 배포에 사용되는 Secrets는 신뢰할 수 있는 워크플로에서만 접근하도록 제한해야 합니다.

21. workflow_dispatch로 수동 배포 구성

GitHub Actions에서는 workflow_dispatch를 사용해 수동 실행 버튼을 만들 수 있습니다.

name: Android Release

on:
  workflow_dispatch:

jobs:
  release:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up Java
        uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: '17'

      - name: Build
        run: ./gradlew bundleRelease

이렇게 하면 GitHub Actions 화면에서 필요한 시점에 워크플로를 실행할 수 있습니다.

다만 이 예제에는 서명과 업로드 단계가 포함되어 있지 않습니다.

실제 배포 워크플로에는 서명, 테스트, 인증 및 업로드 단계를 추가해야 합니다.

22. GitHub Environment로 배포 승인 관리

GitHub Actions에서는 Environment를 이용해 배포 환경을 구분할 수 있습니다.

예를 들어 다음과 같이 구성할 수 있습니다.

GitHub Environments
       │
       ├── internal
       │     └── 내부 테스트
       │
       └── production
             └── 운영 배포

Environment별로 Secrets를 관리하거나 승인 규칙을 설정할 수 있습니다.

다만 Environment 보호 규칙의 지원 범위는 GitHub 요금제와 저장소 공개 여부에 따라 달라질 수 있습니다.

따라서 사용 중인 GitHub 계정에서 해당 기능을 사용할 수 있는지 확인해야 합니다.

23. 여러 Flavor를 자동으로 빌드하기

Product Flavor를 사용하는 프로젝트에서는 GitHub Actions의 Matrix 기능을 활용할 수 있습니다.

name: Android Flavor Build

on:
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        flavor:
          - Bird
          - Fish

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up JDK
        uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: '17'

      - name: Build flavor
        run: ./gradlew bundle${{ matrix.flavor }}Release

이렇게 하면 Bird와 Fish Flavor를 각각 빌드할 수 있습니다.

다만 실제 자동 배포까지 구성한다면 다음 정보를 Flavor별로 관리해야 합니다.

  • Application ID

  • Google Play 패키지 이름

  • 업로드 키

  • versionCode

  • AdMob 설정

  • 앱 이름과 아이콘

  • 출시 노트

  • 배포 트랙

여러 앱을 하나의 워크플로에서 처리하더라도 각 앱의 배포 정보가 혼동되지 않도록 구성하는 것이 중요합니다.

24. 빌드 실패 시 확인할 사항

GitHub Actions에서 Android 빌드가 실패하는 대표적인 원인은 다음과 같습니다.

오류확인 사항
Gradle 실행 실패Wrapper 실행 권한
Java 버전 오류AGP와 JDK 호환성
SDK 오류compileSdk 및 SDK 설치
의존성 다운로드 실패저장소 및 네트워크
서명 실패Keystore, Alias, Password
AAB 생성 실패Gradle 설정 및 Flavor
Google Play 업로드 실패API 권한, 패키지 이름, versionCode
릴리스 거부정책, 서명, 앱 상태

특히 로컬 Android Studio에서는 빌드되지만 GitHub Actions에서 실패하는 경우가 있습니다.

이는 로컬에만 존재하는 파일이나 환경변수에 프로젝트가 의존하고 있기 때문일 수 있습니다.

따라서 CI 환경에서 필요한 설정을 명확하게 관리해야 합니다.

25. GitHub Actions 보안 체크리스트

자동 배포 환경은 앱 서명 키와 배포 권한을 다루기 때문에 보안이 중요합니다.

  • Keystore 파일을 저장소에 커밋하지 않음

  • 서비스 계정 JSON 키를 저장소에 커밋하지 않음

  • GitHub Secrets 사용

  • 서비스 계정 최소 권한 부여

  • Pull Request에서 배포 Secrets 사용 제한

  • 신뢰할 수 없는 코드에서 릴리스 워크플로 실행 방지

  • 서드파티 Action의 버전 및 유지보수 상태 확인

  • 가능하면 Action을 커밋 SHA로 고정

  • 배포 워크플로 수동 실행 또는 승인 절차 적용

  • Artifact 접근 권한 및 보관 기간 관리

  • 서명 키 백업 및 복구 계획 마련

  • Google Play 업로드 키와 앱 서명 키 구분

26. 실제 프로젝트 적용 순서

처음부터 Google Play 자동 배포까지 모두 구현하기보다 단계적으로 적용하는 것이 좋습니다.

1단계: GitHub Actions 자동 빌드

main 브랜치에 Push할 때 디버그 APK를 생성합니다.

2단계: 자동 테스트

Unit Test와 Android Lint를 실행합니다.

3단계: 릴리스 AAB 생성

서명 키를 GitHub Secrets로 관리하고 AAB를 생성합니다.

4단계: 수동 릴리스 워크플로

workflow_dispatch로 필요한 시점에만 릴리스 빌드를 실행합니다.

5단계: Google Play 내부 테스트 업로드

서비스 계정과 Google Play Developer API를 연동합니다.

6단계: 운영 배포 분리

내부 테스트와 운영 배포를 별도의 승인 절차로 관리합니다.

이렇게 단계적으로 구성하면 문제 발생 시 원인을 파악하기 쉽습니다.

27. 마무리

Android 앱 배포 자동화는 단순히 빌드 명령어를 GitHub Actions에 등록하는 작업이 아닙니다.

앱의 빌드, 테스트, 서명, 버전 관리, 배포 권한까지 하나의 과정으로 관리하는 것입니다.

특히 여러 Android 앱을 운영하는 개인 개발자라면 다음과 같은 장점이 있습니다.

  1. 반복적인 빌드 작업을 줄일 수 있습니다.

  2. 빌드 환경을 일관되게 유지할 수 있습니다.

  3. 릴리스 전 테스트를 자동화할 수 있습니다.

  4. 서명 키와 배포 정보를 코드와 분리할 수 있습니다.

  5. 여러 Product Flavor를 체계적으로 관리할 수 있습니다.

  6. Google Play 내부 테스트 배포 과정을 단순화할 수 있습니다.

처음에는 자동 빌드와 테스트만 구성해도 충분한 효과를 얻을 수 있습니다.

이후 프로젝트가 안정되면 AAB 서명과 Google Play 내부 테스트 업로드를 추가하는 것이 좋습니다.

Android CI/CD의 핵심은 모든 배포를 무조건 자동화하는 것이 아니라, 반복 작업을 줄이면서도 릴리스의 안정성과 보안을 유지하는 것입니다.


참고 자료

태그: Android, Kotlin, GitHub Actions, CI/CD, Android Studio, Gradle, APK, AAB, Google Play Console, 자동 배포, 앱 서명, Keystore, Product Flavor, versionCode, Google Play Developer API