diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0849a83..ac5acff 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,44 +1,59 @@
-name: CI
+name: iOS CI
on:
- push:
- branches: [ main, develop ]
pull_request:
- branches: [ main ]
+ branches: [main, feat/week1-foundations]
+ push:
+ tags:
+ - "v*"
jobs:
test:
- name: Unit Tests
- runs-on: macos-latest
-
+ name: Run Tests
+ runs-on: macos-14
steps:
- - name: Checkout
- uses: actions/checkout@v4
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Set up Ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: '3.3'
+ bundler-cache: true
- - name: Select Xcode
- run: sudo xcode-select -s /Applications/Xcode_16.0.app
+ - name: Select Xcode version
+ run: sudo xcode-select -s /Applications/Xcode_16.0.app || sudo xcode-select -s /Applications/Xcode.app
- - name: Build and Test
- run: |
- xcodebuild -scheme "WorkOut Log" \
- -destination 'platform=iOS Simulator,name=iPhone 16' \
- clean build test
+ - name: Install dependencies
+ run: bundle install
- ui-test:
- name: UI Tests (Optional)
- runs-on: macos-latest
- if: github.event_name == 'push' && github.ref == 'refs/heads/main'
+ - name: Run tests
+ run: bundle exec fastlane tests
+ beta:
+ name: Deploy to TestFlight
+ if: startsWith(github.ref, 'refs/tags/v')
+ needs: test
+ runs-on: macos-14
steps:
- - name: Checkout
- uses: actions/checkout@v4
-
- - name: Select Xcode
- run: sudo xcode-select -s /Applications/Xcode_16.0.app
-
- - name: UI Test
- run: |
- xcodebuild -scheme "WorkOut Log" \
- -destination 'platform=iOS Simulator,name=iPhone 16' \
- clean build-for-testing test-without-building \
- -only-testing:WorkOut\ LogUITests
\ No newline at end of file
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Set up Ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: '3.3'
+ bundler-cache: true
+
+ - name: Select Xcode version
+ run: sudo xcode-select -s /Applications/Xcode_16.0.app || sudo xcode-select -s /Applications/Xcode.app
+
+ - name: Install dependencies
+ run: bundle install
+
+ - name: Build and upload to TestFlight
+ env:
+ ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
+ ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
+ ASC_KEY_CONTENT: ${{ secrets.ASC_KEY_CONTENT }}
+ run: bundle exec fastlane beta
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c24ca07
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,98 @@
+# Xcode
+#
+# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
+
+## User settings
+xcuserdata/
+
+## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
+*.xcscmblueprint
+*.xccheckout
+
+## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
+build/
+DerivedData/
+*.moved-aside
+*.pbxuser
+!default.pbxuser
+*.mode1v3
+!default.mode1v3
+*.mode2v3
+!default.mode2v3
+*.perspectivev3
+!default.perspectivev3
+
+## Obj-C/Swift specific
+*.hmap
+
+## App packaging
+*.ipa
+*.dSYM.zip
+*.dSYM
+
+## Playgrounds
+timeline.xctimeline
+playground.xcworkspace
+
+# Swift Package Manager
+#
+# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
+# Packages/
+# Package.pins
+# Package.resolved
+# *.xcodeproj
+#
+# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
+# hence it is not needed unless you have added a package configuration file to your project
+# .swiftpm
+
+.build/
+
+# CocoaPods
+#
+# We recommend against adding the Pods directory to your .gitignore. However
+# you should judge for yourself, the pros and cons are mentioned at:
+# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
+#
+# Pods/
+#
+# Add this line if you want to avoid checking in source code from the Xcode workspace
+# *.xcworkspace
+
+# Carthage
+#
+# Add this line if you want to avoid checking in source code from Carthage dependencies.
+# Carthage/Checkouts
+
+Carthage/Build/
+
+# Accio dependency management
+Dependencies/
+.accio/
+
+# fastlane
+#
+# It is recommended to not store the screenshots in the git repo.
+# Instead, use fastlane to re-generate the screenshots whenever they are needed.
+# For more information about the recommended setup visit:
+# https://docs.fastlane.tools/best-practices/source-control/#source-control
+
+fastlane/report.xml
+fastlane/Preview.html
+fastlane/screenshots/**/*.png
+fastlane/test_output
+fastlane/README.md
+
+# Code Injection
+#
+# After new code Injection tools there's a generated folder /iOSInjectionProject
+# https://github.com/johnno1962/injectionforxcode
+
+iOSInjectionProject/
+
+# Ruby / Bundler
+vendor/bundle/
+.bundle/
+
+# macOS
+.DS_Store
diff --git a/.ruby-version b/.ruby-version
new file mode 100644
index 0000000..15a2799
--- /dev/null
+++ b/.ruby-version
@@ -0,0 +1 @@
+3.3.0
diff --git a/Docs/Fastlane_Guide.md b/Docs/Fastlane_Guide.md
new file mode 100644
index 0000000..8200be9
--- /dev/null
+++ b/Docs/Fastlane_Guide.md
@@ -0,0 +1,887 @@
+# Fastlane 사용 가이드 — WorkOut Log
+
+**문서 버전:** 1.0.0
+**작성일:** 2025년 10월 19일
+**작성자:** Ben (오정석) with Claude
+**대상:** iOS 개발자, CI/CD 운영자, 미래의 나
+
+---
+
+## 📚 목차
+
+1. [Fastlane 개요](#fastlane-개요)
+2. [환경 준비](#환경-준비)
+3. [로컬 사용법](#로컬-사용법)
+4. [Lane 상세 설명](#lane-상세-설명)
+5. [버전 관리 플로우](#버전-관리-플로우)
+6. [CI 워크플로우](#ci-워크플로우)
+7. [Troubleshooting](#troubleshooting)
+8. [보안 주의사항](#보안-주의사항)
+9. [부록: Fastfile 주요 옵션](#부록-fastfile-주요-옵션)
+
+---
+
+## Fastlane 개요
+
+### 왜 Fastlane을 사용하는가?
+
+**반복 작업 자동화**
+- 수동으로 Xcode에서 Archive → Export → Upload를 반복하는 대신, 한 줄 명령으로 완료
+- 빌드 번호 증가, 테스트 실행, 아카이브 생성, TestFlight 업로드를 단일 워크플로우로 통합
+
+**일관성 보장**
+- 팀원 간 동일한 빌드/배포 절차 보장
+- 로컬 개발 환경과 CI 환경에서 동일한 스크립트 사용
+
+**CI/CD 연계**
+- GitHub Actions와 완벽하게 통합
+- 태그 푸시만으로 자동 TestFlight 배포
+
+---
+
+## 환경 준비
+
+### 1. Ruby & Bundler 설치 확인
+
+```bash
+# Ruby 버전 확인 (3.3.0 권장)
+ruby --version
+
+# Bundler 설치
+gem install bundler
+```
+
+### 2. Fastlane 설치
+
+```bash
+# 프로젝트 루트 디렉토리로 이동
+cd "/Users/ojung/Documents/Dev/WorkOut Log"
+
+# 의존성 설치 (Gemfile 기준)
+bundle install
+```
+
+**설치 확인:**
+```bash
+bundle exec fastlane --version
+# 출력 예: fastlane 2.219.0
+```
+
+### 3. Xcode 16 선택
+
+```bash
+# Xcode.app 경로 확인
+xcode-select -p
+
+# Xcode 16으로 전환 (필요 시)
+sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
+
+# 또는 Xcode 16.0.app이 별도로 있다면
+sudo xcode-select -s /Applications/Xcode_16.0.app/Contents/Developer
+```
+
+### 4. App Store Connect API Key 설정
+
+#### 4.1 API Key 생성 (최초 1회)
+
+1. [App Store Connect → Users and Access → Keys](https://appstoreconnect.apple.com/access/api) 접속
+2. **"Generate API Key"** 클릭
+3. 이름: `GitHub Actions CI` (또는 원하는 이름)
+4. 역할: **App Manager** 선택
+5. **Generate** 클릭
+6. `.p8` 파일 다운로드 (예: `AuthKey_AB12CD34EF.p8`)
+7. **Key ID**와 **Issuer ID** 복사 (나중에 필요)
+
+⚠️ **주의:** `.p8` 파일은 한 번만 다운로드 가능. 안전한 곳에 백업하세요.
+
+#### 4.2 macOS 로컬 환경변수 설정
+
+**방법 1: 터미널 세션에서 임시 설정**
+```bash
+# Key ID (예: AB12CD34EF)
+export ASC_KEY_ID="YOUR_KEY_ID"
+
+# Issuer ID (UUID 형식)
+export ASC_ISSUER_ID="YOUR_ISSUER_ID"
+
+# .p8 파일을 Base64로 인코딩
+export ASC_KEY_CONTENT=$(base64 -i /path/to/AuthKey_AB12CD34EF.p8)
+
+# 설정 확인
+echo $ASC_KEY_ID
+```
+
+**방법 2: ~/.zshrc 또는 ~/.bash_profile에 영구 설정**
+```bash
+# 파일 편집
+nano ~/.zshrc
+
+# 아래 내용 추가 (실제 값으로 교체)
+export ASC_KEY_ID="AB12CD34EF"
+export ASC_ISSUER_ID="12345678-1234-1234-1234-123456789abc"
+export ASC_KEY_CONTENT="LS0tLS1CRUdJTi..." # Base64 인코딩된 값
+
+# 저장 후 적용
+source ~/.zshrc
+```
+
+**⚠️ 보안:** 실제 운영에서는 `.p8` 파일을 안전한 곳에 보관하고, 환경변수는 로컬 머신에만 설정하세요. Git에 커밋하지 마세요!
+
+#### 4.3 GitHub Actions Secrets 설정
+
+1. GitHub 저장소 → **Settings** → **Secrets and variables** → **Actions**
+2. **"New repository secret"** 클릭
+3. 아래 3개의 Secret 추가:
+
+| Name | Value | 설명 |
+|------|-------|------|
+| `ASC_KEY_ID` | `AB12CD34EF` | API Key ID |
+| `ASC_ISSUER_ID` | `12345678-1234-...` | Issuer ID (UUID) |
+| `ASC_KEY_CONTENT` | `LS0tLS1CRUdJTi...` | Base64 인코딩된 .p8 파일 내용 |
+
+**Base64 인코딩 방법:**
+```bash
+base64 -i AuthKey_AB12CD34EF.p8 | pbcopy
+# 클립보드에 복사됨 → GitHub Secret에 붙여넣기
+```
+
+---
+
+## 로컬 사용법
+
+### 프로젝트 구성 확인
+
+| 항목 | 값 |
+|------|-----|
+| **프로젝트 파일** | `WorkOut Log.xcodeproj` |
+| **스킴** | `workout_log` |
+| **번들 ID** | `com.Ben.WorkOut-Log` |
+
+**만약 `.xcworkspace` 사용 시:**
+- `Fastfile`에서 `project: XCODEPROJ`를 `workspace: "WorkOut Log.xcworkspace"`로 변경
+- 예시:
+ ```ruby
+ gym(
+ workspace: "WorkOut Log.xcworkspace",
+ scheme: SCHEME,
+ # ...
+ )
+ ```
+
+### 명령어 실행 예시
+
+#### 1. 테스트 실행
+```bash
+bundle exec fastlane tests
+```
+**출력 예시:**
+```
+[✔] 🚀
+[15:30:45]: -----------------------
+[15:30:45]: --- Step: run_tests ---
+[15:30:45]: -----------------------
+[15:30:45]: $ xcodebuild -scheme workout_log -project 'WorkOut Log.xcodeproj' ...
+Test Suite 'All tests' passed at 2025-10-19 15:32:10.
+ Executed 42 tests, with 0 failures (0 unexpected) in 12.345 seconds
+[15:32:11]: ✅ Tests passed successfully
+```
+
+#### 2. 빌드 번호 증가
+```bash
+bundle exec fastlane bump_build
+```
+**효과:**
+- `CFBundleVersion` 값이 1 증가 (예: 5 → 6)
+- 자동 커밋: `chore(ci): bump build number to 6`
+
+#### 3. 로컬 아카이브 생성
+```bash
+bundle exec fastlane build
+```
+**출력:**
+- `build/` 디렉토리에 `.ipa` 파일 생성
+- `build/` 디렉토리에 `.dSYM.zip` 파일 생성
+
+**용도:** App Store Connect 수동 업로드, 로컬 테스트 배포
+
+#### 4. TestFlight 자동 배포 (beta)
+```bash
+# 환경변수 설정 확인
+echo $ASC_KEY_ID
+
+# 실행
+bundle exec fastlane beta
+```
+**동작 단계:**
+1. 빌드 번호 자동 증가
+2. 전체 테스트 실행
+3. App Store 아카이브 생성
+4. TestFlight 업로드
+
+**출력 예시:**
+```
+[15:40:12]: Incrementing build number to 7
+[15:40:15]: Running tests on iPhone 16...
+[15:42:30]: ✅ All tests passed
+[15:42:35]: Building archive...
+[15:45:10]: Exporting IPA...
+[15:46:20]: Uploading to TestFlight...
+[15:48:50]: ✅ Successfully uploaded build 7 to TestFlight!
+```
+
+#### 5. App Store Connect 업로드 (release)
+```bash
+bundle exec fastlane release
+```
+**효과:**
+- 아카이브 생성 후 App Store Connect 업로드
+- `submit_for_review: false`로 설정되어 있어 자동 심사 제출은 안 됨
+- App Store Connect에서 수동으로 "Submit for Review" 클릭 필요
+
+---
+
+## Lane 상세 설명
+
+### 1. `tests` — 단위 테스트 실행
+
+**명령:**
+```bash
+bundle exec fastlane tests
+```
+
+**동작:**
+- iPhone 16 시뮬레이터에서 `workout_log` 스킴 테스트 실행
+- 코드 커버리지 활성화 (`code_coverage: true`)
+- `clean: true`로 빌드 캐시 초기화
+
+**입력:** 없음
+**출력:** 테스트 결과 (성공/실패), 커버리지 리포트
+
+**사전조건:**
+- Xcode 16 선택됨 (`xcode-select`)
+- 시뮬레이터 설치됨
+
+**실패 시:**
+- 로그에서 실패한 테스트 케이스 확인
+- Xcode에서 해당 테스트 직접 실행하여 디버깅
+
+---
+
+### 2. `bump_build` — 빌드 번호 증가
+
+**명령:**
+```bash
+bundle exec fastlane bump_build
+```
+
+**동작:**
+1. `CFBundleVersion` 값 1 증가 (예: `5` → `6`)
+2. `WorkOut Log.xcodeproj/project.pbxproj` 파일 수정
+3. Git 커밋: `chore(ci): bump build number to 6`
+
+**입력:** 없음
+**출력:** 새 빌드 번호, Git 커밋
+
+**사전조건:**
+- Git 작업 트리가 깨끗해야 함 (uncommitted changes 없음)
+- Git 저장소 초기화됨
+
+**실패 시:**
+- Uncommitted changes가 있으면 커밋 실패
+- 먼저 `git status` 확인 후 변경사항 커밋 또는 stash
+
+**롤백:**
+```bash
+git reset --hard HEAD~1 # 마지막 커밋 취소
+```
+
+---
+
+### 3. `build` — App Store 아카이브 생성
+
+**명령:**
+```bash
+bundle exec fastlane build
+```
+
+**동작:**
+- `workout_log` 스킴으로 App Store용 아카이브 빌드
+- Automatic Signing 사용 (Xcode 프로젝트 설정 따름)
+- IPA 및 dSYM 파일 생성
+
+**입력:** 없음
+**출력:**
+- `build/WorkOut Log.ipa`
+- `build/WorkOut Log.app.dSYM.zip`
+
+**사전조건:**
+- Xcode 프로젝트에서 Automatic Signing 활성화
+- Apple Developer 계정 로그인 (Xcode → Settings → Accounts)
+
+**실패 시:**
+- Code signing 오류 → Xcode에서 Signing & Capabilities 탭 확인
+- Provisioning profile 문제 → Xcode → Preferences → Accounts에서 "Download Manual Profiles" 클릭
+
+---
+
+### 4. `beta` — TestFlight 자동 배포
+
+**명령:**
+```bash
+bundle exec fastlane beta
+```
+
+**동작 단계:**
+1. **빌드 번호 증가** (`increment_build_number`)
+2. **테스트 실행** (`run_tests`)
+3. **아카이브 생성** (`gym`)
+4. **TestFlight 업로드** (`pilot`)
+
+**입력:**
+- 환경변수: `ASC_KEY_ID`, `ASC_ISSUER_ID`, `ASC_KEY_CONTENT`
+
+**출력:**
+- TestFlight에 새 빌드 등록
+- 빌드 번호가 증가된 Git 커밋 (로컬에서만, 푸시는 안 됨)
+
+**사전조건:**
+- App Store Connect API Key 환경변수 설정
+- 앱이 App Store Connect에 등록되어 있어야 함
+- 첫 빌드는 Xcode에서 수동으로 1회 업로드 후 Fastlane 사용 권장
+
+**실패 시:**
+- **Auth 오류:** `ASC_KEY_*` 환경변수 확인
+- **테스트 실패:** 먼저 `bundle exec fastlane tests` 단독 실행하여 디버깅
+- **업로드 실패:** App Store Connect 상태 확인 (점검 중인지)
+
+**TestFlight 반영 시간:**
+- 업로드 완료 후 5~30분 내 TestFlight에서 확인 가능
+- "Processing"으로 표시되면 정상
+
+---
+
+### 5. `release` — App Store Connect 업로드
+
+**명령:**
+```bash
+bundle exec fastlane release
+```
+
+**동작:**
+1. App Store 아카이브 생성
+2. App Store Connect에 업로드
+3. **자동 심사 제출 안 함** (`submit_for_review: false`)
+
+**입력:**
+- 환경변수: `ASC_KEY_ID`, `ASC_ISSUER_ID`, `ASC_KEY_CONTENT`
+
+**출력:**
+- App Store Connect에 빌드 등록 (수동 심사 제출 대기 상태)
+
+**사전조건:**
+- `beta` lane과 동일
+- 메타데이터(스크린샷, 설명 등)는 App Store Connect UI에서 별도 관리
+
+**실패 시:**
+- `beta` lane과 동일한 트러블슈팅 적용
+
+**다음 단계:**
+1. [App Store Connect](https://appstoreconnect.apple.com) 접속
+2. 앱 선택 → 버전 선택
+3. **"Submit for Review"** 클릭
+4. 심사 질문 응답 후 제출
+
+---
+
+## 버전 관리 플로우
+
+### 버전 번호 정책
+
+**CFBundleShortVersionString (마케팅 버전):**
+- 형식: `MAJOR.MINOR.PATCH` (예: `1.0.0`)
+- **수동 관리:** Xcode 또는 `agvtool new-marketing-version X.Y.Z`로 변경
+- 의미:
+ - `MAJOR`: 호환성 깨지는 변경
+ - `MINOR`: 기능 추가
+ - `PATCH`: 버그 수정
+
+**CFBundleVersion (빌드 번호):**
+- 형식: 정수 (예: `1`, `2`, `3`, ...)
+- **자동 관리:** `bundle exec fastlane bump_build` 또는 `beta` lane 실행 시 자동 증가
+- App Store는 빌드 번호가 이전 빌드보다 커야 함
+
+### 릴리스 플로우 예시
+
+#### 시나리오 1: 첫 릴리스 (1.0.0)
+
+```bash
+# 1. 마케팅 버전 설정 (Xcode에서 수동 또는)
+agvtool new-marketing-version 1.0.0
+
+# 2. Beta 배포 (빌드 번호 자동 증가)
+bundle exec fastlane beta
+
+# 3. TestFlight에서 내부 테스트
+
+# 4. 정식 릴리스 준비
+bundle exec fastlane release
+
+# 5. App Store Connect에서 Submit for Review
+```
+
+#### 시나리오 2: 버그 수정 릴리스 (1.0.0 → 1.0.1)
+
+```bash
+# 1. 버그 수정 후 마케팅 버전 변경
+agvtool new-marketing-version 1.0.1
+
+# 2. Git 커밋
+git add -A
+git commit -m "fix: critical bug in trends chart"
+
+# 3. 태그 생성 (CI에서 자동 TestFlight 배포)
+git tag v1.0.1
+git push origin v1.0.1
+
+# 4. GitHub Actions가 자동으로 beta lane 실행
+# 5. TestFlight 확인 후 App Store 제출
+```
+
+### 태깅 가이드
+
+**형식:**
+```
+v{MAJOR}.{MINOR}.{PATCH}
+```
+
+**예시:**
+```bash
+# 버전 태그 생성
+git tag v1.0.0
+
+# 태그 푸시 (CI 트리거)
+git push origin v1.0.0
+
+# 결과: GitHub Actions에서 beta lane 자동 실행 → TestFlight 업로드
+```
+
+**태그 목록 확인:**
+```bash
+git tag -l
+```
+
+**태그 삭제 (실수로 생성 시):**
+```bash
+# 로컬 태그 삭제
+git tag -d v1.0.0
+
+# 리모트 태그 삭제
+git push origin :refs/tags/v1.0.0
+```
+
+---
+
+## CI 워크플로우
+
+### 전체 플로우 다이어그램
+
+```
+Developer (local)
+ │
+ ├─── PR to main ────────────────────┐
+ │ │
+ │ GitHub Actions
+ │ │
+ │ ┌────────▼────────┐
+ │ │ test job │
+ │ │ │
+ │ │ 1. bundle install
+ │ │ 2. fastlane tests
+ │ │ │
+ │ └─────────────────┘
+ │ │
+ │ ▼
+ │ ✅ Tests Passed
+ │
+ └─── git tag v1.0.0 ────────────────┐
+ git push origin v1.0.0 │
+ │
+ GitHub Actions
+ │
+ ┌────────▼────────┐
+ │ beta job │
+ │ │
+ │ 1. Run tests │
+ │ 2. fastlane beta│
+ │ │
+ └────────┬────────┘
+ │
+ ▼
+ TestFlight
+ │
+ ▼
+ Internal Testers
+ │
+ ▼
+ App Store Connect
+ │
+ ▼
+ Submit for Review (manual)
+ │
+ ▼
+ App Store
+```
+
+### GitHub Actions 트리거 조건
+
+**1. Pull Request → `test` job 실행**
+```yaml
+on:
+ pull_request:
+ branches: [main, feat/week1-foundations]
+```
+
+**동작:**
+- PR 생성/업데이트 시 자동 실행
+- `bundle exec fastlane tests` 실행
+- 테스트 실패 시 PR merge 블록 권장
+
+**2. Tag Push → `beta` job 실행**
+```yaml
+on:
+ push:
+ tags:
+ - "v*"
+```
+
+**동작:**
+- `v*` 패턴 태그 푸시 시 실행 (예: `v1.0.0`, `v2.1.3`)
+- `test` job이 먼저 실행되고 성공해야 `beta` job 실행 (`needs: test`)
+- `bundle exec fastlane beta` 실행
+- TestFlight 자동 업로드
+
+### GitHub Secrets 설정 체크리스트
+
+| Secret 이름 | 설명 | 확인 방법 |
+|-------------|------|-----------|
+| `ASC_KEY_ID` | App Store Connect API Key ID | 영문+숫자 10자 (예: `AB12CD34EF`) |
+| `ASC_ISSUER_ID` | Issuer ID | UUID 형식 (예: `12345678-1234-...`) |
+| `ASC_KEY_CONTENT` | Base64 인코딩된 .p8 파일 | `LS0tLS1CRUdJTi...`로 시작 |
+
+**설정 경로:**
+```
+GitHub 저장소 → Settings → Secrets and variables → Actions → Repository secrets
+```
+
+---
+
+## Troubleshooting
+
+### 1. Login/Auth 오류
+
+#### 증상:
+```
+[!] Could not authenticate with App Store Connect
+```
+
+#### 원인:
+- 환경변수 미설정 또는 잘못된 값
+- API Key 만료 또는 권한 부족
+- Base64 인코딩 오류
+
+#### 해결:
+
+**Step 1: 환경변수 확인**
+```bash
+echo $ASC_KEY_ID
+echo $ASC_ISSUER_ID
+echo $ASC_KEY_CONTENT | head -c 50 # 앞 50자만 출력
+```
+
+**Step 2: Base64 재인코딩**
+```bash
+# 올바른 방법
+base64 -i AuthKey_AB12CD34EF.p8 | pbcopy
+
+# ❌ 잘못된 방법 (줄바꿈 포함됨)
+cat AuthKey_AB12CD34EF.p8 | base64
+```
+
+**Step 3: API Key 권한 확인**
+- [App Store Connect → Users and Access → Keys](https://appstoreconnect.apple.com/access/api)
+- 해당 Key의 **Access** 열에서 "App Manager" 또는 "Admin" 확인
+- "Revoked" 상태면 새로 생성
+
+**Step 4: GitHub Actions에서 확인**
+```yaml
+# .github/workflows/ci.yml에서 디버깅 추가
+- name: Debug secrets
+ run: |
+ echo "ASC_KEY_ID length: ${#ASC_KEY_ID}"
+ echo "ASC_ISSUER_ID length: ${#ASC_ISSUER_ID}"
+ echo "ASC_KEY_CONTENT length: ${#ASC_KEY_CONTENT}"
+```
+
+---
+
+### 2. 코드 서명 실패
+
+#### 증상:
+```
+error: Automatic signing failed
+```
+
+#### 체크리스트:
+
+**□ Xcode 프로젝트 설정 확인**
+```
+1. Xcode 열기
+2. 프로젝트 네비게이터에서 "WorkOut Log" 선택
+3. Targets → workout_log → Signing & Capabilities
+4. ✅ "Automatically manage signing" 체크
+5. Team 선택됨 (본인 Apple Developer 계정)
+```
+
+**□ Apple Developer 계정 로그인**
+```
+1. Xcode → Settings → Accounts
+2. Apple ID 추가 (kei7659@daum.net)
+3. "Download Manual Profiles" 클릭
+```
+
+**□ Provisioning Profile 갱신**
+```bash
+# Fastlane 사용
+bundle exec fastlane sigh renew
+```
+
+**□ Bundle ID 일치 확인**
+- Xcode: `com.Ben.WorkOut-Log`
+- App Store Connect: `com.Ben.WorkOut-Log`
+- `fastlane/Appfile`: `com.Ben.WorkOut-Log`
+
+---
+
+### 3. Xcode Path 오류
+
+#### 증상:
+```
+xcode-select: error: tool 'xcodebuild' requires Xcode
+```
+
+#### 해결:
+```bash
+# 현재 Xcode 경로 확인
+xcode-select -p
+
+# 올바른 경로로 설정
+sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
+
+# 또는 Xcode 16 버전 지정
+sudo xcode-select -s /Applications/Xcode_16.0.app/Contents/Developer
+
+# Xcode License 동의 (필요 시)
+sudo xcodebuild -license accept
+```
+
+---
+
+### 4. TestFlight 업로드 지연
+
+#### 증상:
+- `pilot` 명령이 완료되었지만 TestFlight에 빌드가 안 보임
+
+#### 정상 상태:
+- 업로드 후 **5~30분** 소요 (Apple의 처리 시간)
+- App Store Connect → TestFlight → iOS Builds에서 "Processing" 상태 확인
+
+#### 로그 확인 지점:
+```bash
+# Fastlane 로그에서 확인
+[15:48:50]: Successfully uploaded package to App Store Connect
+[15:48:50]: ✅ Successfully uploaded build 7 to TestFlight!
+```
+
+#### App Store Connect 확인:
+1. [App Store Connect](https://appstoreconnect.apple.com) 로그인
+2. 앱 선택 → **TestFlight** 탭
+3. **iOS Builds** 섹션에서 "Processing" 또는 "Ready to Submit" 확인
+
+#### 비정상 상태 (에러):
+```
+[!] Error uploading ipa file:
+The provided entity includes an attribute with a value that has already been used
+```
+
+**원인:** 동일한 빌드 번호 재업로드 시도
+**해결:** `bundle exec fastlane bump_build` 실행 후 재시도
+
+---
+
+### 5. 테스트 실패
+
+#### 증상:
+```
+Test Suite 'workout_logTests' failed
+```
+
+#### 해결:
+
+**Step 1: 로컬에서 Xcode로 테스트**
+```
+1. Xcode 열기
+2. Product → Test (Cmd+U)
+3. 실패한 테스트 케이스 확인
+```
+
+**Step 2: 특정 테스트만 실행**
+```bash
+xcodebuild test \
+ -scheme workout_log \
+ -destination 'platform=iOS Simulator,name=iPhone 16' \
+ -only-testing:workout_logTests/WeeklyBucketTests
+```
+
+**Step 3: 시뮬레이터 초기화**
+```bash
+# 모든 시뮬레이터 종료
+xcrun simctl shutdown all
+
+# 시뮬레이터 초기화
+xcrun simctl erase all
+```
+
+---
+
+## 보안 주의사항
+
+### 🔒 절대 금지 사항
+
+**❌ .p8 파일 Git 커밋 금지**
+```bash
+# .gitignore에 반드시 추가
+*.p8
+AuthKey_*.p8
+```
+
+**❌ 환경변수를 코드에 하드코딩 금지**
+```ruby
+# ❌ 잘못된 예시
+api_key = app_store_connect_api_key(
+ key_id: "AB12CD34EF", # 하드코딩 금지!
+ issuer_id: "12345678-1234-...",
+ key_content: "LS0tLS1CRUdJTi..."
+)
+
+# ✅ 올바른 예시
+api_key = app_store_connect_api_key(
+ key_id: ENV["ASC_KEY_ID"],
+ issuer_id: ENV["ASC_ISSUER_ID"],
+ key_content: Base64.decode64(ENV["ASC_KEY_CONTENT"])
+)
+```
+
+**❌ GitHub Actions 로그에 Secret 노출 금지**
+```yaml
+# ❌ 잘못된 예시
+- name: Debug
+ run: echo "Key: ${{ secrets.ASC_KEY_CONTENT }}"
+
+# ✅ 올바른 예시 (길이만 확인)
+- name: Debug
+ run: echo "Key length: ${#ASC_KEY_CONTENT}"
+```
+
+### ✅ 권장 사항
+
+**1. .p8 파일 안전 보관**
+- 1Password, Bitwarden 등 비밀번호 관리자에 저장
+- 로컬 머신의 암호화된 폴더에 백업
+
+**2. API Key 권한 최소화**
+- **Admin** 대신 **App Manager** 역할 사용
+- 필요 없는 Key는 즉시 Revoke
+
+**3. 정기 Key 로테이션**
+- 6개월마다 API Key 재생성 권장
+- 이전 Key는 Revoke 처리
+
+**4. 팀원 간 Secret 공유 방법**
+- Slack DM으로 전송 금지
+- 1Password Shared Vault 사용 권장
+
+---
+
+## 부록: Fastfile 주요 옵션
+
+### `run_tests` 액션
+
+| 옵션 | 설명 | 예시 |
+|------|------|------|
+| `project` | Xcode 프로젝트 파일 경로 | `"WorkOut Log.xcodeproj"` |
+| `workspace` | Xcode 워크스페이스 경로 (CocoaPods 사용 시) | `"WorkOut Log.xcworkspace"` |
+| `scheme` | 빌드 스킴 | `"workout_log"` |
+| `device` | 시뮬레이터 이름 | `"iPhone 16"`, `"iPhone SE (3rd generation)"` |
+| `clean` | 빌드 전 clean 여부 | `true` / `false` |
+| `code_coverage` | 코드 커버리지 활성화 | `true` / `false` |
+| `only_testing` | 특정 테스트만 실행 | `["workout_logTests/WeeklyBucketTests"]` |
+
+### `gym` 액션 (Archive & Export)
+
+| 옵션 | 설명 | 예시 |
+|------|------|------|
+| `project` | Xcode 프로젝트 파일 경로 | `"WorkOut Log.xcodeproj"` |
+| `workspace` | Xcode 워크스페이스 경로 | `"WorkOut Log.xcworkspace"` |
+| `scheme` | 빌드 스킴 | `"workout_log"` |
+| `export_method` | Export 방식 | `"app-store"`, `"ad-hoc"`, `"development"` |
+| `clean` | 빌드 전 clean 여부 | `true` / `false` |
+| `output_directory` | IPA 출력 디렉토리 | `"build"` |
+| `include_symbols` | dSYM 파일 포함 | `true` / `false` |
+| `include_bitcode` | Bitcode 포함 (iOS 14+ 불필요) | `false` |
+
+### `pilot` 액션 (TestFlight Upload)
+
+| 옵션 | 설명 | 예시 |
+|------|------|------|
+| `api_key` | App Store Connect API Key 객체 | `api_key` 변수 전달 |
+| `skip_waiting_for_build_processing` | 업로드 후 Processing 완료 대기 안 함 | `true` (권장) |
+| `changelog` | TestFlight 릴리스 노트 | `"Bug fixes and improvements"` |
+| `distribute_external` | 외부 테스터에게 자동 배포 | `false` (수동 권장) |
+| `groups` | 배포할 테스터 그룹 | `["Internal Testers"]` |
+
+### `deliver` 액션 (App Store Upload)
+
+| 옵션 | 설명 | 예시 |
+|------|------|------|
+| `api_key` | App Store Connect API Key 객체 | `api_key` 변수 전달 |
+| `submit_for_review` | 자동 심사 제출 | `false` (수동 권장) |
+| `skip_metadata` | 메타데이터 업로드 생략 | `true` |
+| `skip_screenshots` | 스크린샷 업로드 생략 | `true` |
+| `force` | 기존 빌드 덮어쓰기 | `true` |
+| `automatic_release` | 심사 승인 후 자동 릴리스 | `false` |
+
+### `increment_build_number` 액션
+
+| 옵션 | 설명 | 예시 |
+|------|------|------|
+| `xcodeproj` | Xcode 프로젝트 경로 | `"WorkOut Log.xcodeproj"` |
+| `build_number` | 특정 빌드 번호 설정 (옵션) | `42` |
+
+**기본 동작:** 현재 빌드 번호 + 1
+
+---
+
+## 참고 문서
+
+- [Fastlane 공식 문서](https://docs.fastlane.tools/)
+- [App Store Connect API](https://developer.apple.com/documentation/appstoreconnectapi)
+- [Xcode Build Settings Reference](https://developer.apple.com/documentation/xcode/build-settings-reference)
+- [GitHub Actions Documentation](https://docs.github.com/en/actions)
+
+---
+
+**문서 버전:** 1.0.0
+**최종 수정:** 2025년 10월 19일
+**작성자:** Ben (오정석)
+**문의:** kei7659@daum.net
+
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..7a118b4
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,3 @@
+source "https://rubygems.org"
+
+gem "fastlane"
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 0000000..af73bfb
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,229 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ CFPropertyList (3.0.7)
+ base64
+ nkf
+ rexml
+ addressable (2.8.7)
+ public_suffix (>= 2.0.2, < 7.0)
+ artifactory (3.0.17)
+ atomos (0.1.3)
+ aws-eventstream (1.4.0)
+ aws-partitions (1.1174.0)
+ aws-sdk-core (3.233.0)
+ aws-eventstream (~> 1, >= 1.3.0)
+ aws-partitions (~> 1, >= 1.992.0)
+ aws-sigv4 (~> 1.9)
+ base64
+ bigdecimal
+ jmespath (~> 1, >= 1.6.1)
+ logger
+ aws-sdk-kms (1.114.0)
+ aws-sdk-core (~> 3, >= 3.231.0)
+ aws-sigv4 (~> 1.5)
+ aws-sdk-s3 (1.200.0)
+ aws-sdk-core (~> 3, >= 3.231.0)
+ aws-sdk-kms (~> 1)
+ aws-sigv4 (~> 1.5)
+ aws-sigv4 (1.12.1)
+ aws-eventstream (~> 1, >= 1.0.2)
+ babosa (1.0.4)
+ base64 (0.3.0)
+ bigdecimal (3.3.1)
+ claide (1.1.0)
+ colored (1.2)
+ colored2 (3.1.2)
+ commander (4.6.0)
+ highline (~> 2.0.0)
+ declarative (0.0.20)
+ digest-crc (0.7.0)
+ rake (>= 12.0.0, < 14.0.0)
+ domain_name (0.6.20240107)
+ dotenv (2.8.1)
+ emoji_regex (3.2.3)
+ excon (0.112.0)
+ faraday (1.10.4)
+ faraday-em_http (~> 1.0)
+ faraday-em_synchrony (~> 1.0)
+ faraday-excon (~> 1.1)
+ faraday-httpclient (~> 1.0)
+ faraday-multipart (~> 1.0)
+ faraday-net_http (~> 1.0)
+ faraday-net_http_persistent (~> 1.0)
+ faraday-patron (~> 1.0)
+ faraday-rack (~> 1.0)
+ faraday-retry (~> 1.0)
+ ruby2_keywords (>= 0.0.4)
+ faraday-cookie_jar (0.0.7)
+ faraday (>= 0.8.0)
+ http-cookie (~> 1.0.0)
+ faraday-em_http (1.0.0)
+ faraday-em_synchrony (1.0.1)
+ faraday-excon (1.1.0)
+ faraday-httpclient (1.0.1)
+ faraday-multipart (1.1.1)
+ multipart-post (~> 2.0)
+ faraday-net_http (1.0.2)
+ faraday-net_http_persistent (1.2.0)
+ faraday-patron (1.0.0)
+ faraday-rack (1.0.0)
+ faraday-retry (1.0.3)
+ faraday_middleware (1.2.1)
+ faraday (~> 1.0)
+ fastimage (2.4.0)
+ fastlane (2.228.0)
+ CFPropertyList (>= 2.3, < 4.0.0)
+ addressable (>= 2.8, < 3.0.0)
+ artifactory (~> 3.0)
+ aws-sdk-s3 (~> 1.0)
+ babosa (>= 1.0.3, < 2.0.0)
+ bundler (>= 1.12.0, < 3.0.0)
+ colored (~> 1.2)
+ commander (~> 4.6)
+ dotenv (>= 2.1.1, < 3.0.0)
+ emoji_regex (>= 0.1, < 4.0)
+ excon (>= 0.71.0, < 1.0.0)
+ faraday (~> 1.0)
+ faraday-cookie_jar (~> 0.0.6)
+ faraday_middleware (~> 1.0)
+ fastimage (>= 2.1.0, < 3.0.0)
+ fastlane-sirp (>= 1.0.0)
+ gh_inspector (>= 1.1.2, < 2.0.0)
+ google-apis-androidpublisher_v3 (~> 0.3)
+ google-apis-playcustomapp_v1 (~> 0.1)
+ google-cloud-env (>= 1.6.0, < 2.0.0)
+ google-cloud-storage (~> 1.31)
+ highline (~> 2.0)
+ http-cookie (~> 1.0.5)
+ json (< 3.0.0)
+ jwt (>= 2.1.0, < 3)
+ mini_magick (>= 4.9.4, < 5.0.0)
+ multipart-post (>= 2.0.0, < 3.0.0)
+ naturally (~> 2.2)
+ optparse (>= 0.1.1, < 1.0.0)
+ plist (>= 3.1.0, < 4.0.0)
+ rubyzip (>= 2.0.0, < 3.0.0)
+ security (= 0.1.5)
+ simctl (~> 1.6.3)
+ terminal-notifier (>= 2.0.0, < 3.0.0)
+ terminal-table (~> 3)
+ tty-screen (>= 0.6.3, < 1.0.0)
+ tty-spinner (>= 0.8.0, < 1.0.0)
+ word_wrap (~> 1.0.0)
+ xcodeproj (>= 1.13.0, < 2.0.0)
+ xcpretty (~> 0.4.1)
+ xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
+ fastlane-sirp (1.0.0)
+ sysrandom (~> 1.0)
+ gh_inspector (1.1.3)
+ google-apis-androidpublisher_v3 (0.54.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-core (0.11.3)
+ addressable (~> 2.5, >= 2.5.1)
+ googleauth (>= 0.16.2, < 2.a)
+ httpclient (>= 2.8.1, < 3.a)
+ mini_mime (~> 1.0)
+ representable (~> 3.0)
+ retriable (>= 2.0, < 4.a)
+ rexml
+ google-apis-iamcredentials_v1 (0.17.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-playcustomapp_v1 (0.13.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-apis-storage_v1 (0.31.0)
+ google-apis-core (>= 0.11.0, < 2.a)
+ google-cloud-core (1.8.0)
+ google-cloud-env (>= 1.0, < 3.a)
+ google-cloud-errors (~> 1.0)
+ google-cloud-env (1.6.0)
+ faraday (>= 0.17.3, < 3.0)
+ google-cloud-errors (1.5.0)
+ google-cloud-storage (1.47.0)
+ addressable (~> 2.8)
+ digest-crc (~> 0.4)
+ google-apis-iamcredentials_v1 (~> 0.1)
+ google-apis-storage_v1 (~> 0.31.0)
+ google-cloud-core (~> 1.6)
+ googleauth (>= 0.16.2, < 2.a)
+ mini_mime (~> 1.0)
+ googleauth (1.8.1)
+ faraday (>= 0.17.3, < 3.a)
+ jwt (>= 1.4, < 3.0)
+ multi_json (~> 1.11)
+ os (>= 0.9, < 2.0)
+ signet (>= 0.16, < 2.a)
+ highline (2.0.3)
+ http-cookie (1.0.8)
+ domain_name (~> 0.5)
+ httpclient (2.9.0)
+ mutex_m
+ jmespath (1.6.2)
+ json (2.15.1)
+ jwt (2.10.2)
+ base64
+ logger (1.7.0)
+ mini_magick (4.13.2)
+ mini_mime (1.1.5)
+ multi_json (1.17.0)
+ multipart-post (2.4.1)
+ mutex_m (0.3.0)
+ nanaimo (0.4.0)
+ naturally (2.3.0)
+ nkf (0.2.0)
+ optparse (0.6.0)
+ os (1.1.4)
+ plist (3.7.2)
+ public_suffix (6.0.2)
+ rake (13.3.0)
+ representable (3.2.0)
+ declarative (< 0.1.0)
+ trailblazer-option (>= 0.1.1, < 0.2.0)
+ uber (< 0.2.0)
+ retriable (3.1.2)
+ rexml (3.4.4)
+ rouge (3.28.0)
+ ruby2_keywords (0.0.5)
+ rubyzip (2.4.1)
+ security (0.1.5)
+ signet (0.21.0)
+ addressable (~> 2.8)
+ faraday (>= 0.17.5, < 3.a)
+ jwt (>= 1.5, < 4.0)
+ multi_json (~> 1.10)
+ simctl (1.6.10)
+ CFPropertyList
+ naturally
+ sysrandom (1.0.5)
+ terminal-notifier (2.0.0)
+ terminal-table (3.0.2)
+ unicode-display_width (>= 1.1.1, < 3)
+ trailblazer-option (0.1.2)
+ tty-cursor (0.7.1)
+ tty-screen (0.8.2)
+ tty-spinner (0.9.3)
+ tty-cursor (~> 0.7)
+ uber (0.1.0)
+ unicode-display_width (2.6.0)
+ word_wrap (1.0.0)
+ xcodeproj (1.27.0)
+ CFPropertyList (>= 2.3.3, < 4.0)
+ atomos (~> 0.1.3)
+ claide (>= 1.0.2, < 2.0)
+ colored2 (~> 3.1)
+ nanaimo (~> 0.4.0)
+ rexml (>= 3.3.6, < 4.0)
+ xcpretty (0.4.1)
+ rouge (~> 3.28.0)
+ xcpretty-travis-formatter (1.0.1)
+ xcpretty (~> 0.2, >= 0.0.7)
+
+PLATFORMS
+ arm64-darwin-23
+ ruby
+
+DEPENDENCIES
+ fastlane
+
+BUNDLED WITH
+ 2.5.6
diff --git a/README.md b/README.md
index eb0b240..6836541 100644
--- a/README.md
+++ b/README.md
@@ -434,6 +434,21 @@ cd Docs && ./export.sh
---
+## 🚀 CI/CD & Fastlane
+
+이 프로젝트는 **Fastlane**을 사용하여 빌드, 테스트, TestFlight 배포를 자동화합니다. PR마다 자동으로 테스트가 실행되며, `v*` 태그를 푸시하면 GitHub Actions가 TestFlight에 자동으로 배포합니다.
+
+**📘 자세한 가이드**: [Docs/Fastlane_Guide.md](Docs/Fastlane_Guide.md) (환경 설정, 로컬 실행, CI 워크플로우, 트러블슈팅 포함)
+
+**로컬 실행 (3 commands):**
+```bash
+bundle install # Ruby 의존성 설치
+bundle exec fastlane tests # 테스트 실행
+bundle exec fastlane beta # TestFlight 배포 (App Store Connect API 키 필요)
+```
+
+---
+
## 🤝 Contributing
### Development Workflow
diff --git a/WorkOut Log.xcodeproj/xcshareddata/xcschemes/WorkOut Log.xcscheme b/WorkOut Log.xcodeproj/xcshareddata/xcschemes/WorkOut Log.xcscheme
new file mode 100644
index 0000000..003b1df
--- /dev/null
+++ b/WorkOut Log.xcodeproj/xcshareddata/xcschemes/WorkOut Log.xcscheme
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WorkOut Log.xcodeproj/xcuserdata/ojung.xcuserdatad/xcschemes/xcschememanagement.plist b/WorkOut Log.xcodeproj/xcuserdata/ojung.xcuserdatad/xcschemes/xcschememanagement.plist
index cbc93ea..6e0cdca 100644
--- a/WorkOut Log.xcodeproj/xcuserdata/ojung.xcuserdatad/xcschemes/xcschememanagement.plist
+++ b/WorkOut Log.xcodeproj/xcuserdata/ojung.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -10,5 +10,23 @@
0
+ SuppressBuildableAutocreation
+
+ 99DC4DB62E9E2850006B8C3F
+
+ primary
+
+
+ 99DC4DC52E9E2853006B8C3F
+
+ primary
+
+
+ 99DC4DCF2E9E2853006B8C3F
+
+ primary
+
+
+
diff --git a/WorkOut Log/Presentation/Resources/Assets.xcassets/WorkoutLog_Logo.imageset/Contents.json b/WorkOut Log/Presentation/Resources/Assets.xcassets/WorkoutLog_Logo.imageset/Contents.json
new file mode 100644
index 0000000..caca957
--- /dev/null
+++ b/WorkOut Log/Presentation/Resources/Assets.xcassets/WorkoutLog_Logo.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "WorkoutLog_Logo_Blue2563EB_1024.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/WorkOut Log/Presentation/Resources/Assets.xcassets/WorkoutLog_Logo.imageset/WorkoutLog_Logo_Blue2563EB_1024.png b/WorkOut Log/Presentation/Resources/Assets.xcassets/WorkoutLog_Logo.imageset/WorkoutLog_Logo_Blue2563EB_1024.png
new file mode 100644
index 0000000..3a681ba
Binary files /dev/null and b/WorkOut Log/Presentation/Resources/Assets.xcassets/WorkoutLog_Logo.imageset/WorkoutLog_Logo_Blue2563EB_1024.png differ
diff --git a/WorkOut Log/Presentation/Resources/LaunchScreen.storyboard b/WorkOut Log/Presentation/Resources/LaunchScreen.storyboard
index 92e0739..775c1a5 100644
--- a/WorkOut Log/Presentation/Resources/LaunchScreen.storyboard
+++ b/WorkOut Log/Presentation/Resources/LaunchScreen.storyboard
@@ -16,32 +16,49 @@
-
-
-
+
+
+
+
+
+
-
+
+
+
-
-
-
+
+
+
+
+
+
-
+
-
+
+
+
+
diff --git a/WorkOut-Log-Info.plist b/WorkOut-Log-Info.plist
index 0c67376..bc11256 100644
--- a/WorkOut-Log-Info.plist
+++ b/WorkOut-Log-Info.plist
@@ -1,5 +1,8 @@
-
+
+ ITSAppUsesNonExemptEncryption
+
+
diff --git a/fastlane/Appfile b/fastlane/Appfile
new file mode 100644
index 0000000..1075cf4
--- /dev/null
+++ b/fastlane/Appfile
@@ -0,0 +1,15 @@
+# Fastlane Appfile
+# Bundle identifier for your app
+app_identifier("com.Ben.WorkOut-Log")
+
+# Your Apple Developer account email
+apple_id("kei7659@daum.net")
+
+# App Store Connect Team ID (optional if you have only one team)
+# itc_team_id("YOUR_ITC_TEAM_ID")
+
+# Developer Portal Team ID (optional if you have only one team)
+# team_id("YOUR_TEAM_ID")
+
+# For more information about the Appfile, see:
+# https://docs.fastlane.tools/advanced/#appfile
diff --git a/fastlane/Fastfile b/fastlane/Fastfile
new file mode 100644
index 0000000..5399832
--- /dev/null
+++ b/fastlane/Fastfile
@@ -0,0 +1,272 @@
+# Fastlane Fastfile for WorkOut Log
+# This file contains the configuration for automating build, test, and deployment
+
+default_platform(:ios)
+
+platform :ios do
+ # ========================================
+ # CONFIGURATION
+ # ========================================
+
+ SCHEME = "workout_log"
+ XCODEPROJ = "WorkOut Log.xcodeproj"
+ OUTPUT_DIR = "build"
+
+ # ========================================
+ # LANES
+ # ========================================
+
+ desc "Run unit and UI tests"
+ lane :tests do
+ run_tests(
+ project: XCODEPROJ,
+ scheme: SCHEME,
+ device: "iPhone 16",
+ clean: true,
+ code_coverage: true
+ )
+ end
+
+ desc "Increment build number (CFBundleVersion) and commit"
+ lane :bump_build do
+ increment_build_number(xcodeproj: XCODEPROJ)
+
+ # Commit the version bump
+ build_number = get_build_number(xcodeproj: XCODEPROJ)
+ commit_version_bump(
+ message: "chore(ci): bump build number to #{build_number}",
+ xcodeproj: XCODEPROJ
+ )
+ end
+
+ desc "Build archive for App Store distribution (automatic signing)"
+ lane :build do
+ gym(
+ project: XCODEPROJ,
+ scheme: SCHEME,
+ export_method: "app-store",
+ skip_package_pkg: true,
+ include_bitcode: false,
+ include_symbols: true,
+ clean: true,
+ silent: false,
+ output_directory: OUTPUT_DIR,
+ export_options: {
+ signingStyle: "automatic",
+ teamID: "8CKPNKA3V9"
+ }
+ )
+ end
+
+ desc "Upload to TestFlight (beta testing)"
+ lane :beta do
+ # Authenticate with App Store Connect API
+ api_key = app_store_connect_api_key(
+ key_id: ENV["ASC_KEY_ID"],
+ issuer_id: ENV["ASC_ISSUER_ID"],
+ key_content: Base64.decode64(ENV["ASC_KEY_CONTENT"]),
+ is_key_content_base64: false
+ )
+
+ # Get current build number (manual versioning - increment in Xcode)
+ build_number = get_info_plist_value(
+ path: "WorkOut-Log-Info.plist",
+ key: "CFBundleVersion"
+ )
+
+ # Skip tests for now (run manually or in CI)
+ # run_tests(
+ # project: XCODEPROJ,
+ # scheme: SCHEME,
+ # device: "iPhone 16",
+ # clean: true
+ # )
+
+ # Build archive (using Xcode automatic signing)
+ gym(
+ project: XCODEPROJ,
+ scheme: SCHEME,
+ export_method: "app-store",
+ clean: true,
+ output_directory: OUTPUT_DIR,
+ include_symbols: true,
+ export_options: {
+ signingStyle: "automatic",
+ teamID: "8CKPNKA3V9"
+ }
+ )
+
+ # Upload to TestFlight
+ pilot(
+ api_key: api_key,
+ skip_waiting_for_build_processing: true,
+ changelog: "Beta build #{build_number}\n\n- Bug fixes and improvements"
+ )
+
+ UI.success("✅ Successfully uploaded build #{build_number} to TestFlight!")
+ end
+
+ desc "Submit to App Store for review with Korean metadata"
+ lane :release do
+ # Authenticate with App Store Connect API
+ api_key = app_store_connect_api_key(
+ key_id: ENV["ASC_KEY_ID"],
+ issuer_id: ENV["ASC_ISSUER_ID"],
+ key_content: Base64.decode64(ENV["ASC_KEY_CONTENT"]),
+ is_key_content_base64: false
+ )
+
+ # Verify export compliance before building
+ check_export_compliance
+
+ # Get current version info
+ version = get_version_number(xcodeproj: XCODEPROJ, target: "WorkOut Log")
+ build_number = get_info_plist_value(
+ path: "WorkOut-Log-Info.plist",
+ key: "CFBundleVersion"
+ )
+
+ UI.header("📦 Building version #{version} (#{build_number}) for App Store")
+
+ # Build archive (using Xcode automatic signing)
+ gym(
+ project: XCODEPROJ,
+ scheme: SCHEME,
+ export_method: "app-store",
+ clean: true,
+ output_directory: OUTPUT_DIR,
+ include_symbols: true,
+ export_options: {
+ signingStyle: "automatic",
+ teamID: "8CKPNKA3V9"
+ }
+ )
+
+ UI.header("📤 Uploading to App Store Connect and submitting for review")
+
+ # Upload to App Store Connect and submit for review
+ deliver(
+ api_key: api_key,
+ submit_for_review: true,
+ force: true,
+ skip_metadata: true, # Skip metadata upload to avoid localization conflicts
+ skip_screenshots: true, # Skip screenshots upload for now
+ automatic_release: false,
+ precheck_include_in_app_purchases: false,
+ submission_information: {
+ add_id_info_uses_idfa: false
+ }
+ )
+
+ UI.success("✅ Successfully submitted version #{version} (#{build_number}) for App Store review!")
+ UI.message("📋 Next steps:")
+ UI.message(" 1. Check App Store Connect for submission status")
+ UI.message(" 2. Review time: typically 24-48 hours")
+ UI.message(" 3. App will go live after manual release approval")
+ end
+
+ desc "Submit existing build for App Store review (no build/upload)"
+ lane :submit_only do
+ # Authenticate with App Store Connect API
+ api_key = app_store_connect_api_key(
+ key_id: ENV["ASC_KEY_ID"],
+ issuer_id: ENV["ASC_ISSUER_ID"],
+ key_content: Base64.decode64(ENV["ASC_KEY_CONTENT"]),
+ is_key_content_base64: false
+ )
+
+ # Get current version info
+ version = get_version_number(xcodeproj: XCODEPROJ, target: "WorkOut Log")
+ build_number = get_info_plist_value(
+ path: "WorkOut-Log-Info.plist",
+ key: "CFBundleVersion"
+ )
+
+ UI.header("📤 Submitting existing build #{version} (#{build_number}) for App Store review")
+
+ # Submit for review without uploading (assumes build already exists)
+ deliver(
+ api_key: api_key,
+ submit_for_review: true,
+ force: true,
+ skip_binary_upload: true, # Skip binary upload - use existing build
+ skip_metadata: true,
+ skip_screenshots: true,
+ automatic_release: false,
+ precheck_include_in_app_purchases: false,
+ submission_information: {
+ add_id_info_uses_idfa: false
+ }
+ )
+
+ UI.success("✅ Successfully submitted version #{version} (#{build_number}) for App Store review!")
+ UI.message("📋 Next steps:")
+ UI.message(" 1. Check App Store Connect for submission status")
+ UI.message(" 2. Review time: typically 24-48 hours")
+ UI.message(" 3. App will go live after manual release approval")
+ end
+
+ # ========================================
+ # HELPER LANES
+ # ========================================
+
+ desc "Clean derived data and build artifacts"
+ lane :clean do
+ clean_build_artifacts
+ clear_derived_data
+ UI.success("✅ Cleaned build artifacts and derived data")
+ end
+
+ desc "Run SwiftLint (if configured)"
+ lane :lint do
+ swiftlint(
+ mode: :lint,
+ executable: "Pods/SwiftLint/swiftlint",
+ raise_if_swiftlint_error: true
+ )
+ end
+
+ desc "Verify export compliance settings (ITSAppUsesNonExemptEncryption)"
+ lane :check_export_compliance do
+ UI.header("🔍 Checking Export Compliance Settings")
+
+ plist_path = "../WorkOut-Log-Info.plist"
+ plist_filename = "WorkOut-Log-Info.plist"
+
+ # Check if Info.plist exists
+ unless File.exist?(plist_path)
+ UI.user_error!("❌ Info.plist not found at: #{plist_path}")
+ end
+
+ # Read the value from Info.plist
+ encryption_value = get_info_plist_value(
+ path: plist_filename,
+ key: "ITSAppUsesNonExemptEncryption"
+ )
+
+ # Verify the value
+ if encryption_value.nil?
+ UI.user_error!("❌ ITSAppUsesNonExemptEncryption key is missing in #{plist_filename}")
+ elsif encryption_value == false || encryption_value == "false" || encryption_value == "NO"
+ UI.success("✅ Export compliance correctly set: ITSAppUsesNonExemptEncryption = false")
+ UI.success("✅ Target: WorkOut Log")
+ UI.success("✅ Info.plist: #{plist_filename}")
+ UI.message("")
+ UI.message("📋 Summary:")
+ UI.message(" • App does not use exempt encryption")
+ UI.message(" • Export compliance questions will be skipped in App Store Connect")
+ UI.message(" • Safe for apps using only standard iOS frameworks (URLSession, etc.)")
+ else
+ UI.user_error!("❌ ITSAppUsesNonExemptEncryption has incorrect value: #{encryption_value} (expected: false)")
+ end
+ end
+
+ # ========================================
+ # ERROR HANDLING
+ # ========================================
+
+ error do |lane, exception|
+ UI.error("❌ Lane #{lane} failed with exception:")
+ UI.error(exception.message)
+ end
+end
diff --git a/fastlane/metadata/ko-KR/keywords.txt b/fastlane/metadata/ko-KR/keywords.txt
deleted file mode 100644
index 749a218..0000000
--- a/fastlane/metadata/ko-KR/keywords.txt
+++ /dev/null
@@ -1 +0,0 @@
-운동 기록,헬스 기록,운동 일지,웨이트 트레이닝,근력 운동,피트니스,헬스장,운동 추적,볼륨 기록,개인 기록,운동 로그,트레이닝 일지,오프라인 운동,개인정보 보호,로컬 저장,세트 기록,반복 횟수,운동 플래너,헬스 다이어리,보디빌딩,파워리프팅,운동 기록앱,헬스 앱,피트니스 앱
\ No newline at end of file
diff --git a/fastlane/metadata/ko-KR/name.txt b/fastlane/metadata/ko-KR/name.txt
deleted file mode 100644
index bd90fa5..0000000
--- a/fastlane/metadata/ko-KR/name.txt
+++ /dev/null
@@ -1 +0,0 @@
-WorkOut Log
\ No newline at end of file
diff --git a/fastlane/metadata/ko-KR/release_notes.txt b/fastlane/metadata/ko-KR/release_notes.txt
deleted file mode 100644
index e14dc5f..0000000
--- a/fastlane/metadata/ko-KR/release_notes.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-버전 1.0.0 — 첫 출시
-
-WorkOut Log에 오신 것을 환영합니다! 완벽한 개인정보 보호로 운동을 기록하세요.
-
-새로운 기능:
-• 자동 볼륨 계산과 함께 세션 및 세트 추적
-• 4개 카테고리(하체/상체/유산소/전신)를 가진 맞춤형 운동 라이브러리
-• 카테고리 배지 및 운동 그룹화가 있는 운동 로그
-• 트렌드 시각화 (일일/주간/월간)
-• 앱 실행 시 매일 동기부여 명언
-• 100% 오프라인 — 계정 없음, 클라우드 없음, 추적 없음
-
-iOS 18용 Swift 6 + SwiftUI + SwiftData로 제작.
-
-문의사항? your-email@example.com
\ No newline at end of file
diff --git a/fastlane/metadata/ko-KR/subtitle.txt b/fastlane/metadata/ko-KR/subtitle.txt
deleted file mode 100644
index 56ffb56..0000000
--- a/fastlane/metadata/ko-KR/subtitle.txt
+++ /dev/null
@@ -1 +0,0 @@
-오프라인 운동 기록 앱
\ No newline at end of file
diff --git a/fastlane/metadata/ko-KR/description.txt b/fastlane/metadata/ko/description.txt
similarity index 71%
rename from fastlane/metadata/ko-KR/description.txt
rename to fastlane/metadata/ko/description.txt
index ed078b8..e75dc8e 100644
--- a/fastlane/metadata/ko-KR/description.txt
+++ b/fastlane/metadata/ko/description.txt
@@ -1,116 +1,92 @@
-# WorkOut Log — 오프라인 운동 기록 앱
-
완벽한 개인정보 보호와 함께 운동을 기록하세요. 모든 데이터는 내 기기에만 저장됩니다—계정 없음, 클라우드 없음, 추적 없음.
-## 주요 기능
+주요 기능
-### 📝 세션 및 세트 기록
+세션 및 세트 기록
• 날짜 선택으로 운동 세션 기록
• 운동명, 무게(kg), 반복 횟수 입력으로 세트 추가
• 자동 볼륨 계산 (무게 × 횟수)
• 빠른 데이터 입력을 위한 운동 고정 선택
• 스와이프로 세션 및 세트 삭제
-### 🏋️ 맞춤형 운동 라이브러리
+맞춤형 운동 라이브러리
• 나만의 운동을 이름으로 생성
• 4가지 카테고리: 하체, 상체, 유산소, 전신
• 즉시 검색 결과 표시
• 스와이프로 운동 삭제 (안전 검증 포함)
• 카테고리별 운동 그룹화로 쉬운 탐색
-### 📊 운동 로그
+운동 로그
• 시간순 세션 목록 (최신순)
• 세션별 운동 카테고리 배지 표시
• 세션별 총 볼륨 표시
• 운동별 세트 그룹화 및 섹션 헤더
• 운동별 세트 번호 매기기 및 소계 볼륨
-### 📈 트렌드 및 분석
-• 3가지 보기 범위: 일일(최근 ≤10일), 주간(8주), 월간(6개월)
+트렌드 및 분석
+• 3가지 보기 범위: 일일(최근 10일 이하), 주간(8주), 월간(6개월)
• 일일 모드 "모든 날 표시" 토글 (볼륨 없는 날 포함)
• 카테고리 필터 (하체/상체/유산소/전신)
• 볼륨 시각화를 위한 인터랙티브 라인 차트
• 한눈에 보는 진행 상황 추적
-### 💬 매일 동기부여
+매일 동기부여
• 앱 실행 시 랜덤 운동 명언
• 운동선수 및 리더의 15개 명언 큐레이션
• 2.5초 후 자동 종료 (또는 탭하여 건너뛰기)
• 스크린 리더 사용자를 위한 긴 지속 시간
-## 개인정보 보호 및 보안
+개인정보 보호 및 보안
-### 100% 오프라인
+100% 오프라인
• 인터넷 불필요—비행기 모드에서도 작동
• 클라우드 동기화, 서버, 데이터베이스 없음
• 모든 데이터는 Apple SwiftData로 로컬 저장
• 데이터가 iPhone 밖으로 나가지 않음
-### 데이터 수집 제로
+데이터 수집 제로
• 개인정보 수집 없음
• 사용 분석 또는 추적 없음
• 광고 식별자 없음
• 타사 SDK 없음
• 외부 서비스로 충돌 보고 없음
-### 내 데이터, 내가 제어
+내 데이터, 내가 제어
• 모든 운동 데이터는 기기에만 저장
• iOS 암호화 (기기 잠금 코드 활성화 시)
• iOS 백업 활성화 시에만 iCloud 백업
• 앱 삭제 시 영구 삭제
-## 접근성
-
+접근성
• 시맨틱 레이블이 있는 완전한 VoiceOver 지원
• 텍스트 크기 조정을 위한 Dynamic Type
• 고대비 색상
• 모든 인터랙티브 요소에 대한 접근성 식별자
• 스크린 리더 사용자를 위한 확장 스플래시 지속 시간
-## 기술 하이라이트
-
+기술 하이라이트
• Swift 6, SwiftUI, SwiftData로 제작
• iOS 18.0 이상 필요
• 도메인 주도 설계의 클린 아키텍처
• Apple 네이티브 프레임워크만 사용 (종속성 없음)
• 즉각적인 성능을 위한 오프라인 우선 설계
-## 영구 무료
-
+영구 무료
• 구독 없음
• 인앱 구매 없음
• 광고 없음
• 숨겨진 비용 없음
• 그저 작동하는 도구
-## 요구 사항
-
+요구 사항
• iOS 18.0 이상을 실행하는 iPhone
• 약 10MB 저장 공간
• 인터넷 연결 불필요
-## 지원
-
+지원
버그를 발견하거나 기능 요청이 있으신가요?
-• GitHub: github.com/ojung/workout-log
-• 이메일: your-email@example.com
-
-## 다음 단계
-
-향후 업데이트 예정 기능:
-• 신체 지표 추적 (체중, 체지방률)
-• 운동별 기록 히스토리
-• CSV로 운동 데이터 내보내기
-• 선택적 iCloud 동기화
-• Apple Watch 컴패니언 앱
-
-## 개발자 정보
-
-WorkOut Log는 클라우드 종속성 없이 심플하고 프라이빗한 운동 기록 앱을 원했던 소프트웨어 엔지니어이자 피트니스 애호가인 오정석이 만들었습니다.
-
-오픈 소스이며 피트니스 커뮤니티를 위해 ❤️로 제작되었습니다.
-
----
+• GitHub: https://github.com/jungseok-corine/WorkOut_Log
+• 이메일: fiverights99@gmail.com
오늘 WorkOut Log를 다운로드하고 운동 데이터를 제어하세요.
diff --git a/fastlane/metadata/ko/keywords.txt b/fastlane/metadata/ko/keywords.txt
new file mode 100644
index 0000000..5655f22
--- /dev/null
+++ b/fastlane/metadata/ko/keywords.txt
@@ -0,0 +1 @@
+운동,기록,헬스,오프라인,볼륨,차트,개인정보보호,세트,반복,웨이트,근력,피트니스,트레이닝,로그
diff --git a/fastlane/metadata/ko/marketing_url.txt b/fastlane/metadata/ko/marketing_url.txt
new file mode 100644
index 0000000..482b66c
--- /dev/null
+++ b/fastlane/metadata/ko/marketing_url.txt
@@ -0,0 +1 @@
+https://jungseok-corine.github.io/ben-homepage/
diff --git a/fastlane/metadata/ko/privacy_url.txt b/fastlane/metadata/ko/privacy_url.txt
new file mode 100644
index 0000000..301969f
--- /dev/null
+++ b/fastlane/metadata/ko/privacy_url.txt
@@ -0,0 +1 @@
+https://github.com/jungseok-corine/WorkOut_Log/blob/main/AppStore/PrivacyPolicy.md
diff --git a/fastlane/metadata/ko-KR/promotional_text.txt b/fastlane/metadata/ko/promotional_text.txt
similarity index 89%
rename from fastlane/metadata/ko-KR/promotional_text.txt
rename to fastlane/metadata/ko/promotional_text.txt
index 0c155f9..e8c4465 100644
--- a/fastlane/metadata/ko-KR/promotional_text.txt
+++ b/fastlane/metadata/ko/promotional_text.txt
@@ -1 +1 @@
-오프라인 운동 기록, 데이터 수집 제로. 세트 기록, 트렌드 시각화, 내 데이터는 내가 소유. 계정 없음, 클라우드 없음, 추적 없음—심플하고 안전한 운동 기록 앱.
\ No newline at end of file
+오프라인 운동 기록, 데이터 수집 제로. 세트 기록, 트렌드 시각화, 내 데이터는 내가 소유. 계정 없음, 클라우드 없음, 추적 없음—심플하고 안전한 운동 기록 앱.
diff --git a/fastlane/metadata/ko/release_notes.txt b/fastlane/metadata/ko/release_notes.txt
new file mode 100644
index 0000000..69e5746
--- /dev/null
+++ b/fastlane/metadata/ko/release_notes.txt
@@ -0,0 +1,12 @@
+초기 릴리스 - WorkOut Log v1.1
+
+• 완전한 오프라인 운동 기록
+• 세션 및 세트 추적
+• 맞춤형 운동 라이브러리
+• 일일/주간/월간 트렌드 차트
+• 100% 개인정보 보호 (데이터 수집 제로)
+• VoiceOver 접근성 지원
+• 영구 무료, 광고 없음
+
+계정 없음. 클라우드 없음. 추적 없음.
+모든 데이터는 내 기기에만 저장됩니다.
diff --git a/fastlane/metadata/ko/screenshots/README.txt b/fastlane/metadata/ko/screenshots/README.txt
new file mode 100644
index 0000000..ec65126
--- /dev/null
+++ b/fastlane/metadata/ko/screenshots/README.txt
@@ -0,0 +1 @@
+📸 NOTE: Screenshot placeholders created. Add actual PNG screenshots before submission.
diff --git a/fastlane/metadata/ko/screenshots/iphone65/01-launch.png b/fastlane/metadata/ko/screenshots/iphone65/01-launch.png
new file mode 100644
index 0000000..87cfa0c
Binary files /dev/null and b/fastlane/metadata/ko/screenshots/iphone65/01-launch.png differ
diff --git a/fastlane/metadata/ko/screenshots/iphone65/02-worklog_badges.png b/fastlane/metadata/ko/screenshots/iphone65/02-worklog_badges.png
new file mode 100644
index 0000000..c21d881
Binary files /dev/null and b/fastlane/metadata/ko/screenshots/iphone65/02-worklog_badges.png differ
diff --git a/fastlane/metadata/ko/screenshots/iphone65/03-worklog_list.png b/fastlane/metadata/ko/screenshots/iphone65/03-worklog_list.png
new file mode 100644
index 0000000..761ccaf
Binary files /dev/null and b/fastlane/metadata/ko/screenshots/iphone65/03-worklog_list.png differ
diff --git a/fastlane/metadata/ko/screenshots/iphone65/04-session_detail_empty.png b/fastlane/metadata/ko/screenshots/iphone65/04-session_detail_empty.png
new file mode 100644
index 0000000..7ad40c5
Binary files /dev/null and b/fastlane/metadata/ko/screenshots/iphone65/04-session_detail_empty.png differ
diff --git a/fastlane/metadata/ko/screenshots/iphone65/05-exercise_picker.png b/fastlane/metadata/ko/screenshots/iphone65/05-exercise_picker.png
new file mode 100644
index 0000000..0632825
Binary files /dev/null and b/fastlane/metadata/ko/screenshots/iphone65/05-exercise_picker.png differ
diff --git a/fastlane/metadata/ko/screenshots/iphone65/06-create_exercise.png b/fastlane/metadata/ko/screenshots/iphone65/06-create_exercise.png
new file mode 100644
index 0000000..070d72b
Binary files /dev/null and b/fastlane/metadata/ko/screenshots/iphone65/06-create_exercise.png differ
diff --git a/fastlane/metadata/ko/screenshots/iphone65/07-session_detail_selected.png b/fastlane/metadata/ko/screenshots/iphone65/07-session_detail_selected.png
new file mode 100644
index 0000000..4041c15
Binary files /dev/null and b/fastlane/metadata/ko/screenshots/iphone65/07-session_detail_selected.png differ
diff --git a/fastlane/metadata/ko/screenshots/iphone65/08-trends.png b/fastlane/metadata/ko/screenshots/iphone65/08-trends.png
new file mode 100644
index 0000000..8e756ec
Binary files /dev/null and b/fastlane/metadata/ko/screenshots/iphone65/08-trends.png differ
diff --git a/fastlane/metadata/ko/support_url.txt b/fastlane/metadata/ko/support_url.txt
new file mode 100644
index 0000000..482b66c
--- /dev/null
+++ b/fastlane/metadata/ko/support_url.txt
@@ -0,0 +1 @@
+https://jungseok-corine.github.io/ben-homepage/