#!/usr/bin/env node const fs = require("fs"); const path = require("path"); const { execSync } = require("child_process"); /** * 버전 동기화 스크립트 * package.json의 버전을 Android build.gradle과 iOS Info.plist에 동기화합니다. */ // package.json에서 버전 읽기 const packageJsonPath = path.join(__dirname, "..", "package.json"); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")); const version = packageJson.version; // --check 플래그가 있으면 버전 검증만 수행 const isCheckMode = process.argv.includes("--check"); if (isCheckMode) { console.log(`🔍 Checking version consistency for ${version}...`); } else { console.log(`🔄 Syncing version ${version} to mobile platforms...`); } // 버전을 숫자로 변환 (예: "1.2.3" -> 10203) function versionToCode(version) { const parts = version.split(".").map(Number); return parts[0] * 10000 + parts[1] * 100 + parts[2]; } const versionCode = versionToCode(version); // Android build.gradle 업데이트 const androidBuildGradlePath = path.join( __dirname, "..", "android", "app", "build.gradle" ); if (fs.existsSync(androidBuildGradlePath)) { if (isCheckMode) { console.log("📱 Checking Android build.gradle versions..."); const buildGradleContent = fs.readFileSync(androidBuildGradlePath, "utf8"); const versionCodeMatch = buildGradleContent.match(/versionCode\s+(\d+)/); const versionNameMatch = buildGradleContent.match( /versionName\s+"([^"]*)"/ ); if (versionCodeMatch && versionNameMatch) { const currentVersionCode = parseInt(versionCodeMatch[1]); const currentVersionName = versionNameMatch[1]; if ( currentVersionCode === versionCode && currentVersionName === version ) { console.log( `✅ Android versions are in sync: ${version} (${versionCode})` ); } else { console.log( `❌ Android version mismatch: expected ${version} (${versionCode}), found ${currentVersionName} (${currentVersionCode})` ); } } else { console.log("❌ Could not find version info in Android build.gradle"); } } else { console.log("📱 Updating Android build.gradle..."); let buildGradleContent = fs.readFileSync(androidBuildGradlePath, "utf8"); // versionCode 업데이트 buildGradleContent = buildGradleContent.replace( /versionCode\s+\d+/, `versionCode ${versionCode}` ); // versionName 업데이트 buildGradleContent = buildGradleContent.replace( /versionName\s+"[^"]*"/, `versionName "${version}"` ); fs.writeFileSync(androidBuildGradlePath, buildGradleContent); console.log(`✅ Android version updated: ${version} (${versionCode})`); } } else { console.log("⚠️ Android build.gradle not found, skipping..."); } // iOS Info.plist 업데이트 const iosInfoPlistPath = path.join( __dirname, "..", "ios", "App", "App", "Info.plist" ); if (fs.existsSync(iosInfoPlistPath)) { if (isCheckMode) { console.log("🍎 Checking iOS Info.plist versions..."); try { const currentVersion = execSync( `/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" "${iosInfoPlistPath}"`, { stdio: "pipe", } ) .toString() .trim(); const currentBuildNumber = execSync( `/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "${iosInfoPlistPath}"`, { stdio: "pipe", } ) .toString() .trim(); if ( currentVersion === version && parseInt(currentBuildNumber) === versionCode ) { console.log(`✅ iOS versions are in sync: ${version} (${versionCode})`); } else { console.log( `❌ iOS version mismatch: expected ${version} (${versionCode}), found ${currentVersion} (${currentBuildNumber})` ); } } catch (error) { console.log( "⚠️ Could not check iOS Info.plist (requires macOS), skipping..." ); } } else { console.log("🍎 Updating iOS Info.plist..."); try { // CFBundleShortVersionString 업데이트 (앱 버전) execSync( `/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${version}" "${iosInfoPlistPath}"`, { stdio: "pipe", } ); // CFBundleVersion 업데이트 (빌드 번호) execSync( `/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${versionCode}" "${iosInfoPlistPath}"`, { stdio: "pipe", } ); console.log(`✅ iOS version updated: ${version} (${versionCode})`); } catch (error) { console.log( "⚠️ Could not update iOS Info.plist (requires macOS), skipping..." ); } } } else { console.log("⚠️ iOS Info.plist not found, skipping..."); } // Capacitor config 업데이트 (선택사항) const capacitorConfigPath = path.join(__dirname, "..", "capacitor.config.ts"); if (fs.existsSync(capacitorConfigPath)) { console.log("⚡ Updating Capacitor config..."); let configContent = fs.readFileSync(capacitorConfigPath, "utf8"); // 버전 정보를 추가할 수 있지만, 현재는 스킵 console.log("✅ Capacitor config checked"); } if (isCheckMode) { console.log("🎉 Version check completed!"); } else { console.log("🎉 Version sync completed!"); console.log(`📦 Version: ${version}`); console.log(`🔢 Build Code: ${versionCode}`); console.log(""); console.log("Next steps:"); console.log("1. Run: npm run mobile:sync"); console.log("2. Build: npm run android:bundle (or ios:archive)"); console.log("3. Test on devices"); }