Skip to content

SCRUM-269 build: Configure product flavors#58

Merged
gdaegeun539 merged 3 commits into
project-lyrics:developfrom
gdaegeun539:feature/SCRUM-269-productflavor
Jun 12, 2026
Merged

SCRUM-269 build: Configure product flavors#58
gdaegeun539 merged 3 commits into
project-lyrics:developfrom
gdaegeun539:feature/SCRUM-269-productflavor

Conversation

@gdaegeun539

@gdaegeun539 gdaegeun539 commented Jun 11, 2026

Copy link
Copy Markdown
Member

Please check if the PR fulfills these requirements

  • The commit message follows our guidelines
  • Tests for the changes have been added (for bug fixes / features) - AI generated

What kind of change does this PR introduce?

  • Add feature

What is the current behavior?

기존에는 단일 빌드 variant만 존재하여 dev/staging/prod 환경 분리가 불가능했습니다.
Kakao native app key와 base URL이 하드코딩되어 있었습니다.

What is the new behavior (if this is a feature change)?

Android product flavor를 3가지 환경(dev/staging/prod)으로 분리합니다.

주요 변경사항:

  • Product Flavors 추가

    • dev: com.lyrics.feelin.dev — 개발 환경
    • staging: com.lyrics.feelin.qa — QA 환경
    • prod: com.lyrics.feelin — 운영 환경
  • Flavor별 설정

    • 각 flavor별 독립적인 applicationId
    • 환경별 BASE_URL (dev/staging: dev.feelinapp.com, prod: api.feelinapp.com)
    • 환경별 Kakao native app key 지원 (kakao.native.app.key.{dev,staging,prod})
    • flavor별 앱 이름 리소스 ([DEV] Feelin, [QA] Feelin, Feelin)
  • Build 설정 개선

    • flavor 요청 시에만 Kakao key 유효성 검증 (로컬 개발 시 다른 flavor 키 불필요)
    • local.properties.example 추가
    • NetworkModuleBuildConfig.BASE_URL을 사용하도록 변경
  • CI 업데이트

    • PR: assembleDevDebug 빌드 검증
    • develop push: stagingDebug + stagingRelease 추가 빌드
  • 테스트 추가

    • FlavorBuildConfigTest: flavor별 APPLICATION_ID, BASE_URL 검증
    • ExampleInstrumentedTest: flavor별 packageName assertion 지원

Does this PR introduce a breaking change?

  • 로컬 개발 환경에서 local.propertieskakao.native.app.key.stagingkakao.native.app.key.prod를 추가해야 합니다.
    • 바로 접근할 수 없는 키는 더미값으로 채워도 괜찮습니다.
  • 기존 ./gradlew :app:assembleDebug./gradlew :app:assembleDevDebug로 변경되었습니다.

ScreenShots

ProductFlavor Launcher icon example

Other information:

  • prod flavor의 signing key는 추후 생성이 필요합니다 (코드 내 MARK 주석 참조).
  • 카카오 Dev 프로젝트의 앱 ID는 dev flavor의 값으로 변경해두었습니다.

Summary by CodeRabbit

  • New Features

    • Added multi-environment build configuration supporting development, staging, and production variants with distinct branding and naming.
    • Automated CI/CD pipeline now builds environment-specific versions based on target branch.
  • Tests

    • Added validation tests for build configuration across environments.
  • Chores

    • Updated CI/CD workflow to conditionally build environment-specific variants.
    • Added configuration template for local development setup.

Introduce 'dev', 'staging', and 'prod' product flavors
to separate development, QA, and production environments.
Dynamic configuration includes custom application IDs, base URLs, and Kakao API keys.

- Define 'environment' flavor dimension with dev, staging, prod flavors
- Set up conditional Kakao key verification depending on Gradle tasks
- Update CI workflow to build flavor-specific outputs
- Inject BASE_URL dynamically and replace hardcoded value in NetworkModule
- Add tests to verify build configurations across flavors
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR refactors the Android build to support dev, staging, and prod flavors: per-flavor Kakao key resolution and BuildConfig injection, flavor-specific app names and applicationIds, Retrofit wired to BuildConfig.BASE_URL, CI build step adjustments, and tests validating per-flavor BuildConfig values.

Changes

Multi-Flavor Build Architecture

Layer / File(s) Summary
Gradle flavor helpers and per-flavor wiring
app/build.gradle.kts
Adds helper functions (requestedTasksMentionFlavor, requestedTasksIncludeAggregateBuild, shouldRequireKakaoNativeAppKey, kakaoNativeAppKey) to resolve Kakao keys from local.properties with env fallback; defines environment flavor dimension and dev/staging/prod flavors that set applicationId, BASE_URL, KAKAO_NATIVE_APP_KEY BuildConfig fields, and manifestPlaceholders["kakaoNativeAppKey"] per flavor.
Flavor string resources
app/src/dev/res/values/strings.xml, app/src/staging/res/values/strings.xml, app/src/prod/res/values/strings.xml
Adds app_name per flavor: "[DEV] Feelin", "[QA] Feelin", and Feelin.
Runtime wiring and instrumented test update
app/src/main/java/com/lyrics/feelin/core/data/di/NetworkModule.kt, app/src/androidTest/java/com/lyrics/feelin/ExampleInstrumentedTest.kt
Retrofit baseUrl now uses BuildConfig.BASE_URL; instrumented test compares package against BuildConfig.APPLICATION_ID.
BuildConfig unit tests
app/src/test/java/com/lyrics/feelin/FlavorBuildConfigTest.kt
Adds tests mapping BuildConfig.FLAVOR to expected applicationId/BASE_URL pairs and asserting BuildConfig.KAKAO_NATIVE_APP_KEY is non-blank for the requested variant.
CI workflow build steps
.github/workflows/android-ci.yml
Adds KAKAO_NATIVE_APP_KEY_STAGING env; replaces single assembleDebug with :app:assembleDevDebug (always), :app:assembleStagingDebug/StagingRelease (only on push to develop), and :app:assembleProdDebug/ProdRelease (only on push to main).
Local properties example
local.properties.example
Provides sdk.dir and placeholder keys kakao.native.app.key.dev, kakao.native.app.key.staging, kakao.native.app.key.prod.

Sequence Diagram(s)

sequenceDiagram
  participant CI as GitHub Actions
  participant Gradle as Gradle Daemon
  participant BuildConfig as BuildConfig
  participant App as Android App

  CI->>Gradle: trigger assembleDevDebug / assembleStaging* / assembleProd*
  Gradle->>Gradle: detect requested flavor (requestedTasksMentionFlavor / aggregate detection)
  Gradle->>Gradle: resolve kakaoNativeAppKey from local.properties or env
  Gradle->>BuildConfig: inject BASE_URL and KAKAO_NATIVE_APP_KEY per flavor
  App->>BuildConfig: read BASE_URL / KAKAO_NATIVE_APP_KEY at runtime
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰
I hop through gradle files with glee,
flavors blooming magically,
keys from local or the secret sky,
BuildConfig sings—no hardcoded lie,
tests nod, CI builds, and I nibble a pea.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately and specifically describes the main change: configuring Android product flavors with environment separation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3d78920b12

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/build.gradle.kts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (3)
local.properties.example (3)

2-4: ⚡ Quick win

Add developer guidance comments to improve onboarding experience.

The example file would benefit from comments explaining:

  • Where developers can obtain Kakao native app keys
  • That environment variables can be used as fallback (e.g., KAKAO_NATIVE_APP_KEY_DEV)
  • That builds will fail if keys are missing for the requested flavor

This documentation would significantly reduce setup friction for new developers joining the project.

📝 Proposed improvement with developer guidance
+# Kakao native app keys for each environment
+# Obtain these keys from Kakao Developers Console (https://developers.kakao.com/)
+# Alternatively, you can set environment variables:
+#   KAKAO_NATIVE_APP_KEY_DEV, KAKAO_NATIVE_APP_KEY_STAGING, KAKAO_NATIVE_APP_KEY_PROD
+# Note: Builds will fail if the key is missing for the flavor you're building
 kakao.native.app.key.dev=KAKAO_DEV_NATIVE_APP_KEY_HERE
 kakao.native.app.key.staging=KAKAO_QA_NATIVE_APP_KEY_HERE
 kakao.native.app.key.prod=KAKAO_PROD_NATIVE_APP_KEY_HERE
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@local.properties.example` around lines 2 - 4, Add brief inline comments above
the kakao.native.app.key.* entries explaining where to obtain Kakao native app
keys (link to Kakao developers console), note that environment variables (e.g.,
KAKAO_NATIVE_APP_KEY_DEV, KAKAO_NATIVE_APP_KEY_STAGING,
KAKAO_NATIVE_APP_KEY_PROD) can be used as fallbacks, and warn that builds will
fail for a requested flavor if the corresponding key (kakao.native.app.key.dev /
kakao.native.app.key.staging / kakao.native.app.key.prod) is missing; place
these comments near those exact property names so new devs see the guidance when
opening local.properties.example.

1-1: ⚡ Quick win

Clarify the sdk.dir placeholder to reduce setup confusion.

The current placeholder text "WILL_BE_AUTOMATICALLY_CREATED" may confuse developers about whether they need to manually set this value. Android Studio typically creates this entry automatically when opening the project.

Consider either:

  • Adding a comment explaining this is auto-generated by Android Studio
  • Providing an OS-specific example path (e.g., /Users/yourname/Library/Android/sdk for macOS)
  • Omitting this line entirely since it's auto-generated
📝 Proposed improvement with explanatory comment
+# sdk.dir is automatically set by Android Studio when you open the project
+# If needed, set it to your Android SDK path, e.g.:
+# sdk.dir=/Users/yourname/Library/Android/sdk (macOS)
+# sdk.dir=C:\\Users\\YourName\\AppData\\Local\\Android\\Sdk (Windows)
-sdk.dir=YOUR_ANDROID_SDK_DIR_WILL_BE_AUTOMATICALLY_CREATED
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@local.properties.example` at line 1, Update local.properties.example to
clarify the sdk.dir placeholder: replace
"YOUR_ANDROID_SDK_DIR_WILL_BE_AUTOMATICALLY_CREATED" with a short comment that
Android Studio typically generates this entry (e.g., "# Android Studio will
auto-create this file on first open"), and include optional OS-specific example
paths (macOS: /Users/yourname/Library/Android/sdk, Linux:
/home/yourname/Android/Sdk, Windows:
C:\Users\yourname\AppData\Local\Android\Sdk) or simply remove the sdk.dir line
if you prefer to avoid shipping a placeholder; ensure the file clearly states it
is an example and should not be committed with real credentials/paths.

3-3: 💤 Low value

Consider using "STAGING" instead of "QA" for consistency.

The placeholder uses "KAKAO_QA_NATIVE_APP_KEY_HERE", but the flavor is named "staging" throughout the codebase. While the staging app displays "[QA] Feelin", using "STAGING" in the placeholder would be more consistent with the property key kakao.native.app.key.staging.

♻️ Proposed consistency improvement
-kakao.native.app.key.staging=KAKAO_QA_NATIVE_APP_KEY_HERE
+kakao.native.app.key.staging=KAKAO_STAGING_NATIVE_APP_KEY_HERE
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@local.properties.example` at line 3, Update the placeholder value for the
staging Kakao native app key to match the "staging" flavor naming: replace the
current placeholder "KAKAO_QA_NATIVE_APP_KEY_HERE" referenced alongside the
property key kakao.native.app.key.staging with a "STAGING" variant (e.g.,
"KAKAO_STAGING_NATIVE_APP_KEY_HERE") so the placeholder is consistent with the
staging flavor used throughout the codebase.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/android-ci.yml:
- Around line 78-87: CI currently builds only dev and staging flavors (tasks
assembleDevDebug, assembleStagingDebug, assembleStagingRelease), so prod flavor
wiring isn't validated; add equivalent GitHub Actions steps that run ./gradlew
:app:assembleProdDebug --no-daemon --stacktrace (and optionally
:app:assembleProdRelease) with the same conditionals as staging (e.g., on push
to develop or on push to main/production branch as appropriate) to ensure the
prod BuildConfig/manifest/resources are compiled in CI.

In `@app/build.gradle.kts`:
- Line 99: The buildConfigField("String", "BASE_URL", ...) is set to an insecure
HTTP URL; change the value to use HTTPS (e.g., "https://api.feelinapp.com/") in
the build.gradle.kts so production traffic uses TLS, and update the expected
string in the test (FlavorBuildConfigTest.kt) to match the new HTTPS value so
tests continue to pass.
- Around line 22-46: requestedTasksContainFlavor currently uses substring
matching which allows aggregate tasks to bypass Kakao key validation; update
requestedTasksContainFlavor so it only returns true when the flavor is actually
present as a distinct task token or as a concrete variant token (e.g., matches
assemble<Flavor>, install<Flavor> or a colon-separated flavor segment), not
merely as a substring. Concretely, change requestedTasksContainFlavor to iterate
gradle.startParameter.taskNames and use a case-insensitive regex or
token-splitting logic to detect exact flavor occurrences (match patterns like
":...:assembleFlavor", ":...:installFlavor", or a colon-separated flavor
segment) and keep kakaoNativeAppKey using this tightened function for
validation.

---

Nitpick comments:
In `@local.properties.example`:
- Around line 2-4: Add brief inline comments above the kakao.native.app.key.*
entries explaining where to obtain Kakao native app keys (link to Kakao
developers console), note that environment variables (e.g.,
KAKAO_NATIVE_APP_KEY_DEV, KAKAO_NATIVE_APP_KEY_STAGING,
KAKAO_NATIVE_APP_KEY_PROD) can be used as fallbacks, and warn that builds will
fail for a requested flavor if the corresponding key (kakao.native.app.key.dev /
kakao.native.app.key.staging / kakao.native.app.key.prod) is missing; place
these comments near those exact property names so new devs see the guidance when
opening local.properties.example.
- Line 1: Update local.properties.example to clarify the sdk.dir placeholder:
replace "YOUR_ANDROID_SDK_DIR_WILL_BE_AUTOMATICALLY_CREATED" with a short
comment that Android Studio typically generates this entry (e.g., "# Android
Studio will auto-create this file on first open"), and include optional
OS-specific example paths (macOS: /Users/yourname/Library/Android/sdk, Linux:
/home/yourname/Android/Sdk, Windows:
C:\Users\yourname\AppData\Local\Android\Sdk) or simply remove the sdk.dir line
if you prefer to avoid shipping a placeholder; ensure the file clearly states it
is an example and should not be committed with real credentials/paths.
- Line 3: Update the placeholder value for the staging Kakao native app key to
match the "staging" flavor naming: replace the current placeholder
"KAKAO_QA_NATIVE_APP_KEY_HERE" referenced alongside the property key
kakao.native.app.key.staging with a "STAGING" variant (e.g.,
"KAKAO_STAGING_NATIVE_APP_KEY_HERE") so the placeholder is consistent with the
staging flavor used throughout the codebase.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c0827323-4084-427c-9b6e-c099e04332fb

📥 Commits

Reviewing files that changed from the base of the PR and between e0c1cf2 and 3d78920.

📒 Files selected for processing (9)
  • .github/workflows/android-ci.yml
  • app/build.gradle.kts
  • app/src/androidTest/java/com/lyrics/feelin/ExampleInstrumentedTest.kt
  • app/src/dev/res/values/strings.xml
  • app/src/main/java/com/lyrics/feelin/core/data/di/NetworkModule.kt
  • app/src/prod/res/values/strings.xml
  • app/src/staging/res/values/strings.xml
  • app/src/test/java/com/lyrics/feelin/FlavorBuildConfigTest.kt
  • local.properties.example

Comment thread .github/workflows/android-ci.yml
Comment thread app/build.gradle.kts Outdated
Comment thread app/build.gradle.kts
Configure the CI pipeline to run production debug and release builds
when pushing to the main branch.
Also define the KAKAO_NATIVE_APP_KEY_PROD environment variable
with a fallback dummy key for CI compile checks.

- Add KAKAO_NATIVE_APP_KEY_PROD to workflow env block
- Create 'Build prod debug' step triggered on push to main
- Create 'Build prod release' step triggered on push to main
Update app/build.gradle.kts to verify the Kakao native app key
not only for specific flavor tasks,
but also for aggregate Gradle tasks (like assemble, build, check) that compile those flavors.

- Refactor task verification to use regex for precise matching
- Add shouldRequireKakaoNativeAppKey to detect aggregate builds
@gdaegeun539 gdaegeun539 self-assigned this Jun 11, 2026
@gdaegeun539 gdaegeun539 added build 빌드 관련 파일 수정 init 초기 설정 labels Jun 11, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
.github/workflows/android-ci.yml (1)

90-96: 💤 Low value

Consider adding prod build validation on PRs to main.

Currently, PRs targeting main only run assembleDevDebug. Prod-specific wiring issues (BuildConfig fields, manifest placeholders, resources) won't surface until after the merge. If fail-fast validation before merge is desired, consider adding a conditional prod build for PRs to main:

      - name: Build prod debug
        if: github.event_name == 'push' && github.ref == 'refs/heads/main' || github.event_name == 'pull_request' && github.base_ref == 'main'
        run: ./gradlew :app:assembleProdDebug --no-daemon --stacktrace

This is optional if the current workflow (validate prod only at merge time) is intentional.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/android-ci.yml around lines 90 - 96, Update the job
conditionals for the "Build prod debug" (and optionally "Build prod release")
steps so they run not only on direct pushes to main but also for pull requests
targeting main by including github.event_name == 'pull_request' &&
github.base_ref == 'main' in the if expression; locate the steps named "Build
prod debug" and "Build prod release" and change their if conditions to combine
the existing push-to-main check with the pull_request-to-main check so
assembleProdDebug (and assembleProdRelease if desired) runs for PRs against main
as well.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.github/workflows/android-ci.yml:
- Around line 90-96: Update the job conditionals for the "Build prod debug" (and
optionally "Build prod release") steps so they run not only on direct pushes to
main but also for pull requests targeting main by including github.event_name ==
'pull_request' && github.base_ref == 'main' in the if expression; locate the
steps named "Build prod debug" and "Build prod release" and change their if
conditions to combine the existing push-to-main check with the
pull_request-to-main check so assembleProdDebug (and assembleProdRelease if
desired) runs for PRs against main as well.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6b75da01-613b-4486-a52a-867a408a2c2e

📥 Commits

Reviewing files that changed from the base of the PR and between 3d78920 and 2d17f37.

📒 Files selected for processing (2)
  • .github/workflows/android-ci.yml
  • app/build.gradle.kts

@gdaegeun539

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@gdaegeun539

Copy link
Copy Markdown
Member Author

AI 에이전트 코드리뷰에서 큰 문제가 발견되지 않았으므로 병합하겠습니다.
@hyunjung-choi 이번 건은 실행 설정이 변경되는 거라 한번 더 멘션드려요.

@gdaegeun539 gdaegeun539 merged commit f62fbb6 into project-lyrics:develop Jun 12, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build 빌드 관련 파일 수정 init 초기 설정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant