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
21 changes: 20 additions & 1 deletion Tekken8 Frame Data/ci_scripts/ci_post_clone.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set -eu

: "${API_KEY:?Xcode Cloud API_KEY is missing}"
: "${SUPABASE_URL:?Xcode Cloud SUPABASE_URL is missing}"
: "${FIREBASE_GOOGLE_SERVICE_INFO_PLIST_BASE64:?Xcode Cloud FIREBASE_GOOGLE_SERVICE_INFO_PLIST_BASE64 is missing}"
: "${CI_PRIMARY_REPOSITORY_PATH:?Xcode Cloud CI_PRIMARY_REPOSITORY_PATH is missing}"

fail() {
Expand Down Expand Up @@ -43,12 +44,15 @@ validate_api_key

config_directory="${CI_PRIMARY_REPOSITORY_PATH}/Tekken8 Frame Data/TK8"
config_path="${config_directory}/Secrets.xcconfig"
firebase_config_path="${config_directory}/GoogleService-Info.plist"
[ -d "$config_directory" ] || fail "TK8 configuration directory is missing."

umask 077
temporary_config="$(mktemp "${config_directory}/Secrets.xcconfig.XXXXXX")"
temporary_firebase_config="$(mktemp "${config_directory}/GoogleService-Info.plist.XXXXXX")"
cleanup() {
[ -z "${temporary_config:-}" ] || rm -f "$temporary_config"
[ -z "${temporary_firebase_config:-}" ] || rm -f "$temporary_firebase_config"
}
trap cleanup EXIT

Expand All @@ -59,4 +63,19 @@ chmod 600 "$temporary_config"
mv -f "$temporary_config" "$config_path"
temporary_config=""

echo "Generated TK8/Secrets.xcconfig from Xcode Cloud environment variables."
if ! /usr/bin/printf '%s' "$FIREBASE_GOOGLE_SERVICE_INFO_PLIST_BASE64" | /usr/bin/base64 -D > "$temporary_firebase_config"; then
fail "Xcode Cloud FIREBASE_GOOGLE_SERVICE_INFO_PLIST_BASE64 is not valid Base64."
fi

if ! /usr/bin/plutil -lint "$temporary_firebase_config" >/dev/null; then
fail "Decoded Firebase GoogleService-Info.plist is invalid."
fi

firebase_bundle_id="$(/usr/bin/plutil -extract BUNDLE_ID raw "$temporary_firebase_config" 2>/dev/null || true)"
[ "$firebase_bundle_id" = "com.moongoon.TK8" ] || fail "Firebase GoogleService-Info.plist has an unexpected BUNDLE_ID."

chmod 600 "$temporary_firebase_config"
mv -f "$temporary_firebase_config" "$firebase_config_path"
temporary_firebase_config=""

echo "Generated TK8 build configuration from Xcode Cloud environment variables."
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ frame_data_version 증가
- `TK8Tests`: 모델 decoding/hash, command tokenization, 한/영 번역, 기술 필터, 메모 CRUD와 백업 merge를 검증한다.
- `SupabaseAPITests`: mock을 사용해 Supabase adapter 경계를 검증한다.
- CI의 `swift.yml`은 SPM 의존성을 해석하고 `Tekken8 Frame Data` scheme을 Simulator 대상으로 clean build한다. 현재 workflow에는 테스트 실행 단계가 별도로 없다.
- Xcode Cloud release workflow는 `main` 변경 시 Archive한다. `ci_scripts/ci_post_clone.sh`가 `CI_PRIMARY_REPOSITORY_PATH`의 실제 checkout 위치를 기준으로 workflow의 secret 환경변수 `API_KEY`, `SUPABASE_URL`를 추적되지 않는 `TK8/Secrets.xcconfig`에 원자적으로 기록한 뒤 Archive가 진행된다. 둘 중 하나라도 누락되면 스크립트가 실패해 잘못된 설정의 배포를 막는다. 기존 설정 파일이 있어도 최종 권한은 `600`으로 강제한다. `API_KEY`는 `sb_publishable_` key 또는 `role=anon` legacy JWT만 허용하며, secret/service-role key는 사용하지 않는다.
- Xcode Cloud release workflow는 `main` 변경 시 Archive한다. `ci_scripts/ci_post_clone.sh`가 `CI_PRIMARY_REPOSITORY_PATH`의 실제 checkout 위치를 기준으로 workflow의 secret 환경변수 `API_KEY`, `SUPABASE_URL`를 추적되지 않는 `TK8/Secrets.xcconfig`에 원자적으로 기록한 뒤 Archive가 진행된다. 둘 중 하나라도 누락되면 스크립트가 실패해 잘못된 설정의 배포를 막는다. 기존 설정 파일이 있어도 최종 권한은 `600`으로 강제한다. `API_KEY`는 `sb_publishable_` key 또는 `role=anon` legacy JWT만 허용하며, secret/service-role key는 사용하지 않는다. Firebase Analytics 초기화에 필요한 `TK8/GoogleService-Info.plist`는 `FIREBASE_GOOGLE_SERVICE_INFO_PLIST_BASE64` secret environment variable을 post-clone 단계에서 Base64 복원한다. 복원 파일은 plist 문법과 `BUNDLE_ID=com.moongoon.TK8`을 검증하고 권한 `600`으로 원자적으로 교체한다. 따라서 Firebase configuration은 Git에 추적하지 않는다.
- Core Data 관련 테스트는 in-memory persistent store를 사용한다.

## 구조 변경 시 동기화 대상
Expand Down
Loading