Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -303,4 +303,12 @@ app.*.map.json
# FVM Version Cache
.fvm/

# Fastlane
ios/fastlane/report.xml
ios/fastlane/README.md
ios/fastlane/screenshots/
ios/fastlane/test_output/
*.ipa
*.dSYM.zip

/secrets/*
85 changes: 84 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,76 @@ build-prod-ios: _ensure-env-prod
$(FLUTTER) build ios --release --dart-define=FLAVOR=prod
@echo "✅ 빌드 완료!"

# ============================================
# 🍎 iOS 배포 (Fastlane)
# ============================================

# iOS 배포 도구 설치 (최초 1회)
setup-ios-deploy:
@echo "======iOS 배포 도구 설치 중...======"
@which bundle > /dev/null || (echo "❌ Bundler가 없습니다. gem install bundler 실행하세요." && exit 1)
cd ios && bundle install
@echo "✅ Fastlane 설치 완료!"

# .env.prod에서 ASC 인증 환경변수 검증 헬퍼
_load-asc-env:
@if [ ! -f ".env.prod" ]; then \
echo "❌ .env.prod 파일이 없습니다. make prepare-env-prod 를 먼저 실행하세요."; \
exit 1; \
fi
@ASC_KEY_ID=$$(grep '^ASC_KEY_ID=' .env.prod | cut -d '=' -f2); \
ASC_ISSUER_ID=$$(grep '^ASC_ISSUER_ID=' .env.prod | cut -d '=' -f2); \
ASC_KEY_BASE64=$$(grep '^ASC_KEY_BASE64=' .env.prod | cut -d '=' -f2); \
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

[P0] .env.prod에서 값을 읽을 때 cut -d '=' -f2를 사용하면 base64 값에 = 패딩이 포함된 경우 뒤가 잘려서 ASC_KEY_BASE64가 손상됩니다. cut -d '=' -f2- 또는 sed 's/^ASC_KEY_BASE64=//'처럼 전체 값을 보존하도록 수정이 필요합니다.

Suggested change
ASC_KEY_BASE64=$$(grep '^ASC_KEY_BASE64=' .env.prod | cut -d '=' -f2); \
ASC_KEY_BASE64=$$(grep '^ASC_KEY_BASE64=' .env.prod | cut -d '=' -f2-); \

Copilot uses AI. Check for mistakes.
if [ -z "$$ASC_KEY_ID" ] || [ -z "$$ASC_ISSUER_ID" ] || [ -z "$$ASC_KEY_BASE64" ]; then \
echo "❌ .env.prod에 App Store Connect API 키 정보가 누락되었습니다."; \
echo " 필요한 값: ASC_KEY_ID, ASC_ISSUER_ID, ASC_KEY_BASE64"; \
echo ""; \
echo " [설정 방법]"; \
echo " 1. App Store Connect → 사용자 및 액세스 → 통합 → API 키 생성"; \
echo " 2. .p8 파일을 base64 인코딩: base64 -i AuthKey_XXXX.p8"; \
echo " 3. .env.prod에 추가:"; \
echo " ASC_KEY_ID=키ID"; \
echo " ASC_ISSUER_ID=발급자ID"; \
echo " ASC_KEY_BASE64=base64인코딩값"; \
exit 1; \
fi

# IPA 빌드 (내부 헬퍼 - Fastfile에서 호출)
_build-ios-ipa: _ensure-env-prod
@echo "======iOS IPA 빌드 중...======"
$(FLUTTER) build ipa --release --dart-define=FLAVOR=prod --export-options-plist=ios/ExportOptions.plist 2>/dev/null || \
$(FLUTTER) build ipa --release --dart-define=FLAVOR=prod
@echo "✅ IPA 빌드 완료!"

# TestFlight 배포
deploy-ios-testflight: _ensure-env-prod _load-asc-env
@echo "======iOS TestFlight 배포 중...======"
@# IPA 빌드
$(MAKE) _build-ios-ipa
@# Fastlane 실행 (환경변수 전달: base64 디코딩하여 키 내용 전달)
@export ASC_KEY_ID=$$(grep '^ASC_KEY_ID=' .env.prod | cut -d '=' -f2); \
export ASC_ISSUER_ID=$$(grep '^ASC_ISSUER_ID=' .env.prod | cut -d '=' -f2); \
export ASC_KEY_CONTENT=$$(grep '^ASC_KEY_BASE64=' .env.prod | cut -d '=' -f2 | base64 --decode); \
export IPA_PATH=$$(ls build/ios/ipa/*.ipa 2>/dev/null | head -1); \
cd ios && bundle exec fastlane beta
Comment on lines +336 to +340
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

[P1] macOS 기본 base64--decode 옵션을 지원하지 않아 iOS 배포 환경(대부분 mac)에서 ASC_KEY_CONTENT 디코딩이 실패합니다. base64 -D(mac)와 base64 --decode(GNU)를 모두 처리하거나, python3 -m base64 -d 같은 플랫폼 독립적인 디코딩으로 바꾸는 게 안전합니다.

Copilot uses AI. Check for mistakes.
@echo "✅ TestFlight 배포 완료!"

# TestFlight 배포 (별칭)
deploy-ios: deploy-ios-testflight

# App Store 제출
deploy-ios-appstore: _ensure-env-prod _load-asc-env
@echo "======iOS App Store 제출 중...======"
@# IPA 빌드
$(MAKE) _build-ios-ipa
@# Fastlane 실행 (환경변수 전달: base64 디코딩하여 키 내용 전달)
@export ASC_KEY_ID=$$(grep '^ASC_KEY_ID=' .env.prod | cut -d '=' -f2); \
export ASC_ISSUER_ID=$$(grep '^ASC_ISSUER_ID=' .env.prod | cut -d '=' -f2); \
export ASC_KEY_CONTENT=$$(grep '^ASC_KEY_BASE64=' .env.prod | cut -d '=' -f2 | base64 --decode); \
export IPA_PATH=$$(ls build/ios/ipa/*.ipa 2>/dev/null | head -1); \
Comment on lines +352 to +355
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

[P0] App Store 제출 타겟도 .env.prod 값을 cut -d '=' -f2로 파싱하고 있어 base64 값에 =가 있으면 잘립니다. TestFlight/Release 모두 동일하게 -f2-로 수정하지 않으면 배포가 환경에 따라 즉시 실패할 수 있습니다.

Copilot uses AI. Check for mistakes.
cd ios && bundle exec fastlane release
@echo "✅ App Store 제출 완료!"

# ============================================
# 📋 도움말
# ============================================
Expand Down Expand Up @@ -330,10 +400,23 @@ help:
@echo " make build-dev-ios - 개발 iOS 빌드"
@echo " make build-prod-ios - 프로덕션 iOS 빌드"
@echo ""
@echo "🍎 iOS 배포 (Fastlane):"
@echo " make setup-ios-deploy - Fastlane 설치 (최초 1회)"
@echo " make deploy-ios - TestFlight 배포 (별칭)"
@echo " make deploy-ios-testflight - TestFlight 배포"
@echo " make deploy-ios-appstore - App Store 제출"
@echo ""
@echo " [사전 준비]"
@echo " 1. App Store Connect → 사용자 및 액세스 → 통합 → API 키 생성"
@echo " 2. .p8 파일을 base64 인코딩: base64 -i AuthKey_XXXX.p8"
@echo " 3. .env.prod에 ASC_KEY_ID, ASC_ISSUER_ID, ASC_KEY_BASE64 추가"
@echo ""

.PHONY: setup setup-signing fresh clean-ios clean-ios-quick clean-android codegen codegen-watch \
version bump-build bump-patch bump-minor bump-major \
decrypt-env-dev decrypt-env-prod prepare-env-dev prepare-env-prod \
build-env-dev build-env-prod _ensure-env-dev _ensure-env-prod run run-dev run-local run-prod \
build-dev-android build-prod-android build-prod-android-aab \
build-dev-ios build-prod-ios help
build-dev-ios build-prod-ios \
setup-ios-deploy _load-asc-env _build-ios-ipa \
deploy-ios deploy-ios-testflight deploy-ios-appstore help
7 changes: 5 additions & 2 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<!-- image_picker uses system Photo Picker (no broad storage permission needed) -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" tools:node="remove" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" tools:node="remove" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>


<application android:label="BottleNote" android:name="${applicationName}" android:icon="@mipmap/launcher_icon" android:networkSecurityConfig="@xml/network_security_config">
Expand Down
3 changes: 3 additions & 0 deletions ios/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
source "https://rubygems.org"

gem "fastlane", "~> 2.225"
Loading