diff --git a/CLAUDE.md b/CLAUDE.md index 31fb5023..2180877e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -17,11 +17,13 @@ |---|---| | `Runnect-iOS/Network/Foundation/Config.swift` | 서버 baseURL, kakaoRestAPIKey, tmapAPIKey, kakaoNativeAppKey, naverMapClientId, 개발자 패스워드 | | `Runnect-iOS/Network/Foundation/AdConfig.swift` | AdMob 광고 단위 ID | +| `Runnect-iOS/GoogleService-Info.plist` | Firebase 설정 | **관리 흐름**: -- 두 파일 모두 `.gitignore` 등록 + 메인 레포에서 추적 해제됨 -- 실제 값은 **별도 private 레포** `thingineeer/thingineeer-env` 의 `Runnect-env` 에서 관리 -- 클론 후 private 레포에서 두 파일을 가져와 동일 경로에 배치해야 빌드 가능 +- 위 파일 모두 `.gitignore` 등록 + 메인 레포에서 추적 해제됨 +- 실제 값은 **별도 private 레포** `thingineeer/thingineeer-env` 의 `Runnect-env/` 에서 관리 +- **신규 셋업**: `gh auth login` 후 git root 에서 `./bin/setup` 한 줄로 자동 배치 + - `gh` CLI 본인 계정 인증을 활용해 private 레포 접근. 권한 없는 계정은 자동 차단 **작업 시 주의**: - `git status --ignored` 가 아닌 일반 status 에는 안 보이지만, 실수로라도 **`git add -f` / staged 처리 / commit 금지** diff --git a/README.md b/README.md index 2a0ccea4..736916c9 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,24 @@ ### 앱스토어 링크: [Appstore](https://apps.apple.com/kr/app/runnect-%EC%BD%94%EC%8A%A4%EB%A5%BC-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EA%B3%B5%EC%9C%A0%ED%95%98%EB%8A%94-%EB%8D%B0%EC%9D%BC%EB%A6%AC-%EB%9F%AC%EB%8B%9D%EC%95%B1/id1663884202) v2.4.3 +## 신규 셋업 + +본 레포는 public 입니다. 빌드에 필요한 secret 파일들(`Config.swift`, `AdConfig.swift`, `GoogleService-Info.plist`)은 별도 private 레포 `thingineeer/thingineeer-env` 의 `Runnect-env/` 에서 관리됩니다. + +```bash +# 1. 클론 +git clone https://github.com/Runnect/Runnect-iOS.git +cd Runnect-iOS + +# 2. GitHub 인증 (한 번만) +gh auth login + +# 3. 비밀 파일 자동 배치 +./bin/setup +``` + +`./bin/setup` 은 `gh` CLI 본인 계정 인증을 사용해 private 레포에 접근하므로, 권한이 없는 계정에서는 자동 차단됩니다. + ![1](https://github.com/thingineeer/Runnect-iOS/assets/88179341/937f9e65-61e5-4298-b703-bc2cf5022bf6) ![2](https://github.com/thingineeer/Runnect-iOS/assets/88179341/ad913367-65f2-4839-9658-e538bccf2d6c) diff --git a/bin/setup b/bin/setup new file mode 100755 index 00000000..3f7e2a5c --- /dev/null +++ b/bin/setup @@ -0,0 +1,121 @@ +#!/usr/bin/env bash +# +# Runnect-iOS 신규 클론 후 비밀 파일을 자동 배치. +# - Config.swift (서버 baseURL, kakao/tmap/naverMap 키) +# - AdConfig.swift (AdMob 광고 단위 ID) +# - GoogleService-Info.plist (Firebase) +# +# 비밀 파일들은 private 레포 `thingineeer/thingineeer-env` 의 `Runnect-env/` 에 보관됨. +# 본 스크립트는 `gh` CLI 인증을 사용하므로 해당 private 레포 접근 권한이 있는 계정만 동작. +# +# Usage: ./bin/setup +# + +set -euo pipefail + +ENV_REPO="thingineeer/thingineeer-env" +ENV_SUBDIR="Runnect-env" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" +APP_DIR="${REPO_ROOT}/Runnect-iOS/Runnect-iOS" + +# ────────────────────────────────────────────────────────── +# 0. 사전 체크 +# ────────────────────────────────────────────────────────── + +cyan() { printf "\033[36m%s\033[0m\n" "$*"; } +green() { printf "\033[32m%s\033[0m\n" "$*"; } +yellow() { printf "\033[33m%s\033[0m\n" "$*"; } +red() { printf "\033[31m%s\033[0m\n" "$*"; } + +cyan "📦 Runnect-iOS secret setup" +echo " 대상 디렉토리: ${APP_DIR}" +echo + +if ! command -v gh >/dev/null 2>&1; then + red "❌ gh CLI 가 필요합니다." + echo " 설치: brew install gh" + exit 1 +fi + +if ! gh auth status >/dev/null 2>&1; then + red "❌ GitHub 인증이 필요합니다." + echo " 실행: gh auth login" + exit 1 +fi + +if [[ ! -d "${APP_DIR}" ]]; then + red "❌ 잘못된 위치에서 실행 중입니다." + echo " 기대 경로: ${APP_DIR}" + echo " 현재 git root: ${REPO_ROOT}" + exit 1 +fi + +# ────────────────────────────────────────────────────────── +# 1. private env repo 임시 클론 +# ────────────────────────────────────────────────────────── + +TMPDIR="$(mktemp -d -t runnect-env-XXXXXX)" +trap 'rm -rf "${TMPDIR}"' EXIT + +cyan "🔐 ${ENV_REPO} 클론 중..." +if ! gh repo clone "${ENV_REPO}" "${TMPDIR}/env" -- --depth=1 --quiet 2>/dev/null; then + red "❌ ${ENV_REPO} 접근 불가." + echo " 권한 있는 계정인지 확인하세요 (private 레포)." + echo " 실행: gh auth status" + exit 1 +fi + +ENV_DIR="${TMPDIR}/env/${ENV_SUBDIR}" +if [[ ! -d "${ENV_DIR}" ]]; then + red "❌ ${ENV_REPO}/${ENV_SUBDIR} 가 없습니다." + echo " private 레포 구조를 확인하세요." + exit 1 +fi + +# ────────────────────────────────────────────────────────── +# 2. 파일 배치 +# ────────────────────────────────────────────────────────── + +declare -a MAPPING=( + "Config.swift|Network/Foundation/Config.swift" + "AdConfig.swift|Network/Foundation/AdConfig.swift" + "GoogleService-Info.plist|GoogleService-Info.plist" +) + +cyan "📋 파일 배치" +for entry in "${MAPPING[@]}"; do + src_name="${entry%%|*}" + dst_rel="${entry##*|}" + src_path="${ENV_DIR}/${src_name}" + dst_path="${APP_DIR}/${dst_rel}" + + if [[ ! -f "${src_path}" ]]; then + yellow " ⚠️ 스킵: ${src_name} (env 레포에 없음)" + continue + fi + + mkdir -p "$(dirname "${dst_path}")" + cp "${src_path}" "${dst_path}" + green " ✓ ${dst_rel}" +done + +# ────────────────────────────────────────────────────────── +# 3. .gitignore 처리 검증 +# ────────────────────────────────────────────────────────── + +cyan "🔒 추적 상태 검증" +cd "${REPO_ROOT}" +for entry in "${MAPPING[@]}"; do + dst_rel="${entry##*|}" + rel_from_root="Runnect-iOS/Runnect-iOS/${dst_rel}" + if git check-ignore -q "${rel_from_root}" 2>/dev/null; then + green " ✓ ${dst_rel} (gitignored)" + else + yellow " ⚠️ ${dst_rel} 가 .gitignore 에 없습니다. 커밋되지 않도록 주의하세요." + fi +done + +echo +green "✅ Setup 완료. Xcode 에서 빌드 가능합니다." +echo " 메인 앱 스킴: Runnect-iOS"