Skip to content

Conversation

@dmp100
Copy link
Contributor

@dmp100 dmp100 commented Oct 14, 2025

ISSUE

❗ WORK DESCRIPTION

  • GitHub Actions를 통한 CI/CD 파이프라인 구축
  • Firebase App Distribution 자동 배포 시스템 구성
  • Fastlane을 이용한 릴리스 자동화

주요 변경사항:

  • CI 워크플로우: 빌드 + 유닛 테스트 자동화
  • CD 워크플로우: main 브랜치 푸시 시 Firebase 자동 배포
  • Firebase SDK 및 Google Services 플러그인 추가
  • Gradle 캐싱으로 빌드 속도 개선

기술 스택:

  • GitHub Actions
  • Fastlane
  • Firebase App Distribution

📸 SCREENSHOT

CI/CD 파이프라인이므로 스크린샷 대신 워크플로우 구조 설명

Push to main/develop
↓
CI (ci.yml)
├─ Build APK
├─ Run Tests
└─ Upload Reports
↓
CD (distribute.yml) - main only
├─ Build Release APK
└─ Deploy to Firebase
↓
Testers receive notification

📢 TO REVIEWERS

  • Lint 체크는 Compose 버그로 인해 현재 비활성화했습니다 (추후 수정 예정)
  • main 혹은 develop 브랜치 머지 후 Actions 탭에서 워크플로우 정상 동작 확인 부탁드립니다
  • 첫 배포 시 Firebase App Distribution에서 테스터 초대 메일 확인 필요합니다
    ( 받아보고싶으신 분들은 이메일 주시면 좋을것같습니다.)

Summary by CodeRabbit

  • New Features

    • Integrated Firebase Analytics and enabled Google services configuration.
  • Chores

    • Set up automated build, test, and distribution pipeline.
    • Added release tooling for testing, beta, deploy, and app distribution.
    • Updated ignore rules to exclude platform, build, and tooling artifacts.
    • Cleaned repository by removing local and IDE-specific configuration files.
  • Documentation

    • Added usage guide for release tooling commands and workflows.

@dmp100 dmp100 requested a review from vvan2 October 14, 2025 03:11
@dmp100 dmp100 self-assigned this Oct 14, 2025
@dmp100 dmp100 added add ➕ 새 파일생성 setting ⚙️ 기초 세팅 규현 🐻 규현 전용 라벨 labels Oct 14, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 14, 2025

Walkthrough

This change adds Firebase integration (Google Services plugin, BOM, Analytics), introduces Fastlane with lanes for test/beta/deploy/distribute, and configures a GitHub Actions CI/CD pipeline that builds/tests and conditionally distributes via Firebase App Distribution. It also adds a Gemfile, updates .gitignore, and removes various IDE/local environment files.

Changes

Cohort / File(s) Summary
Version control ignores
/.gitignore
Add ignores for .DS_Store, Gradle build/, Fastlane artifacts, Firebase service account files; keep ignoring .cxx/.
Gradle internals cleanup
/.gradle/buildOutputCleanup/cache.properties, /.gradle/config.properties
Remove timestamp, gradle.version, and java.home overrides from Gradle cache/config.
IDE metadata removal
/.idea/gradle.xml, /.idea/workspace.xml
Delete project/workspace IDE configuration files.
IDE device cache update
/.idea/caches/deviceStreaming.xml
Modify device selection entries; add OnePlus API 35, remove several others.
Android app build config
/app/build.gradle.kts
Add Google Services plugin alias; conditionally load local.properties; add Firebase BOM and Analytics; adjust BASE_URL property loading.
Root build config
/build.gradle.kts, /gradle/libs.versions.toml
Register Google Services plugin; add Firebase versions, BOM and Analytics libraries; define google-services plugin version.
Firebase config
/app/google-services.json
Add Firebase project configuration JSON.
Fastlane setup
/Gemfile, /fastlane/Appfile, /fastlane/Fastfile, /fastlane/Pluginfile, /fastlane/README.md
Add Ruby Gemfile (fastlane), Fastlane Appfile, lanes (test/beta/deploy/distribute), Firebase App Distribution plugin, and autogenerated README.
Local machine config removal
/local.properties
Remove local SDK path and comments from version control.
CI/CD workflow
/.github/workflows/ci-cd.yml
Add GitHub Actions: build-and-test on push/PR; distribute on push to main/develop using Fastlane and Firebase service account secret.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Developer
  participant GH as GitHub
  participant GA as GitHub Actions
  participant Gradle as Gradle Build
  participant Test as Unit Tests
  participant Ruby as Ruby/Bundler
  participant Fastlane as Fastlane
  participant Firebase as Firebase App Dist.

  Dev->>GH: Push/PR to main or develop
  GH->>GA: Trigger workflow (build-and-test)
  GA->>Gradle: ./gradlew assembleDebug
  Gradle-->>GA: APK/outputs
  GA->>Test: ./gradlew test
  Test-->>GA: Test reports (artifact upload)

  alt push on main/develop and build success
    GH->>GA: Trigger distribute job
    GA->>Ruby: Setup Ruby 3.1 + bundle install
    GA->>GA: Decode FIREBASE_SECRET -> firebase-service-account.json
    GA->>Fastlane: bundle exec fastlane android distribute
    Fastlane->>Gradle: clean assembleRelease
    Gradle-->>Fastlane: release APK/AAB
    Fastlane->>Firebase: Upload build + notes + testers
    Firebase-->>Fastlane: Distribution result
  end
Loading
sequenceDiagram
  autonumber
  actor Dev as Developer
  participant FL as Fastlane
  participant Gradle as Gradle
  participant Crash as Crashlytics
  participant Play as Google Play
  participant FAD as Firebase App Dist.

  rect rgba(200,255,200,0.2)
  note right of FL: Lanes overview (Android)
  Dev->>FL: fastlane android test
  FL->>Gradle: gradle(task: "test")
  end

  rect rgba(200,200,255,0.2)
  Dev->>FL: fastlane android beta
  FL->>Gradle: clean assembleRelease
  Gradle-->>FL: Release build
  FL->>Crash: upload_crashlytics_symbols / triggers
  end

  rect rgba(255,240,200,0.2)
  Dev->>FL: fastlane android deploy
  FL->>Gradle: clean assembleRelease
  Gradle-->>FL: Release build
  FL->>Play: supply/upload to Play Console
  end

  rect rgba(255,220,220,0.2)
  Dev->>FL: fastlane android distribute
  FL->>Gradle: clean assembleRelease
  Gradle-->>FL: APK/AAB
  FL->>FAD: firebase_app_distribution (app_id, testers, notes)
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

I thump my paws on build-time ground,
New lanes hop in, with carrots bound. 🥕
Firebase clouds and workflows spin,
I nose-twitch at the testing win.
From burrow to the testers’ queue—
Ship it swift, with hop and woo!
(\\)_(/_/) 🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The PR includes deletion of IDE metadata files (.idea/gradle.xml, .idea/workspace.xml, .idea/caches/deviceStreaming.xml) and removal of local Gradle and SDK configuration files, which are not related to the CI/CD pipeline objectives and could be separated from this feature work. Please isolate IDE configuration and local environment cleanup into a separate commit or PR or provide justification for their inclusion alongside the CI/CD changes.
Title Check ❓ Inconclusive The title “Setting/#3-init-cicd” resembles a branch name rather than a concise summary and includes issue tagging and punctuation that do not clearly convey the main change; it is too generic and not formatted as a clear, standalone sentence. Please rename the PR title to a clear, descriptive sentence such as “Initialize CI/CD pipeline with GitHub Actions, Fastlane, and Firebase App Distribution” to better summarize the primary change.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues Check ✅ Passed All coding tasks from issue #3 have been addressed: Firebase plugins are configured in build.gradle, Fastlane is set up for automated App Distribution, and GitHub Actions workflows build, test, and deploy to testers as specified.
Description Check ✅ Passed The description follows the repository template by including the ISSUE, ❗ WORK DESCRIPTION, 📸 SCREENSHOT, and 📢 TO REVIEWERS sections, and it clearly details the CI/CD and Fastlane setup along with workflow steps.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch setting/#3-init-CICD

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 10

🧹 Nitpick comments (7)
Gemfile (1)

1-6: LGTM with a minor suggestion.

The Gemfile structure is correct. Consider pinning the Fastlane version for reproducible builds (e.g., gem "fastlane", "~> 2.0"), though this is optional for development.

fastlane/Fastfile (3)

46-46: Consider making tester list configurable.

The tester email is hardcoded. For better maintainability, consider using an environment variable or a configuration file that can be updated without modifying the Fastfile.

Example approach:

-      testers: "[email protected]",
+      testers: ENV["FIREBASE_TESTERS"] || "[email protected]",

Then set FIREBASE_TESTERS in your workflow as a secret or configuration variable.


24-31: Unused lane references unconfigured Crashlytics.

The beta lane calls crashlytics but Crashlytics is not configured in this PR. If this lane is not currently used, consider removing it or adding a TODO comment indicating future plans.


33-37: Unused lane references unconfigured Play Store.

The deploy lane calls upload_to_play_store but Google Play Store configuration is not present in this PR. If this lane is not currently used, consider removing it or adding a TODO comment indicating future plans.

.github/workflows/distribute.yml (3)

15-15: Update GitHub Actions to v4.

The actions/checkout@v3 action is outdated and may not run on the latest GitHub-hosted runners.

Apply this diff:

-        uses: actions/checkout@v3
+        uses: actions/checkout@v4

Based on static analysis hints.


24-24: Update GitHub Actions to v4.

The actions/setup-java@v3 action is outdated and may not run on the latest GitHub-hosted runners.

Apply this diff:

-        uses: actions/setup-java@v3
+        uses: actions/setup-java@v4

Based on static analysis hints.


30-30: Update GitHub Actions to v4.

The actions/cache@v3 action is outdated and may not run on the latest GitHub-hosted runners.

Apply this diff:

-        uses: actions/cache@v3
+        uses: actions/cache@v4

Based on static analysis hints.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6d84673 and 922e6b5.

⛔ Files ignored due to path filters (10)
  • .gradle/8.13/checksums/checksums.lock is excluded by !**/*.lock
  • .gradle/8.13/executionHistory/executionHistory.bin is excluded by !**/*.bin
  • .gradle/8.13/executionHistory/executionHistory.lock is excluded by !**/*.lock
  • .gradle/8.13/fileChanges/last-build.bin is excluded by !**/*.bin
  • .gradle/8.13/fileHashes/fileHashes.bin is excluded by !**/*.bin
  • .gradle/8.13/fileHashes/fileHashes.lock is excluded by !**/*.lock
  • .gradle/8.13/fileHashes/resourceHashesCache.bin is excluded by !**/*.bin
  • .gradle/buildOutputCleanup/buildOutputCleanup.lock is excluded by !**/*.lock
  • .gradle/buildOutputCleanup/outputFiles.bin is excluded by !**/*.bin
  • Gemfile.lock is excluded by !**/*.lock
📒 Files selected for processing (18)
  • .github/workflows/ci.yml (1 hunks)
  • .github/workflows/distribute.yml (1 hunks)
  • .gitignore (1 hunks)
  • .gradle/buildOutputCleanup/cache.properties (0 hunks)
  • .gradle/config.properties (0 hunks)
  • .idea/gradle.xml (0 hunks)
  • .idea/workspace.xml (0 hunks)
  • Gemfile (1 hunks)
  • app/build.gradle.kts (2 hunks)
  • app/google-services.json (1 hunks)
  • build.gradle.kts (1 hunks)
  • fastlane/Appfile (1 hunks)
  • fastlane/Fastfile (1 hunks)
  • fastlane/Pluginfile (1 hunks)
  • fastlane/README.md (1 hunks)
  • fastlane/report.xml (1 hunks)
  • gradle/libs.versions.toml (4 hunks)
  • local.properties (0 hunks)
💤 Files with no reviewable changes (5)
  • .idea/gradle.xml
  • .gradle/buildOutputCleanup/cache.properties
  • .gradle/config.properties
  • local.properties
  • .idea/workspace.xml
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/distribute.yml

15-15: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


24-24: the runner of "actions/setup-java@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


30-30: the runner of "actions/cache@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.github/workflows/ci.yml

15-15: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


18-18: the runner of "actions/setup-java@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


24-24: the runner of "actions/cache@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


44-44: the runner of "actions/upload-artifact@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🪛 Gitleaks (8.28.0)
app/google-services.json

[high] 18-18: Uncovered a GCP API key, which could lead to unauthorized access to Google Cloud services and data breaches.

(gcp-api-key)

🪛 markdownlint-cli2 (0.18.1)
fastlane/README.md

4-4: Heading style
Expected: setext; Actual: atx

(MD003, heading-style)


14-14: Heading style
Expected: setext; Actual: atx

(MD003, heading-style)


16-16: Heading style
Expected: setext; Actual: atx

(MD003, heading-style)


18-18: Heading style
Expected: setext; Actual: atx

(MD003, heading-style)


26-26: Heading style
Expected: setext; Actual: atx

(MD003, heading-style)


34-34: Heading style
Expected: setext; Actual: atx

(MD003, heading-style)


42-42: Heading style
Expected: setext; Actual: atx

(MD003, heading-style)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: distribute
🔇 Additional comments (13)
app/google-services.json (1)

1-29: LGTM! Static analysis false positive.

The google-services.json file is correctly structured for Firebase integration. The API key flagged by Gitleaks is a Firebase client configuration key (not a secret) that is meant to be included in the app. Firebase restricts its usage through console settings (package name restrictions, SHA fingerprint verification, etc.).

fastlane/README.md (1)

1-56: LGTM! Auto-generated documentation.

The README is auto-generated by Fastlane and provides helpful documentation for the available lanes. The markdown style hints from static analysis can be safely ignored since this file is regenerated automatically.

Note: The Xcode installation instructions (lines 6-10) are part of Fastlane's default template and are harmless for an Android-only project.

build.gradle.kts (1)

11-11: LGTM!

The Google Services plugin is correctly added using the version catalog alias and apply false at the root level, following Gradle best practices. It will be applied in the app module where needed.

app/build.gradle.kts (2)

10-10: LGTM!

The Google Services plugin is correctly applied in the app module, enabling Firebase services integration.


82-83: LGTM!

Firebase dependencies are correctly configured using the BOM (Bill of Materials) platform dependency, which ensures version consistency across all Firebase libraries. The Analytics library is properly imported through the BOM.

fastlane/Appfile (1)

2-2: LGTM!

The package name correctly matches the configuration in google-services.json.

fastlane/Pluginfile (1)

1-5: LGTM!

The Pluginfile correctly declares the Firebase App Distribution plugin dependency.

fastlane/Fastfile (1)

39-50: LGTM on the distribute lane logic!

The distribute lane correctly builds a release APK and distributes it via Firebase App Distribution. The configuration parameters (app ID, release notes, artifact type) are appropriate.

.github/workflows/distribute.yml (2)

39-43: LGTM on Firebase credentials handling!

The workflow correctly decodes the base64-encoded Firebase service account secret and writes it to a file that matches the Fastfile reference (assuming the Fastfile is updated per earlier comment).


17-21: Good job on the workflow structure!

The workflow properly sets up the required environment (Ruby, JDK, Gradle caching) and executes Fastlane distribution. The use of bundler-cache and Gradle caching will improve build performance.

Also applies to: 23-28, 29-37, 45-49

gradle/libs.versions.toml (3)

52-54: LGTM on version declarations!

The Google Services plugin version and Firebase BOM version are properly declared.


107-109: LGTM on Firebase library declarations!

The Firebase BOM and Analytics library are correctly declared. Using the BOM pattern ensures consistent Firebase library versions across the project.


121-121: LGTM on plugin declaration!

The Google Services plugin is properly declared and references the correct version.

@@ -0,0 +1,2 @@
json_key_file("") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Empty json_key_file path will cause Fastlane failures.

The json_key_file is set to an empty string, which will cause Firebase App Distribution to fail. Based on the distribute.yml workflow (which decodes FIREBASE_SECRET to firebase-service-account.json), this should point to that file.

Apply this diff:

-json_key_file("") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
+json_key_file("firebase-service-account.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one

Alternatively, if you want to support both local development and CI, you can use an environment variable:

json_key_file(ENV["FIREBASE_KEY_PATH"] || "firebase-service-account.json")
🤖 Prompt for AI Agents
In fastlane/Appfile around line 1, the json_key_file is set to an empty string
which breaks Firebase App Distribution; update this line to point to the decoded
CI secret file (firebase-service-account.json) or use an environment-aware value
so local dev and CI both work — e.g. set the json_key_file to use
ENV["FIREBASE_KEY_PATH"] with a fallback to "firebase-service-account.json".

Comment on lines 1 to 23
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="fastlane.lanes">




<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000216">

</testcase>


<testcase classname="fastlane.lanes" name="1: clean assembleRelease" time="13.863117">

</testcase>


<testcase classname="fastlane.lanes" name="2: firebase_app_distribution" time="17.440506">

</testcase>

</testsuite>
</testsuites>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Remove generated test report from VCS.

The fastlane/report.xml file is a generated artifact from local Fastlane execution and should not be committed to version control. These files are regenerated on each run and will cause unnecessary merge conflicts.

Apply this fix:

  1. Remove the file from the repository:
git rm fastlane/report.xml
  1. Add the following pattern to your .gitignore:
+# Fastlane
+fastlane/report.xml
+fastlane/Preview.html
+fastlane/screenshots
+fastlane/test_output
🤖 Prompt for AI Agents
In fastlane/report.xml around lines 1 to 23, this is a generated Fastlane test
report that should not be committed; remove the file from the repository (git rm
fastlane/report.xml) and update the repository .gitignore to ignore Fastlane
generated reports (add an appropriate pattern such as fastlane/report.xml or
fastlane/*.xml) so the file is not tracked in future commits.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
.gitignore (1)

44-45: Remove duplicate Gradle ignore rules.

.gradle/ and build/ are already ignored at Lines 19-20; keeping the duplicates just adds noise. Please drop the redundant entries.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 922e6b5 and d23c18b.

📒 Files selected for processing (4)
  • .github/workflows/ci-cd.yml (1 hunks)
  • .gitignore (1 hunks)
  • .idea/caches/deviceStreaming.xml (1 hunks)
  • app/build.gradle.kts (3 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .idea/caches/deviceStreaming.xml
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/build.gradle.kts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-and-test

Comment on lines +80 to +85
- name: Decode Firebase service account
env:
FIREBASE_SECRET: ${{ secrets.FIREBASE_SECRET }}
run: |
echo $FIREBASE_SECRET | base64 --decode > firebase-service-account.json
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Quote the secret before decoding.

Use echo "$FIREBASE_SECRET" (or printf '%s' "$FIREBASE_SECRET") to avoid shell word-splitting/globbing corrupting the Base64 payload. Keeps the decoded JSON intact across environments.

-          echo $FIREBASE_SECRET | base64 --decode > firebase-service-account.json
+          echo "$FIREBASE_SECRET" | base64 --decode > firebase-service-account.json
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Decode Firebase service account
env:
FIREBASE_SECRET: ${{ secrets.FIREBASE_SECRET }}
run: |
echo $FIREBASE_SECRET | base64 --decode > firebase-service-account.json
- name: Decode Firebase service account
env:
FIREBASE_SECRET: ${{ secrets.FIREBASE_SECRET }}
run: |
echo "$FIREBASE_SECRET" | base64 --decode > firebase-service-account.json
🤖 Prompt for AI Agents
.github/workflows/ci-cd.yml around lines 80 to 85: the workflow decodes the
FIREBASE_SECRET using echo $FIREBASE_SECRET which allows shell
word-splitting/globbing to corrupt the Base64 payload; change the command to use
a quoted expansion or printf (e.g., use echo "$FIREBASE_SECRET" or printf '%s'
"$FIREBASE_SECRET") before piping to base64 --decode so the secret is preserved
exactly and the decoded JSON remains valid.

@vvan2
Copy link
Member

vvan2 commented Oct 14, 2025

고생하셨습니다!!

@dmp100 dmp100 merged commit cada1ab into develop Oct 14, 2025
3 checks passed
This was referenced Oct 14, 2025
@vvan2 vvan2 changed the title Setting/#3-init-cicd [setting/#3] init-cicd Oct 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

add ➕ 새 파일생성 setting ⚙️ 기초 세팅 규현 🐻 규현 전용 라벨

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[setting] Project CICD

3 participants