From e4c6a0b299d743c6d88c9ffbc904efa7b5441d1a Mon Sep 17 00:00:00 2001 From: ChoiAnYong Date: Thu, 15 Jan 2026 17:55:09 +0900 Subject: [PATCH 01/16] =?UTF-8?q?docs:=20#1-=20gitignore=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 5183772..9fbec88 100644 --- a/.gitignore +++ b/.gitignore @@ -87,3 +87,6 @@ Tuist/.build # Fastlane.swift runner binary **/fastlane/FastlaneRunner + +# 환경 변수 +**/fastlane/.env.default From 4a11365a4edf8e5d9c472d57b2a1ea3521de28b1 Mon Sep 17 00:00:00 2001 From: ChoiAnYong Date: Thu, 15 Jan 2026 17:58:36 +0900 Subject: [PATCH 02/16] =?UTF-8?q?chore:=20#1=20-=20Tuist=20=EC=84=B8?= =?UTF-8?q?=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .swiftlint.yml | 49 ++++++++++ Plugins/ConfigPlugin/Plugin.swift | 10 ++ .../Configurations.swift | 35 +++++++ Plugins/DependencyPlugin/Plugin.swift | 10 ++ .../Dependency+Project.swift | 44 +++++++++ .../Dependency+SPM.swift | 21 +++++ .../ProjectDescriptionHelpers/Path+.swift | 35 +++++++ Plugins/EnvPlugin/Plugin.swift | 10 ++ .../Environment.swift | 29 ++++++ .../ProjectDescriptionHelpers/InfoPlist.swift | 66 ++++++++++++++ .../Settings+Extension.swift | 86 ++++++++++++++++++ .../Target+Extension.swift | 67 ++++++++++++++ Plugins/TemplatePlugin/Plugin.swift | 11 +++ .../Templates/Feature/Empty.stencil | 8 ++ .../Templates/Feature/Feature.swift | 50 ++++++++++ .../Templates/Feature/Project.stencil | 25 +++++ Projects/App/Project.swift | 29 ++++++ .../AppIcon~ios-marketing.png | Bin 0 -> 160963 bytes .../AppIcon.appiconset/Contents.json | 36 ++++++++ .../Resources/Assets.xcassets/Contents.json | 6 ++ .../App/Resources/LaunchScreen.storyboard | 48 ++++++++++ .../App/Sources/Application/AppDelegate.swift | 40 ++++++++ .../Sources/Application/SceneDelegate.swift | 49 ++++++++++ Projects/Core/Project.swift | 24 +++++ .../Sources/Extensions/UIKit+/Empty.swift | 8 ++ Projects/Data/Project.swift | 27 ++++++ .../Data/Sources/Repository/RepoEmpty.swift | 8 ++ .../Data/Sources/Transform/TransEmpty.swift | 8 ++ Projects/Domain/Project.swift | 24 +++++ .../Sources/Interface/InterfaceEmpty.swift | 8 ++ .../Domain/Sources/Model/ModelEmpty.swift | 8 ++ .../Domain/Sources/UseCase/UsecaseEmpty.swift | 8 ++ .../BaseFeatureDependency/Project.swift | 26 ++++++ .../Sources/BaseEmpty.swift | 8 ++ Projects/Features/HomeFeature/Project.swift | 26 ++++++ .../Features/HomeFeature/Sources/HomeVC.swift | 37 ++++++++ Projects/Features/RootFeature/Project.swift | 26 ++++++ .../Features/RootFeature/Sources/RootVC.swift | 33 +++++++ Projects/Modules/DSKit/Project.swift | 24 +++++ .../DSKit/Sources/Component/DSCEmpty.swift | 8 ++ Projects/Modules/DSKit/Sources/DSEmpty.swift | 8 ++ Projects/Modules/Networks/Project.swift | 25 +++++ .../Networks/Sources/API/APIEmpty.swift | 8 ++ .../Networks/Sources/Base/NBaseEmpty.swift | 8 ++ .../Networks/Sources/Entity/EntityEmpty.swift | 8 ++ .../Sources/Service/ServiceEmpty.swift | 8 ++ Projects/Modules/ThirdPartyLibs/Project.swift | 29 ++++++ .../ThirdPartyLibs/Sources/Empty.swift | 8 ++ Tuist.swift | 11 +++ Tuist/Package.resolved | 78 ++++++++++++++++ Tuist/Package.swift | 26 ++++++ .../Project+MakeModule.swift | 49 ++++++++++ .../TargetScript+Extension.swift | 39 ++++++++ Workspace.swift | 8 ++ mise.toml | 2 + xcconfigs/NDGL.entitlements | 1 + 56 files changed, 1391 insertions(+) create mode 100644 .swiftlint.yml create mode 100644 Plugins/ConfigPlugin/Plugin.swift create mode 100644 Plugins/ConfigPlugin/ProjectDescriptionHelpers/Configurations.swift create mode 100644 Plugins/DependencyPlugin/Plugin.swift create mode 100644 Plugins/DependencyPlugin/ProjectDescriptionHelpers/Dependency+Project.swift create mode 100644 Plugins/DependencyPlugin/ProjectDescriptionHelpers/Dependency+SPM.swift create mode 100644 Plugins/DependencyPlugin/ProjectDescriptionHelpers/Path+.swift create mode 100644 Plugins/EnvPlugin/Plugin.swift create mode 100644 Plugins/EnvPlugin/ProjectDescriptionHelpers/Environment.swift create mode 100644 Plugins/EnvPlugin/ProjectDescriptionHelpers/InfoPlist.swift create mode 100644 Plugins/EnvPlugin/ProjectDescriptionHelpers/Settings+Extension.swift create mode 100644 Plugins/EnvPlugin/ProjectDescriptionHelpers/Target+Extension.swift create mode 100644 Plugins/TemplatePlugin/Plugin.swift create mode 100644 Plugins/TemplatePlugin/Templates/Feature/Empty.stencil create mode 100644 Plugins/TemplatePlugin/Templates/Feature/Feature.swift create mode 100644 Plugins/TemplatePlugin/Templates/Feature/Project.stencil create mode 100644 Projects/App/Project.swift create mode 100644 Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon~ios-marketing.png create mode 100644 Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 Projects/App/Resources/Assets.xcassets/Contents.json create mode 100644 Projects/App/Resources/LaunchScreen.storyboard create mode 100644 Projects/App/Sources/Application/AppDelegate.swift create mode 100644 Projects/App/Sources/Application/SceneDelegate.swift create mode 100644 Projects/Core/Project.swift create mode 100644 Projects/Core/Sources/Extensions/UIKit+/Empty.swift create mode 100644 Projects/Data/Project.swift create mode 100644 Projects/Data/Sources/Repository/RepoEmpty.swift create mode 100644 Projects/Data/Sources/Transform/TransEmpty.swift create mode 100644 Projects/Domain/Project.swift create mode 100644 Projects/Domain/Sources/Interface/InterfaceEmpty.swift create mode 100644 Projects/Domain/Sources/Model/ModelEmpty.swift create mode 100644 Projects/Domain/Sources/UseCase/UsecaseEmpty.swift create mode 100644 Projects/Features/BaseFeatureDependency/Project.swift create mode 100644 Projects/Features/BaseFeatureDependency/Sources/BaseEmpty.swift create mode 100644 Projects/Features/HomeFeature/Project.swift create mode 100644 Projects/Features/HomeFeature/Sources/HomeVC.swift create mode 100644 Projects/Features/RootFeature/Project.swift create mode 100644 Projects/Features/RootFeature/Sources/RootVC.swift create mode 100644 Projects/Modules/DSKit/Project.swift create mode 100644 Projects/Modules/DSKit/Sources/Component/DSCEmpty.swift create mode 100644 Projects/Modules/DSKit/Sources/DSEmpty.swift create mode 100644 Projects/Modules/Networks/Project.swift create mode 100644 Projects/Modules/Networks/Sources/API/APIEmpty.swift create mode 100644 Projects/Modules/Networks/Sources/Base/NBaseEmpty.swift create mode 100644 Projects/Modules/Networks/Sources/Entity/EntityEmpty.swift create mode 100644 Projects/Modules/Networks/Sources/Service/ServiceEmpty.swift create mode 100644 Projects/Modules/ThirdPartyLibs/Project.swift create mode 100644 Projects/Modules/ThirdPartyLibs/Sources/Empty.swift create mode 100644 Tuist.swift create mode 100644 Tuist/Package.resolved create mode 100644 Tuist/Package.swift create mode 100644 Tuist/ProjectDescriptionHelpers/Project+MakeModule.swift create mode 100644 Tuist/ProjectDescriptionHelpers/TargetScript+Extension.swift create mode 100644 Workspace.swift create mode 100644 mise.toml create mode 100644 xcconfigs/NDGL.entitlements diff --git a/.swiftlint.yml b/.swiftlint.yml new file mode 100644 index 0000000..1cae64d --- /dev/null +++ b/.swiftlint.yml @@ -0,0 +1,49 @@ +# 검사에서 제외할 디렉토리 지정 +excluded: + - Tuist + - Tuist/Dependencies + - Carthage + - Pods + - .build + - Derived + - fastlane + - "**/*.generated.swift" + - "**/Derived/**" + - "**/*.tuist.generated.swift" + - "**/TuistBundle+*.swift" + - "**/TuistAssets+*.swift" + - "**/Project.swift" + - Scripts + +# 추가로 활성화할 규칙들 +opt_in_rules: + - empty_count # count == 0 대신 isEmpty 사용 권장 + - empty_string # "" 대신 String() 사용 권장 + - fatal_error_message # fatalError 메시지 필수 + - first_where # filter().first 대신 first(where:) 사용 권장 + - force_unwrapping # 강제 언래핑(!) 사용 제한 + - implicit_return # 암시적 return 사용 제한 + - modifier_order # 수정자 순서 강제 + - operator_usage_whitespace # 연산자 주변 공백 + - sorted_imports # import 알파벳 순 정렬 + +# 비활성화할 일반적인 규칙 +disabled_rules: + - trailing_whitespace + - todo + - trailing_newline + - multiple_closures_with_trailing_closure + - leading_whitespace + +# 라인 길이 설정 +line_length: + warning: 120 + error: 300 + +# 타입 본문 길이 설정 +type_body_length: + warning: 400 + error: 500 + +analyzer_rules: + - unused_import # 사용하지 않는 import diff --git a/Plugins/ConfigPlugin/Plugin.swift b/Plugins/ConfigPlugin/Plugin.swift new file mode 100644 index 0000000..ff1a242 --- /dev/null +++ b/Plugins/ConfigPlugin/Plugin.swift @@ -0,0 +1,10 @@ +// +// Plugin.swift +// EnvPlugin +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription + +let configPlugin = Plugin(name: "ConfigPlugin") diff --git a/Plugins/ConfigPlugin/ProjectDescriptionHelpers/Configurations.swift b/Plugins/ConfigPlugin/ProjectDescriptionHelpers/Configurations.swift new file mode 100644 index 0000000..68683c9 --- /dev/null +++ b/Plugins/ConfigPlugin/ProjectDescriptionHelpers/Configurations.swift @@ -0,0 +1,35 @@ +// +// Configurations.swift +// EnvPlugin +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription + +public struct XCConfig { + public struct Path { + static var debug: ProjectDescription.Path { + .relativeToRoot("xcconfigs/Debug.xcconfig") + } + + static var release: ProjectDescription.Path { + .relativeToRoot("xcconfigs/Release.xcconfig") + } + } + + public static let framework: [Configuration] = [ + .debug(name: "Debug", xcconfig: Path.debug), + .release(name: "Release", xcconfig: Path.release) + ] + + public static let demo: [Configuration] = [ + .debug(name: "Debug", xcconfig: Path.debug), + .release(name: "Release", xcconfig: Path.release) + ] + + public static let prod: [Configuration] = [ + .debug(name: "Debug", xcconfig: Path.debug), + .release(name: "Release", xcconfig: Path.release) + ] +} diff --git a/Plugins/DependencyPlugin/Plugin.swift b/Plugins/DependencyPlugin/Plugin.swift new file mode 100644 index 0000000..2798840 --- /dev/null +++ b/Plugins/DependencyPlugin/Plugin.swift @@ -0,0 +1,10 @@ +// +// Plugin.swift +// EnvPlugin +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription + +let dependencyPlugin = Plugin(name: "DependencyPlugin") diff --git a/Plugins/DependencyPlugin/ProjectDescriptionHelpers/Dependency+Project.swift b/Plugins/DependencyPlugin/ProjectDescriptionHelpers/Dependency+Project.swift new file mode 100644 index 0000000..4e65b76 --- /dev/null +++ b/Plugins/DependencyPlugin/ProjectDescriptionHelpers/Dependency+Project.swift @@ -0,0 +1,44 @@ +// +// Dependency+Project.swift +// EnvPlugin +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription + +public extension TargetDependency { + struct Features { + public struct Home {} + } + + struct Modules {} +} + +public extension TargetDependency { + static let data = TargetDependency.project(target: "Data", path: .data) + static let domain = TargetDependency.project(target: "Domain", path: .domain) + static let core = TargetDependency.project(target: "Core", path: .core) +} + +public extension TargetDependency.Modules { + static let dsKit = TargetDependency.project(target: "DSKit", path: .relativeToModules("DSKit")) + static let networks = TargetDependency.project(target: "Networks", path: .relativeToModules("Networks")) + static let thirdPartyLibs = TargetDependency.project(target: "ThirdPartyLibs", path: .relativeToModules("ThirdPartyLibs")) +} + +public extension TargetDependency.Features { + static func project(name: String, group: String) -> TargetDependency { + .project(target: "\(group)\(name)", path: .relativeToFeature("\(group)\(name)")) + } + + static let baseFeatureDependency = TargetDependency.project(target: "BaseFeatureDependency", path: .relativeToFeature("BaseFeatureDependency")) + + static let rootFeature = TargetDependency.project(target: "RootFeature", path: .relativeToFeature("RootFeature")) +} + +public extension TargetDependency.Features.Home { + static let group = "Home" + + static let feature = TargetDependency.Features.project(name: "Feature", group: group) +} diff --git a/Plugins/DependencyPlugin/ProjectDescriptionHelpers/Dependency+SPM.swift b/Plugins/DependencyPlugin/ProjectDescriptionHelpers/Dependency+SPM.swift new file mode 100644 index 0000000..d4083ed --- /dev/null +++ b/Plugins/DependencyPlugin/ProjectDescriptionHelpers/Dependency+SPM.swift @@ -0,0 +1,21 @@ +// +// Dependency+SPM.swift +// EnvPlugin +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription + +public extension TargetDependency { + enum SPM {} +} + +public extension TargetDependency.SPM { + static let SnapKit = TargetDependency.external(name: "SnapKit") + static let Then = TargetDependency.external(name: "Then") + static let Kingfisher = TargetDependency.external(name: "Kingfisher") + static let Moya = TargetDependency.external(name: "Moya") + static let RxSwift = TargetDependency.external(name: "RxSwift") + static let RIBs = TargetDependency.external(name: "RIBs") +} diff --git a/Plugins/DependencyPlugin/ProjectDescriptionHelpers/Path+.swift b/Plugins/DependencyPlugin/ProjectDescriptionHelpers/Path+.swift new file mode 100644 index 0000000..65c3b68 --- /dev/null +++ b/Plugins/DependencyPlugin/ProjectDescriptionHelpers/Path+.swift @@ -0,0 +1,35 @@ +// +// Path+.swift +// EnvPlugin +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription + +public extension ProjectDescription.Path { + static func relativeToFeature(_ path: String) -> Self { + return .relativeToRoot("Projects/Features/\(path)") + } + + static func relativeToModules(_ path: String) -> Self { + return .relativeToRoot("Projects/Modules/\(path)") + } + + static var app: Self { + return .relativeToRoot("Projects/App") + } + + static var data: Self { + return .relativeToRoot("Projects/Data") + } + + static var domain: Self { + return .relativeToRoot("Projects/Domain") + } + + static var core: Self { + return .relativeToRoot("Projects/Core") + } +} + diff --git a/Plugins/EnvPlugin/Plugin.swift b/Plugins/EnvPlugin/Plugin.swift new file mode 100644 index 0000000..fe0d2a3 --- /dev/null +++ b/Plugins/EnvPlugin/Plugin.swift @@ -0,0 +1,10 @@ +// +// Plugin.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription + +let envPlugin = Plugin(name: "EnvPlugin") diff --git a/Plugins/EnvPlugin/ProjectDescriptionHelpers/Environment.swift b/Plugins/EnvPlugin/ProjectDescriptionHelpers/Environment.swift new file mode 100644 index 0000000..bd6bfb3 --- /dev/null +++ b/Plugins/EnvPlugin/ProjectDescriptionHelpers/Environment.swift @@ -0,0 +1,29 @@ +// +// Environment.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription + +public enum Environment { + public static let workspaceName = "NDGL-iOS" + public static let deploymentTarget = "17.0" + public static let bundleId = "org.yapp.NDGL" + + public struct App { + public static let displayName = "나도갈래" + public static let version = "1.0.0" + public static let buildNumber = "1" + } +} + +public extension Project { + enum Environment { + public static let organizationName = "NDGL-iOS" + public static let deploymentTarget = DeploymentTargets.iOS("17.0") + public static let bundleId = "org.yapp.NDGL" + public static let appName = "NDGL" + } +} diff --git a/Plugins/EnvPlugin/ProjectDescriptionHelpers/InfoPlist.swift b/Plugins/EnvPlugin/ProjectDescriptionHelpers/InfoPlist.swift new file mode 100644 index 0000000..73a7f17 --- /dev/null +++ b/Plugins/EnvPlugin/ProjectDescriptionHelpers/InfoPlist.swift @@ -0,0 +1,66 @@ +// +// InfoPlist.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription + +public extension Project { + static let appInfoPlist: [String: Plist.Value] = [ + "CFBundleShortVersionString": .string("1.0.0"), + "CFBundleDevelopmentRegion": .string("ko"), + "CFBundleVersion": .string("1"), + "UIUserInterfaceStyle": "Light", + "UISupportedInterfaceOrientations": ["UIInterfaceOrientationPortrait"], + "CFBundleIdentifier": .string("\(Environment.bundleId).App"), + "CFBundleDisplayName": .string("$(APP_DISPLAY_NAME)"), + "UILaunchStoryboardName": .string("LaunchScreen"), + "UIApplicationSceneManifest": .dictionary([ + "UIApplicationSupportsMultipleScenes": .boolean(false), + "UISceneConfigurations": .dictionary([ + "UIWindowSceneSessionRoleApplication": .array([ + .dictionary([ + "UISceneConfigurationName": .string("Default Configuration"), + "UISceneDelegateClassName": .string("$(PRODUCT_MODULE_NAME).SceneDelegate") + ]) + ]) + ]) + ]), + "NSAppTransportSecurity": .dictionary([ + "NSAllowsArbitraryLoads": .boolean(true) + ]), + "ITSAppUsesNonExemptEncryption": .boolean(false) + ] + + static let demoInfoPlist: [String: Plist.Value] = [ + "CFBundleShortVersionString": .string("1.0.0"), + "CFBundleDevelopmentRegion": .string("ko"), + "CFBundleVersion": .string("1"), + "UIUserInterfaceStyle": "Light", + "UISupportedInterfaceOrientations": ["UIInterfaceOrientationPortrait"], + "CFBundleIdentifier": .string("\(Environment.bundleId)"), + "CFBundleDisplayName": .string("$(APP_DISPLAY_NAME)"), + "UILaunchStoryboardName": .string("LaunchScreen"), + "UIApplicationSceneManifest": .dictionary([ + "UIApplicationSupportsMultipleScenes": .boolean(false), + "UISceneConfigurations": .dictionary([ + "UIWindowSceneSessionRoleApplication": .array([ + .dictionary([ + "UISceneConfigurationName": .string("Default Configuration"), + "UISceneDelegateClassName": .string("$(PRODUCT_MODULE_NAME).SceneDelegate") + ]) + ]) + ]) + ]), + "NSAppTransportSecurity": .dictionary([ + "NSAllowsArbitraryLoads": .boolean(true) + ]), + "ITSAppUsesNonExemptEncryption": .boolean(false) + ] + + static let framework: InfoPlist = .extendingDefault(with: [ + "CFBundlePackageType": "FMWK" + ]) +} diff --git a/Plugins/EnvPlugin/ProjectDescriptionHelpers/Settings+Extension.swift b/Plugins/EnvPlugin/ProjectDescriptionHelpers/Settings+Extension.swift new file mode 100644 index 0000000..1af74fa --- /dev/null +++ b/Plugins/EnvPlugin/ProjectDescriptionHelpers/Settings+Extension.swift @@ -0,0 +1,86 @@ +// +// Settings+Extension.swift +// EnvPlugin +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription + +public extension Settings { + /// 프레임워크용 기본 설정 + static let frameworkSettings: Settings = .settings( + base: [ + "SKIP_INSTALL": "YES", + "BUILD_LIBRARY_FOR_DISTRIBUTION": "YES", + "DEFINES_MODULE": "YES", + "ENABLE_BITCODE": "NO", + "IPHONEOS_DEPLOYMENT_TARGET": .string(Environment.deploymentTarget), + "SWIFT_VERSION": "6.0", + "CLANG_ENABLE_MODULES": "YES", + "ENABLE_USER_SCRIPT_SANDBOXING": "NO", + "ENABLE_MODULE_VERIFIER": "YES", + "MODULE_VERIFIER_SUPPORTED_LANGUAGES": "objective-c objective-c++" + ] + ) + + /// 앱용 설정 + static func appSettings() -> Settings { + let baseSettings: [String: SettingValue] = [ + "APP_NAME": .string(Environment.App.displayName), + "APP_DISPLAY_NAME": .string(Environment.App.displayName), + "CODE_SIGN_STYLE": "Manual", + "DEVELOPMENT_TEAM": SettingValue(stringLiteral: "$(DEVELOPMENT_TEAM)"), + "MARKETING_VERSION": .string(Environment.App.version), + "CURRENT_PROJECT_VERSION": .string(Environment.App.buildNumber), + "ENABLE_BITCODE": "NO", + "IPHONEOS_DEPLOYMENT_TARGET": .string(Environment.deploymentTarget), + "SWIFT_VERSION": "6.0", + "CLANG_ENABLE_MODULES": "YES", + "ENABLE_USER_SCRIPT_SANDBOXING": "NO", + "ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS": "YES" + ] + + let debugSettings: [String: SettingValue] = [ + "APP_DISPLAY_NAME": .string("\(Environment.App.displayName)-Dev"), + "PRODUCT_NAME": .string("\(Environment.App.displayName)"), + "PROVISIONING_PROFILE_SPECIFIER": SettingValue(stringLiteral: "$(APP_PROVISIONING_PROFILE)"), + "CODE_SIGN_IDENTITY": SettingValue(stringLiteral: "$(CODE_SIGN_IDENTITY)"), + "ENABLE_TESTABILITY": "YES", + "GCC_OPTIMIZATION_LEVEL": "0", + "SWIFT_OPTIMIZATION_LEVEL": "-Onone", + "DEBUG_INFORMATION_FORMAT": "dwarf", + "GCC_PREPROCESSOR_DEFINITIONS": .array(["DEBUG=1"]) + ] + + let releaseSettings: [String: SettingValue] = [ + "APP_DISPLAY_NAME": .string(Environment.App.displayName), + "PRODUCT_NAME": .string("\(Environment.App.displayName)"), + "PROVISIONING_PROFILE_SPECIFIER": SettingValue(stringLiteral: "$(APP_PROVISIONING_PROFILE)"), + "CODE_SIGN_IDENTITY": SettingValue(stringLiteral: "$(CODE_SIGN_IDENTITY)"), + "SWIFT_OPTIMIZATION_LEVEL": "-O", + "ENABLE_TESTABILITY": "NO", + "DEBUG_INFORMATION_FORMAT": "dwarf-with-dsym", + "SWIFT_COMPILATION_MODE": "wholemodule" + ] + + return .settings( + base: baseSettings, + configurations: [ + .debug(name: .debug, settings: debugSettings), + .release(name: .release, settings: releaseSettings) + ] + ) + } + + /// 데모 앱용 설정 + static let demoAppSettings: Settings = .settings( + base: [ + "CODE_SIGN_STYLE": "Automatic", + "DEVELOPMENT_TEAM": SettingValue(stringLiteral: "$(DEVELOPMENT_TEAM)"), + "IPHONEOS_DEPLOYMENT_TARGET": .string(Environment.deploymentTarget), + "SWIFT_VERSION": "6.0", + "ENABLE_TESTABILITY": "YES" + ] + ) +} diff --git a/Plugins/EnvPlugin/ProjectDescriptionHelpers/Target+Extension.swift b/Plugins/EnvPlugin/ProjectDescriptionHelpers/Target+Extension.swift new file mode 100644 index 0000000..19f7d80 --- /dev/null +++ b/Plugins/EnvPlugin/ProjectDescriptionHelpers/Target+Extension.swift @@ -0,0 +1,67 @@ +// +// Target+Extension.swift +// EnvPlugin +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription + +//MARK: - App Target 생성 +public extension Target { + static func makeAppTarget( + name: String, + deploymentTargetsVersion: String = Environment.App.version, + infoPlist: [String : Plist.Value], + entitlements: String? = nil, + scripts: [TargetScript], + dependencies: [TargetDependency], + settings: Settings + ) -> Target { + let appTaget: Target = .target( + name: name, + destinations: [.iPhone], + product: .app, + bundleId: "\(Environment.bundleId).\(name)", + deploymentTargets: .iOS(deploymentTargetsVersion), + infoPlist: .extendingDefault(with: infoPlist), + sources: ["Sources/**"], + resources: ["Resources/**"], + entitlements: entitlements.map { + .file(path: .relativeToRoot($0)) + }, + scripts: scripts, + dependencies: dependencies, + settings: settings + ) + + return appTaget + } +} + +//MARK: - Framework Target 생성 +public extension Target { + static func makeFrameworkTarget( + name: String, + infoPlist: [String : Plist.Value] = [:], + sources: SourceFilesList = ["Sources/**"], + dependencies: [TargetDependency], + scripts: [TargetScript], + isStatic: Bool = false, + hasResources: Bool = true + ) -> Target { + return .target( + name: name, + destinations: .iOS, + product: isStatic ? .staticFramework : .framework, + bundleId: "\(Environment.bundleId).\(name)", + deploymentTargets: .iOS(Environment.deploymentTarget), + infoPlist: .extendingDefault(with: infoPlist), + sources: sources, + resources: hasResources ? ["Resources/**"] : nil, + scripts: scripts, + dependencies: dependencies, + settings: .frameworkSettings + ) + } +} diff --git a/Plugins/TemplatePlugin/Plugin.swift b/Plugins/TemplatePlugin/Plugin.swift new file mode 100644 index 0000000..6812e2b --- /dev/null +++ b/Plugins/TemplatePlugin/Plugin.swift @@ -0,0 +1,11 @@ +// +// Plugin.swift +// ConfigPlugin +// +// Created by 최안용 on 1/15/26. +// + +import ProjectDescription + +let templatePlugin = Plugin(name: "TemplatePlugin") + diff --git a/Plugins/TemplatePlugin/Templates/Feature/Empty.stencil b/Plugins/TemplatePlugin/Templates/Feature/Empty.stencil new file mode 100644 index 0000000..fd5453b --- /dev/null +++ b/Plugins/TemplatePlugin/Templates/Feature/Empty.stencil @@ -0,0 +1,8 @@ +// +// Empty.swift +// Templates +// +// Created by {{ author }} on {{ current_date }} +// + +import Foundation diff --git a/Plugins/TemplatePlugin/Templates/Feature/Feature.swift b/Plugins/TemplatePlugin/Templates/Feature/Feature.swift new file mode 100644 index 0000000..4510b1e --- /dev/null +++ b/Plugins/TemplatePlugin/Templates/Feature/Feature.swift @@ -0,0 +1,50 @@ +// +// Feature.swift +// ConfigPlugin +// +// Created by 최안용 on 1/15/26. +// + +import ProjectDescription + +let nameAttribute: Template.Attribute = .required("name") +let author: Template.Attribute = .required("author") +let currentDate: Template.Attribute = .required("current_date") + +let template = Template( + description: "Creates a new feature module", + attributes: [ + nameAttribute, + author, + currentDate + ], + items: ModuleTemplate.allCases.flatMap{ $0.item } +) + +enum ModuleTemplate: CaseIterable { + case main, sources // 추후 tests/demo 등 추가 + + var path: String { + switch self { + case .main: + return .basePath + case .sources: + return .basePath + "/Sources" + } + } + + var item: [Template.Item] { + switch self { + case .main: + return [.file(path: path + "/Project.swift", templatePath: "Project.stencil")] + case .sources: + return [.file(path: path + "/Empty.swift", templatePath: "Empty.stencil")] + } + } +} + +extension String { + static var basePath: String { + return "Projects/Features/\(nameAttribute)Feature" + } +} diff --git a/Plugins/TemplatePlugin/Templates/Feature/Project.stencil b/Plugins/TemplatePlugin/Templates/Feature/Project.stencil new file mode 100644 index 0000000..5caad42 --- /dev/null +++ b/Plugins/TemplatePlugin/Templates/Feature/Project.stencil @@ -0,0 +1,25 @@ +// +// Project.swift +// ProjectDescriptionHelpers +// +// Created by {{ author }} on {{ current_date }}. +// + +import ProjectDescription +import ProjectDescriptionHelpers +import DependencyPlugin + +let project = Project.makeModule( + name: "{{name}}Feature", + targets: [ + .makeFrameworkTarget( + name: "{{name}}Feature", + dependencies: [ + .Features.baseFeatureDependency + ], + scripts: [.swiftLint], + isStatic: true, + hasResources: false + ) + ] +) diff --git a/Projects/App/Project.swift b/Projects/App/Project.swift new file mode 100644 index 0000000..eb201ca --- /dev/null +++ b/Projects/App/Project.swift @@ -0,0 +1,29 @@ +// +// Project.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription +import ProjectDescriptionHelpers +import EnvPlugin +import DependencyPlugin +import ConfigPlugin + + +let project = Project.makeModule( + name: "App", + targets: [ + .makeAppTarget( + name: "App", + infoPlist: Project.appInfoPlist, + scripts: [.swiftLint], + dependencies: [ + .data, + .Features.rootFeature + ], + settings: .appSettings() + ) + ] +) diff --git a/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon~ios-marketing.png b/Projects/App/Resources/Assets.xcassets/AppIcon.appiconset/AppIcon~ios-marketing.png new file mode 100644 index 0000000000000000000000000000000000000000..105677ad1bc8d1dbe305f2f223cd6af7175b5526 GIT binary patch literal 160963 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

|^5oAYAsY_++~fNHlCM3syY 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Projects/App/Sources/Application/AppDelegate.swift b/Projects/App/Sources/Application/AppDelegate.swift new file mode 100644 index 0000000..3f64da5 --- /dev/null +++ b/Projects/App/Sources/Application/AppDelegate.swift @@ -0,0 +1,40 @@ +// +// AppDelegate.swift +// App +// +// Created by 최안용 on 1/14/26. +// Copyright © 2026 NDGL-iOS. All rights reserved. +// + +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + return true + } + + // MARK: UISceneSession Lifecycle + + func application( + _ application: UIApplication, + configurationForConnecting connectingSceneSession: UISceneSession, + options: UIScene.ConnectionOptions + ) -> UISceneConfiguration { + return UISceneConfiguration( + name: "Default Configuration", + sessionRole: connectingSceneSession.role + ) + } + + func application( + _ application: UIApplication, + didDiscardSceneSessions sceneSessions: Set + ) { + + } +} + diff --git a/Projects/App/Sources/Application/SceneDelegate.swift b/Projects/App/Sources/Application/SceneDelegate.swift new file mode 100644 index 0000000..7d847a1 --- /dev/null +++ b/Projects/App/Sources/Application/SceneDelegate.swift @@ -0,0 +1,49 @@ +// +// SceneDelegate.swift +// App +// +// Created by 최안용 on 1/14/26. +// Copyright © 2026 NDGL-iOS. All rights reserved. +// + +import UIKit + +import Core +import RootFeature +import BaseFeatureDependency + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + var window: UIWindow? + + func scene( + _ scene: UIScene, + willConnectTo session: UISceneSession, + options connectionOptions: UIScene.ConnectionOptions + ) { + guard let windowScene = (scene as? UIWindowScene) else { return } + window = UIWindow(windowScene: windowScene) + window?.rootViewController = RootVC() + window?.makeKeyAndVisible() + } + + func sceneDidDisconnect(_ scene: UIScene) { + + } + + func sceneDidBecomeActive(_ scene: UIScene) { + + } + + func sceneWillResignActive(_ scene: UIScene) { + + } + + func sceneWillEnterForeground(_ scene: UIScene) { + + } + + func sceneDidEnterBackground(_ scene: UIScene) { + + } +} + diff --git a/Projects/Core/Project.swift b/Projects/Core/Project.swift new file mode 100644 index 0000000..12cd60a --- /dev/null +++ b/Projects/Core/Project.swift @@ -0,0 +1,24 @@ +// +// Project.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription +import ProjectDescriptionHelpers +import DependencyPlugin + +let project = Project.makeModule( + name: "Core", + targets: [ + .makeFrameworkTarget( + name: "Core", + dependencies: [ + .Modules.thirdPartyLibs + ], + scripts: [.swiftLint], + hasResources: false + ) + ] +) diff --git a/Projects/Core/Sources/Extensions/UIKit+/Empty.swift b/Projects/Core/Sources/Extensions/UIKit+/Empty.swift new file mode 100644 index 0000000..3423f2b --- /dev/null +++ b/Projects/Core/Sources/Extensions/UIKit+/Empty.swift @@ -0,0 +1,8 @@ +// +// Empty.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import UIKit diff --git a/Projects/Data/Project.swift b/Projects/Data/Project.swift new file mode 100644 index 0000000..e59eccf --- /dev/null +++ b/Projects/Data/Project.swift @@ -0,0 +1,27 @@ +// +// Project.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription +import ProjectDescriptionHelpers +import DependencyPlugin + +let project = Project.makeModule( + name: "Data", + targets: [ + .makeFrameworkTarget( + name: "Data", + dependencies: [ + .domain, + .Modules.networks + ], + scripts: [.swiftLint], + isStatic: true, + hasResources: false + ) + ] +) + diff --git a/Projects/Data/Sources/Repository/RepoEmpty.swift b/Projects/Data/Sources/Repository/RepoEmpty.swift new file mode 100644 index 0000000..17afcba --- /dev/null +++ b/Projects/Data/Sources/Repository/RepoEmpty.swift @@ -0,0 +1,8 @@ +// +// RepoEmpty.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import Foundation diff --git a/Projects/Data/Sources/Transform/TransEmpty.swift b/Projects/Data/Sources/Transform/TransEmpty.swift new file mode 100644 index 0000000..f83abee --- /dev/null +++ b/Projects/Data/Sources/Transform/TransEmpty.swift @@ -0,0 +1,8 @@ +// +// TransEmpty.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import Foundation diff --git a/Projects/Domain/Project.swift b/Projects/Domain/Project.swift new file mode 100644 index 0000000..e6bd7da --- /dev/null +++ b/Projects/Domain/Project.swift @@ -0,0 +1,24 @@ +// +// Project.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription +import ProjectDescriptionHelpers +import DependencyPlugin + +let project = Project.makeModule( + name: "Domain", + targets: [ + .makeFrameworkTarget( + name: "Domain", + dependencies: [ + .core + ], + scripts: [.swiftLint], + hasResources: false + ) + ] +) diff --git a/Projects/Domain/Sources/Interface/InterfaceEmpty.swift b/Projects/Domain/Sources/Interface/InterfaceEmpty.swift new file mode 100644 index 0000000..c2e3ea8 --- /dev/null +++ b/Projects/Domain/Sources/Interface/InterfaceEmpty.swift @@ -0,0 +1,8 @@ +// +// InterfaceEmpty.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import Foundation diff --git a/Projects/Domain/Sources/Model/ModelEmpty.swift b/Projects/Domain/Sources/Model/ModelEmpty.swift new file mode 100644 index 0000000..a2f2190 --- /dev/null +++ b/Projects/Domain/Sources/Model/ModelEmpty.swift @@ -0,0 +1,8 @@ +// +// ModelEmpty.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import Foundation diff --git a/Projects/Domain/Sources/UseCase/UsecaseEmpty.swift b/Projects/Domain/Sources/UseCase/UsecaseEmpty.swift new file mode 100644 index 0000000..42a520b --- /dev/null +++ b/Projects/Domain/Sources/UseCase/UsecaseEmpty.swift @@ -0,0 +1,8 @@ +// +// UsecaseEmpty.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import Foundation diff --git a/Projects/Features/BaseFeatureDependency/Project.swift b/Projects/Features/BaseFeatureDependency/Project.swift new file mode 100644 index 0000000..584bfc9 --- /dev/null +++ b/Projects/Features/BaseFeatureDependency/Project.swift @@ -0,0 +1,26 @@ +// +// Project.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/15/26. +// + +import ProjectDescription +import ProjectDescriptionHelpers +import DependencyPlugin + +let project = Project.makeModule( + name: "BaseFeatureDependency", + targets: [ + .makeFrameworkTarget( + name: "BaseFeatureDependency", + dependencies: [ + .domain, + .Modules.dsKit + ], + scripts: [.swiftLint], + hasResources: false + ) + ] +) + diff --git a/Projects/Features/BaseFeatureDependency/Sources/BaseEmpty.swift b/Projects/Features/BaseFeatureDependency/Sources/BaseEmpty.swift new file mode 100644 index 0000000..6d09b52 --- /dev/null +++ b/Projects/Features/BaseFeatureDependency/Sources/BaseEmpty.swift @@ -0,0 +1,8 @@ +// +// BaseEmpty.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/15/26. +// + +import Foundation diff --git a/Projects/Features/HomeFeature/Project.swift b/Projects/Features/HomeFeature/Project.swift new file mode 100644 index 0000000..4c3baad --- /dev/null +++ b/Projects/Features/HomeFeature/Project.swift @@ -0,0 +1,26 @@ +// +// Project.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/14/26. +// + +import ProjectDescription +import ProjectDescriptionHelpers +import DependencyPlugin + +let project = Project.makeModule( + name: "HomeFeature", + targets: [ + .makeFrameworkTarget( + name: "HomeFeature", + dependencies: [ + .Features.baseFeatureDependency + ], + scripts: [.swiftLint], + isStatic: true, + hasResources: false + ) + ] +) + diff --git a/Projects/Features/HomeFeature/Sources/HomeVC.swift b/Projects/Features/HomeFeature/Sources/HomeVC.swift new file mode 100644 index 0000000..c2ebe59 --- /dev/null +++ b/Projects/Features/HomeFeature/Sources/HomeVC.swift @@ -0,0 +1,37 @@ +// +// HomeVC.swift +// HomeFeature +// +// Created by 최안용 on 1/15/26. +// Copyright © 2026 NDGL-iOS. All rights reserved. +// + +import UIKit + +import Core +import Domain +import DSKit + +import BaseFeatureDependency + +// Coordinator 도입시 public 제거 후 Coordinator 클래스를 통해 접근 +public final class HomeVC: UIViewController { + + public override func viewDidLoad() { + super.viewDidLoad() + + view.backgroundColor = .red + } + + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/Projects/Features/RootFeature/Project.swift b/Projects/Features/RootFeature/Project.swift new file mode 100644 index 0000000..cc68da1 --- /dev/null +++ b/Projects/Features/RootFeature/Project.swift @@ -0,0 +1,26 @@ +// +// Project.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription +import ProjectDescriptionHelpers +import DependencyPlugin + +let project = Project.makeModule( + name: "RootFeature", + targets: [ + .makeFrameworkTarget( + name: "RootFeature", + dependencies: [ + .Features.Home.feature + ], + scripts: [.swiftLint], + isStatic: true, + hasResources: false + ) + ] +) + diff --git a/Projects/Features/RootFeature/Sources/RootVC.swift b/Projects/Features/RootFeature/Sources/RootVC.swift new file mode 100644 index 0000000..6e2290b --- /dev/null +++ b/Projects/Features/RootFeature/Sources/RootVC.swift @@ -0,0 +1,33 @@ +// +// RootVC.swift +// RootFeature +// +// Created by 최안용 on 1/15/26. +// Copyright © 2026 NDGL-iOS. All rights reserved. +// + +import UIKit + +import Core +import BaseFeatureDependency +import HomeFeature + + +public final class RootVC: UIViewController { + + public override func viewDidLoad() { + super.viewDidLoad() + + let homeNavigationController = UINavigationController() + homeNavigationController.viewControllers = [HomeVC()] + + addChild(homeNavigationController) + + view.addSubview(homeNavigationController.view) + + homeNavigationController.view.frame = view.bounds + homeNavigationController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] + + homeNavigationController.didMove(toParent: self) + } +} diff --git a/Projects/Modules/DSKit/Project.swift b/Projects/Modules/DSKit/Project.swift new file mode 100644 index 0000000..f993ce1 --- /dev/null +++ b/Projects/Modules/DSKit/Project.swift @@ -0,0 +1,24 @@ +// +// Project.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription +import ProjectDescriptionHelpers +import DependencyPlugin + +let project = Project.makeModule( + name: "DSKit", + targets: [ + .makeFrameworkTarget( + name: "DSKit", + dependencies: [ + .core + ], + scripts: [.swiftLint], + hasResources: false + ) + ] +) diff --git a/Projects/Modules/DSKit/Sources/Component/DSCEmpty.swift b/Projects/Modules/DSKit/Sources/Component/DSCEmpty.swift new file mode 100644 index 0000000..de7d7d8 --- /dev/null +++ b/Projects/Modules/DSKit/Sources/Component/DSCEmpty.swift @@ -0,0 +1,8 @@ +// +// DSCEmpty.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import Foundation diff --git a/Projects/Modules/DSKit/Sources/DSEmpty.swift b/Projects/Modules/DSKit/Sources/DSEmpty.swift new file mode 100644 index 0000000..a9b76b7 --- /dev/null +++ b/Projects/Modules/DSKit/Sources/DSEmpty.swift @@ -0,0 +1,8 @@ +// +// DSEmpty.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import Foundation diff --git a/Projects/Modules/Networks/Project.swift b/Projects/Modules/Networks/Project.swift new file mode 100644 index 0000000..2414eb4 --- /dev/null +++ b/Projects/Modules/Networks/Project.swift @@ -0,0 +1,25 @@ +// +// Project.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription +import ProjectDescriptionHelpers +import DependencyPlugin + +let project = Project.makeModule( + name: "Networks", + targets: [ + .makeFrameworkTarget( + name: "Networks", + dependencies: [ + .core + ], + scripts: [.swiftLint], + isStatic: true, + hasResources: false + ) + ] +) diff --git a/Projects/Modules/Networks/Sources/API/APIEmpty.swift b/Projects/Modules/Networks/Sources/API/APIEmpty.swift new file mode 100644 index 0000000..cc161f1 --- /dev/null +++ b/Projects/Modules/Networks/Sources/API/APIEmpty.swift @@ -0,0 +1,8 @@ +// +// APIEmpty.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import Foundation diff --git a/Projects/Modules/Networks/Sources/Base/NBaseEmpty.swift b/Projects/Modules/Networks/Sources/Base/NBaseEmpty.swift new file mode 100644 index 0000000..c0b8f52 --- /dev/null +++ b/Projects/Modules/Networks/Sources/Base/NBaseEmpty.swift @@ -0,0 +1,8 @@ +// +// NBaseEmpty.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import Foundation diff --git a/Projects/Modules/Networks/Sources/Entity/EntityEmpty.swift b/Projects/Modules/Networks/Sources/Entity/EntityEmpty.swift new file mode 100644 index 0000000..be4230d --- /dev/null +++ b/Projects/Modules/Networks/Sources/Entity/EntityEmpty.swift @@ -0,0 +1,8 @@ +// +// EntityEmpty.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import Foundation diff --git a/Projects/Modules/Networks/Sources/Service/ServiceEmpty.swift b/Projects/Modules/Networks/Sources/Service/ServiceEmpty.swift new file mode 100644 index 0000000..a45ef69 --- /dev/null +++ b/Projects/Modules/Networks/Sources/Service/ServiceEmpty.swift @@ -0,0 +1,8 @@ +// +// ServiceEmpty.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import Foundation diff --git a/Projects/Modules/ThirdPartyLibs/Project.swift b/Projects/Modules/ThirdPartyLibs/Project.swift new file mode 100644 index 0000000..411b945 --- /dev/null +++ b/Projects/Modules/ThirdPartyLibs/Project.swift @@ -0,0 +1,29 @@ +// +// Project.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription +import ProjectDescriptionHelpers +import DependencyPlugin + +let project = Project.makeModule( + name: "ThirdPartyLibs", + targets: [ + .makeFrameworkTarget( + name: "ThirdPartyLibs", + dependencies: [ + .SPM.Kingfisher, + .SPM.Moya, + .SPM.RIBs, + .SPM.RxSwift, + .SPM.SnapKit, + .SPM.Then + ], + scripts: [], + hasResources: false + ) + ] +) diff --git a/Projects/Modules/ThirdPartyLibs/Sources/Empty.swift b/Projects/Modules/ThirdPartyLibs/Sources/Empty.swift new file mode 100644 index 0000000..7063f0b --- /dev/null +++ b/Projects/Modules/ThirdPartyLibs/Sources/Empty.swift @@ -0,0 +1,8 @@ +// +// Empty.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import Foundation diff --git a/Tuist.swift b/Tuist.swift new file mode 100644 index 0000000..eefebbb --- /dev/null +++ b/Tuist.swift @@ -0,0 +1,11 @@ +import ProjectDescription + +let tuist = Tuist(project: .tuist( + plugins: [ + .local(path: .relativeToRoot("Plugins/DependencyPlugin")), + .local(path: .relativeToRoot("Plugins/ConfigPlugin")), + .local(path: .relativeToRoot("Plugins/EnvPlugin")), + .local(path: .relativeToRoot("Plugins/TemplatePlugin")) + ], + generationOptions: .options() +)) diff --git a/Tuist/Package.resolved b/Tuist/Package.resolved new file mode 100644 index 0000000..d5a5d8f --- /dev/null +++ b/Tuist/Package.resolved @@ -0,0 +1,78 @@ +{ + "originHash" : "d7518f58a4cae139e84fb7d8fe5dd3abeb7b75bb9b7260d32354d7473b9a6b84", + "pins" : [ + { + "identity" : "alamofire", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Alamofire/Alamofire.git", + "state" : { + "revision" : "7be73f6c2b5cd90e40798b06ebd5da8f9f79cf88", + "version" : "5.11.0" + } + }, + { + "identity" : "kingfisher", + "kind" : "remoteSourceControl", + "location" : "https://github.com/onevcat/Kingfisher.git", + "state" : { + "revision" : "d30a5fad881137e2267f96a8e3fc35c58999bb94", + "version" : "8.6.2" + } + }, + { + "identity" : "moya", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Moya/Moya.git", + "state" : { + "revision" : "c263811c1f3dbf002be9bd83107f7cdc38992b26", + "version" : "15.0.3" + } + }, + { + "identity" : "reactiveswift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ReactiveCocoa/ReactiveSwift.git", + "state" : { + "revision" : "c43bae3dac73fdd3cb906bd5a1914686ca71ed3c", + "version" : "6.7.0" + } + }, + { + "identity" : "ribs-ios", + "kind" : "remoteSourceControl", + "location" : "https://github.com/uber/RIBs-iOS.git", + "state" : { + "revision" : "53f7cb391d48c385730df6ce1fb95029bca9d25a", + "version" : "1.0.0" + } + }, + { + "identity" : "rxswift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ReactiveX/RxSwift.git", + "state" : { + "revision" : "5004a18539bd68905c5939aa893075f578f4f03d", + "version" : "6.9.1" + } + }, + { + "identity" : "snapkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/SnapKit/SnapKit.git", + "state" : { + "revision" : "2842e6e84e82eb9a8dac0100ca90d9444b0307f4", + "version" : "5.7.1" + } + }, + { + "identity" : "then", + "kind" : "remoteSourceControl", + "location" : "https://github.com/devxoul/Then", + "state" : { + "revision" : "e421a7b3440a271834337694e6050133a3958bc7", + "version" : "2.7.0" + } + } + ], + "version" : 3 +} diff --git a/Tuist/Package.swift b/Tuist/Package.swift new file mode 100644 index 0000000..69ab405 --- /dev/null +++ b/Tuist/Package.swift @@ -0,0 +1,26 @@ +// swift-tools-version: 6.0 +import PackageDescription + +#if TUIST + import struct ProjectDescription.PackageSettings + + let packageSettings = PackageSettings( + // Customize the product types for specific package product + // Default is .staticFramework + // productTypes: ["Alamofire": .framework,] + productTypes: [:] + ) +#endif + +let package = Package( + name: "NDGL-iOS", + dependencies: [ + .package(url: "https://github.com/Moya/Moya.git", from: "15.0.0"), + .package(url: "https://github.com/SnapKit/SnapKit.git", from: "5.0.1"), + .package(url: "https://github.com/devxoul/Then", from: "2.0.0"), + .package(url: "https://github.com/ReactiveX/RxSwift.git", from: "6.0.0"), + .package(url: "https://github.com/onevcat/Kingfisher.git", from: "8.0.0"), + .package(url: "https://github.com/uber/RIBs-iOS.git", from: "1.0.0") + ] +) + diff --git a/Tuist/ProjectDescriptionHelpers/Project+MakeModule.swift b/Tuist/ProjectDescriptionHelpers/Project+MakeModule.swift new file mode 100644 index 0000000..4221ef3 --- /dev/null +++ b/Tuist/ProjectDescriptionHelpers/Project+MakeModule.swift @@ -0,0 +1,49 @@ +// +// Project+MakeModule.swift +// 27th-App-Team-1-iOSManifests +// +// Created by 최안용 on 1/13/26. +// + +import ProjectDescription +import EnvPlugin +import ConfigPlugin + +extension Project { + public static func makeModule( + name: String, + organizationName: String = Environment.organizationName, + packages: [Package] = [], + settings: Settings? = nil, + targets: [Target] = [], + schemes: [Scheme]? = nil, + fileHeaderTemplate: FileHeaderTemplate? = nil, + additionalFiles: [FileElement] = [], + resourceSynthesizers: [ResourceSynthesizer] = .default + ) -> Project { + if let schemes = schemes { + return Project( + name: name, + organizationName: organizationName, + packages: packages, + settings: .settings(configurations: XCConfig.prod), + targets: targets, + schemes: schemes, + fileHeaderTemplate: fileHeaderTemplate, + additionalFiles: additionalFiles, + resourceSynthesizers: resourceSynthesizers + ) + } else { + return Project( + name: name, + organizationName: organizationName, + packages: packages, + settings: .settings(configurations: XCConfig.prod), + targets: targets, + fileHeaderTemplate: fileHeaderTemplate, + additionalFiles: additionalFiles, + resourceSynthesizers: resourceSynthesizers + ) + } + } +} diff --git a/Tuist/ProjectDescriptionHelpers/TargetScript+Extension.swift b/Tuist/ProjectDescriptionHelpers/TargetScript+Extension.swift new file mode 100644 index 0000000..bc0725b --- /dev/null +++ b/Tuist/ProjectDescriptionHelpers/TargetScript+Extension.swift @@ -0,0 +1,39 @@ +// +// TargetScript+Extension.swift +// ProjectDescriptionHelpers +// +// Created by 최안용 on 1/15/26. +// + +import ProjectDescription + +public extension TargetScript { + static let swiftLint = TargetScript.pre( + script: """ + export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH" + + SWIFTLINT="$(command -v swiftlint || true)" + if [ -z "$SWIFTLINT" ]; then + echo "warning: SwiftLint not installed (skipping)" + exit 0 + fi + + ROOT="$SRCROOT" + while [ "$ROOT" != "/" ] && [ ! -f "$ROOT/.swiftlint.yml" ]; do + ROOT="$(dirname "$ROOT")" + done + + if [ ! -f "$ROOT/.swiftlint.yml" ]; then + echo "warning: .swiftlint.yml not found (skipping)" + exit 0 + fi + + echo "SwiftLint: $SWIFTLINT" + echo "Config: $ROOT/.swiftlint.yml" + + "$SWIFTLINT" lint --config "$ROOT/.swiftlint.yml" + """, + name: "SwiftLint", + basedOnDependencyAnalysis: false + ) +} diff --git a/Workspace.swift b/Workspace.swift new file mode 100644 index 0000000..8f9c68f --- /dev/null +++ b/Workspace.swift @@ -0,0 +1,8 @@ +import ProjectDescription + +let workspace = Workspace( + name: "NDGL-iOS", + projects: [ + "Projects/**" + ] +) diff --git a/mise.toml b/mise.toml new file mode 100644 index 0000000..eb98974 --- /dev/null +++ b/mise.toml @@ -0,0 +1,2 @@ +[tools] +tuist = "4.118.1" diff --git a/xcconfigs/NDGL.entitlements b/xcconfigs/NDGL.entitlements new file mode 100644 index 0000000..98331b3 --- /dev/null +++ b/xcconfigs/NDGL.entitlements @@ -0,0 +1 @@ +dk From 96e36c7958b24db06dc00695a88bed3f63585d9b Mon Sep 17 00:00:00 2001 From: ChoiAnYong Date: Thu, 15 Jan 2026 17:59:01 +0900 Subject: [PATCH 03/16] =?UTF-8?q?chore:=20#1=20-=20=EC=8A=A4=ED=81=AC?= =?UTF-8?q?=EB=A6=BD=ED=8A=B8=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 27 ++++++++++++ Scripts/GenerateModule.swift | 60 ++++++++++++++++++++++++++ Scripts/Onboarding.swift | 84 ++++++++++++++++++++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 Makefile create mode 100644 Scripts/GenerateModule.swift create mode 100644 Scripts/Onboarding.swift diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e5b1ba6 --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ +generate: + tuist install + tuist generate + +clean: + rm -rf **/**/**/*.xcodeproj + rm -rf **/**/*.xcodeproj + rm -rf **/*.xcodeproj + rm -rf *.xcworkspace + +reset: + tuist clean + make clean + +regenerate: + make clean + tuist generate + +# Feature 모듈 생성 +feature: + @swift Scripts/GenerateModule.swift + tuist edit + +# 팀원이 파일을 모두 배치한 후 실행 +setup: + @chmod +x Scripts/onboarding.sh + @/bin/bash Scripts/onboarding.sh diff --git a/Scripts/GenerateModule.swift b/Scripts/GenerateModule.swift new file mode 100644 index 0000000..3ab4e6b --- /dev/null +++ b/Scripts/GenerateModule.swift @@ -0,0 +1,60 @@ +#!/user/bin/swift +import Foundation + +// 1. 유틸리티 함수: 날짜 가져오기 +func getCurrentDate() -> String { + let formatter = DateFormatter() + formatter.dateFormat = "yyyy/MM/dd" + return formatter.string(from: Date()) +} + +// 2. 입력 받기 +print("🚀 새 Feature 모듈 생성을 시작합니다.") + +print("입력: 모듈 이름 (예: Home, MyPage)", terminator: " : ") +guard let name = readLine(), !name.isEmpty else { + print("❌ 모듈 이름은 필수입니다."); exit(1) +} + +print("입력: 작성자 이름", terminator: " : ") +guard let author = readLine(), !author.isEmpty else { + print("❌ 작성자 이름은 필수입니다."); exit(1) +} + +let currentDate = getCurrentDate() + +// 3. 실행할 tuist scaffold 명령어 구성 +// 템플릿 이름이 'feature'라고 가정합니다. (Template.swift가 있는 폴더명) +let command = [ + "tuist", "scaffold", "Feature", + "--name", name, + "--author", author, + "--current_date", currentDate +] + +print("\n-------------------------------------------") +print("생성 정보 확인") +print("- 모듈명: \(name)Feature") +print("- 작성자: \(author)") +print("- 날짜: \(currentDate)") +print("-------------------------------------------\n") + +// 4. 프로세스 실행 +let process = Process() +process.executableURL = URL(fileURLWithPath: "/usr/bin/env") +process.currentDirectoryURL = URL(fileURLWithPath: FileManager.default.currentDirectoryPath) +process.arguments = command + +do { + try process.run() + process.waitUntilExit() + + if process.terminationStatus == 0 { + print("\n✅ \(name)Feature 모듈이 성공적으로 생성되었습니다!") + print("💡 'tuist generate'를 실행하여 프로젝트를 갱신하세요.") + } else { + print("\n❌ 모듈 생성 중 오류가 발생했습니다. (Status: \(process.terminationStatus))") + } +} catch { + print("❌ 명령어 실행 실패: \(error)") +} diff --git a/Scripts/Onboarding.swift b/Scripts/Onboarding.swift new file mode 100644 index 0000000..2cf0b0f --- /dev/null +++ b/Scripts/Onboarding.swift @@ -0,0 +1,84 @@ +#!/bin/bash + +# 에러 발생 시 즉시 중단 +set -e + +echo -e "🚀 Onboarding Start\n" + +# 0. 실행 경로 고정 (프로젝트 루트) +cd "$(dirname "$0")/.." + +# 1. 관리자에게 직접 전달받아야 할 필수 파일 체크 +REQUIRED_FILES=( + "fastlane/.env.default" + "xcconfigs/Debug.xcconfig" + "xcconfigs/Release.xcconfig" + "xcconfigs/NDGL.entitlements" +) + +echo "🔍 필수 설정 파일 확인 중..." +MISSING_FILES=() + +for FILE in "${REQUIRED_FILES[@]}"; do + if [ ! -f "$FILE" ]; then + MISSING_FILES+=("$FILE") + fi +done + +if [ ${#MISSING_FILES[@]} -ne 0 ]; then + echo -e "\n❌ [Error] 아래 파일이 누락되었습니다:" + for MISSING in "${MISSING_FILES[@]}"; do + echo " - $MISSING" + done + echo -e "\n👉 관리자에게 해당 파일들을 전달받아 정해진 경로에 넣어주세요." + exit 1 +fi + +echo -e "✅ 모든 필수 파일이 확인되었습니다.\n" + +# 2. .env.default 환경 변수 로드 (fastlane match 실행용) +# fastlane 폴더 안에 있는 설정을 로드합니다. +export $(grep -v '^#' fastlane/.env.default | xargs) + +# 3. mise 설치 및 활성화 +if ! command -v mise &> /dev/null; then + echo -e "[mise] Installing mise..." + brew install mise +fi +eval "$(mise activate zsh)" + +# 4. 도구 설치 (tuist 등) +if [ -f .mise.toml ]; then + echo -e "[mise] Installing tools from .mise.toml..." + mise install +fi + +# 5. rbenv 및 Ruby 설정 +if ! command -v rbenv &> /dev/null; then + brew install rbenv +fi +export PATH="$HOME/.rbenv/bin:$PATH" +eval "$(rbenv init - zsh)" + +RUBY_VERSION=$(cat .ruby-version 2>/dev/null || echo "3.2.2") +if ! rbenv versions | grep -q "$RUBY_VERSION"; then + rbenv install "$RUBY_VERSION" +fi +rbenv global "$RUBY_VERSION" +rbenv rehash + +# 6. Bundler 및 의존성 설치 +export PATH="$HOME/.rbenv/shims:$PATH" +bundle install + +# 7. Tuist 종속성 설치 및 프로젝트 생성 +echo -e "\n📦 Tuist Setting..." +tuist install +tuist generate + +# 8. Fastlane Match (인증서 설치) +echo -e "\n🔐 Installing Certificates..." +bundle exec fastlane match development --readonly +bundle exec fastlane match appstore --readonly + +echo -e "\n✅ 온보딩 완료! 이제 Xcode에서 프로젝트를 빌드할 수 있습니다." From f86c247b1fa7205fc0c28a56a144672cddd31b56 Mon Sep 17 00:00:00 2001 From: ChoiAnYong Date: Thu, 15 Jan 2026 17:59:13 +0900 Subject: [PATCH 04/16] =?UTF-8?q?chore:=20#1=20-=20fastlane=20=EC=84=B8?= =?UTF-8?q?=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile | 3 + Gemfile.lock | 316 +++++++++++++++++++++++++++++++++++++++++++++ fastlane/Appfile | 8 ++ fastlane/Fastfile | 24 ++++ fastlane/Matchfile | 13 ++ fastlane/README.md | 32 +++++ 6 files changed, 396 insertions(+) create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 fastlane/Appfile create mode 100644 fastlane/Fastfile create mode 100644 fastlane/Matchfile create mode 100644 fastlane/README.md 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..fc5caa6 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,316 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (3.0.8) + addressable (2.8.8) + public_suffix (>= 2.0.2, < 8.0) + atomos (0.1.3) + babosa (1.0.2) + base64 (0.3.0) + bigdecimal (4.0.1) + cert (1.4.4) + fastlane_core (>= 0.55.0, < 1.0.0) + spaceship (>= 0.37.0, < 1.0.0) + claide (1.0.3) + colored (1.2) + colored2 (3.1.2) + commander (4.6.0) + highline (~> 2.0.0) + credentials_manager (0.16.4) + colored + commander (>= 4.3.5) + highline (>= 1.7.1) + security + deliver (1.16.1) + credentials_manager (>= 0.16.2, < 1.0.0) + fastimage (~> 1.6) + fastlane_core (>= 0.58.0, < 1.0.0) + plist (>= 3.1.0, < 4.0.0) + spaceship (>= 0.38.5, < 1.0.0) + domain_name (0.6.20240107) + dotenv (3.2.0) + excon (0.112.0) + faraday (0.17.6) + multipart-post (>= 1.2, < 3) + faraday-cookie_jar (0.0.8) + faraday (>= 0.8.0) + http-cookie (>= 1.0.0) + faraday_middleware (0.14.0) + faraday (>= 0.7.4, < 1.0) + fastimage (1.6.8) + addressable (~> 2.3, >= 2.3.5) + fastlane (1.92.0) + addressable (~> 2.3) + cert (>= 1.4.1, < 2.0.0) + credentials_manager (>= 0.16.0, < 1.0.0) + deliver (>= 1.11.3, < 2.0.0) + fastlane_core (>= 0.44.2, < 1.0.0) + frameit (>= 2.6.2, < 3.0.0) + gym (>= 1.6.3, < 2.0.0) + krausefx-shenzhen (>= 0.14.7) + match (>= 0.6.0, < 1.0.0) + multipart-post (~> 2.0.0) + pem (>= 1.3.1, < 2.0.0) + pilot (>= 1.7.0, < 2.0.0) + plist (~> 3.1.0) + produce (>= 1.1.2, < 2.0.0) + scan (>= 0.7.1, < 1.0.0) + screengrab (>= 0.3.2, < 1.0.0) + sigh (>= 1.8.0, < 2.0.0) + slack-notifier (~> 1.3) + snapshot (>= 1.12.1, < 2.0.0) + spaceship (>= 0.27.1, < 1.0.0) + supply (>= 0.7.0, < 1.0.0) + terminal-notifier (~> 1.6.2) + terminal-table (~> 1.4.5) + xcode-install (~> 1.4.0) + xcodeproj (>= 0.20, < 2.0.0) + xcpretty (>= 0.2.1) + fastlane_core (0.59.0) + colored + commander (>= 4.4.0, <= 5.0.0) + credentials_manager (>= 0.16.2, < 1.0.0) + excon (>= 0.45.0, < 1.0) + gh_inspector (>= 1.0.1, < 2.0.0) + highline (>= 1.7.2) + json + multi_json + plist (>= 3.1.0, < 4.0.0) + rubyzip (~> 1.1.6) + terminal-table (>= 1.4.5, < 2.0.0) + frameit (2.8.0) + deliver (> 0.3) + fastimage (~> 1.6.3) + fastlane_core (>= 0.52.1, < 1.0.0) + mini_magick (~> 4.5.1) + gh_inspector (1.1.3) + google-api-client (0.9.4) + addressable (~> 2.3) + googleauth (~> 0.5) + httpclient (~> 2.7) + hurley (~> 0.1) + memoist (~> 0.11) + mime-types (>= 1.6) + representable (~> 2.3.0) + retriable (~> 2.0) + thor (~> 0.19) + googleauth (0.17.1) + faraday (>= 0.17.3, < 2.0) + jwt (>= 1.4, < 3.0) + memoist (~> 0.16) + multi_json (~> 1.11) + os (>= 0.9, < 2.0) + signet (~> 0.15) + gym (1.12.1) + fastlane_core (>= 0.57.0, < 1.0.0) + plist (>= 3.1.0, < 4.0.0) + rubyzip (>= 1.1.7) + terminal-table (>= 1.4.5, < 2.0.0) + xcpretty (>= 0.2.4, < 1.0.0) + highline (2.0.3) + http-cookie (1.1.0) + domain_name (~> 0.5) + httpclient (2.9.0) + mutex_m + hurley (0.2) + json (1.8.6) + jwt (2.10.2) + base64 + krausefx-shenzhen (0.14.11) + commander (>= 4.3, < 5.0) + dotenv (>= 0.7) + faraday (~> 0.9) + faraday_middleware (~> 0.9) + highline (>= 1.7.2) + json (~> 1.8) + net-sftp (~> 2.1.2) + plist (>= 3.1.0, < 4.0.0) + rubyzip (~> 1.1) + security (~> 0.1.3) + terminal-table (~> 1.4.5) + logger (1.7.0) + match (0.11.1) + cert (>= 1.4.4, < 2.0.0) + credentials_manager (>= 0.16.2, < 1.0.0) + fastlane_core (>= 0.58.0, < 1.0.0) + security + sigh (>= 1.12.1, < 2.0.0) + spaceship (>= 0.38.5, < 1.0.0) + memoist (0.16.2) + mime-types (3.7.0) + logger + mime-types-data (~> 3.2025, >= 3.2025.0507) + mime-types-data (3.2026.0113) + mini_magick (4.5.1) + multi_json (1.19.1) + multi_xml (0.8.1) + bigdecimal (>= 3.1, < 5) + multipart-post (2.0.0) + mutex_m (0.3.0) + nanaimo (0.4.0) + net-sftp (2.1.2) + net-ssh (>= 2.6.5) + net-ssh (7.3.0) + os (1.1.4) + pem (1.4.1) + fastlane_core (>= 0.58.0, < 1.0.0) + spaceship (>= 0.38.5, < 1.0.0) + pilot (1.12.1) + credentials_manager (>= 0.16.0) + fastlane_core (>= 0.56.0, < 1.0.0) + spaceship (>= 0.37.0, < 1.0.0) + terminal-table (>= 1.4.5, < 2.0.0) + plist (3.1.0) + produce (1.3.2) + fastlane_core (>= 0.57.2, < 1.0.0) + spaceship (>= 0.38.4, < 1.0.0) + public_suffix (7.0.2) + representable (2.3.0) + uber (~> 0.0.7) + retriable (2.1.0) + rexml (3.4.4) + rouge (3.28.0) + rubyzip (1.1.7) + scan (0.14.2) + fastlane_core (>= 0.57.0, < 1.0.0) + slack-notifier (~> 1.3) + terminal-table (>= 1.4.5, < 2.0.0) + xcpretty (>= 0.2.4, < 1.0.0) + xcpretty-travis-formatter (>= 0.0.3) + screengrab (0.5.6) + fastlane_core (>= 0.55.0, < 1.0.0) + security (0.1.5) + sigh (1.12.1) + fastlane_core (>= 0.57.2, < 1.0.0) + plist (>= 3.1.0, < 4.0.0) + spaceship (>= 0.38.4, < 1.0.0) + signet (0.21.0) + addressable (~> 2.8) + faraday (>= 0.17.5, < 3.a) + jwt (>= 1.5, < 4.0) + multi_json (~> 1.10) + slack-notifier (1.5.1) + snapshot (1.16.4) + fastimage (~> 1.6.3) + fastlane_core (>= 0.57.0, < 1.0.0) + plist (>= 3.1.0, < 4.0.0) + xcpretty (>= 0.2.4, < 1.0.0) + spaceship (0.39.0) + babosa (= 1.0.2) + colored + credentials_manager (>= 0.16.0) + faraday (~> 0.9) + faraday-cookie_jar (~> 0.0.6) + faraday_middleware (~> 0.9) + fastimage (>= 1.6) + multi_xml (~> 0.5) + plist (>= 3.1.0, < 4.0.0) + supply (0.8.0) + credentials_manager (>= 0.16.0) + fastlane_core (>= 0.52.0) + google-api-client (~> 0.9.1) + terminal-notifier (1.6.3) + terminal-table (1.4.5) + thor (0.20.3) + uber (0.0.15) + xcode-install (1.4.0) + claide (>= 0.9.1, < 1.1.0) + spaceship (>= 0.25.1, < 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-24 + ruby + +DEPENDENCIES + fastlane + +CHECKSUMS + CFPropertyList (3.0.8) sha256=2c99d0d980536d3d7ab252f7bd59ac8be50fbdd1ff487c98c949bb66bb114261 + addressable (2.8.8) sha256=7c13b8f9536cf6364c03b9d417c19986019e28f7c00ac8132da4eb0fe393b057 + atomos (0.1.3) sha256=7d43b22f2454a36bace5532d30785b06de3711399cb1c6bf932573eda536789f + babosa (1.0.2) sha256=4edc28885e0cbf3e1c258887531c274986ebc1ceaf703266276c917fc9eb2f17 + base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b + bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7 + cert (1.4.4) sha256=6dfd045c7ecd3ec8258b29cabf5901bee6161e9ce654a82f20b8e26757019b9f + claide (1.0.3) sha256=1fbc84bad66bbde2058d13875f73a25fd1d252fa1620837563cf11a1abee5a4d + colored (1.2) sha256=9d82b47ac589ce7f6cab64b1f194a2009e9fd00c326a5357321f44afab2c1d2c + colored2 (3.1.2) sha256=b13c2bd7eeae2cf7356a62501d398e72fde78780bd26aec6a979578293c28b4a + commander (4.6.0) sha256=7d1ddc3fccae60cc906b4131b916107e2ef0108858f485fdda30610c0f2913d9 + credentials_manager (0.16.4) sha256=2f15b5e380fdceb7ce415e3ce492045c04193166c3056efb9064e836e4e916b3 + deliver (1.16.1) sha256=2c915c2fe68514960ef7bc3ada80ce20d4a5652913fdc147c57a2265ea2c7190 + domain_name (0.6.20240107) sha256=5f693b2215708476517479bf2b3802e49068ad82167bcd2286f899536a17d933 + dotenv (3.2.0) sha256=e375b83121ea7ca4ce20f214740076129ab8514cd81378161f11c03853fe619d + excon (0.112.0) sha256=daf9ac3a4c2fc9aa48383a33da77ecb44fa395111e973084d5c52f6f214ae0f0 + faraday (0.17.6) sha256=a572118695fce2937e3a8bed33498ac0c25a263cdb570ea5cd2e41b36c821c34 + faraday-cookie_jar (0.0.8) sha256=0140605823f8cc63c7028fccee486aaed8e54835c360cffc1f7c8c07c4299dbb + faraday_middleware (0.14.0) sha256=4cb37ddd656b2c4de0bd684b72b08c34486f70560c31cb303cd506faef7ef2f4 + fastimage (1.6.8) sha256=3721806a38cd42762c5cd0fd123509ae9687bbf7bd3f413480d085ab1f824099 + fastlane (1.92.0) sha256=9c41c5bc1aae2f47a09e7bac4e9a0dfcca450e3812d8e39884ffd789983f9dc5 + fastlane_core (0.59.0) sha256=2572887ddf99fbe92e5e46219302a4ac35501d52e435438a59ef279f34cd7ccb + frameit (2.8.0) sha256=b2403d26f1e6f5636b89a4c29fa37d678ada2b612acb409e419fca5453dc38e0 + gh_inspector (1.1.3) sha256=04cca7171b87164e053aa43147971d3b7f500fcb58177698886b48a9fc4a1939 + google-api-client (0.9.4) sha256=55c8d701a989b38fe5ea0d16d645a4590d75f34a187211648310aa48f743d817 + googleauth (0.17.1) sha256=d4a9cbce0d6b5fbb9e6f8e42c18ab44ea38594757952d94706461dabc4c28922 + gym (1.12.1) sha256=78cfe1e4bbac3dd7c1fbba097392175b44d487769cc1dd27367be613eb5393b7 + highline (2.0.3) sha256=2ddd5c127d4692721486f91737307236fe005352d12a4202e26c48614f719479 + http-cookie (1.1.0) sha256=38a5e60d1527eebc396831b8c4b9455440509881219273a6c99943d29eadbb19 + httpclient (2.9.0) sha256=4b645958e494b2f86c2f8a2f304c959baa273a310e77a2931ddb986d83e498c8 + hurley (0.2) sha256=6f44cd30f47141ef3c5dbc799c6613e45d52ce9c1a499dc64bc165db9692ee92 + json (1.8.6) sha256=65af27ca985f70eb0d083aab0f75712c771871222af021ce533bad77bd3bb262 + jwt (2.10.2) sha256=31e1ee46f7359883d5e622446969fe9c118c3da87a0b1dca765ce269c3a0c4f4 + krausefx-shenzhen (0.14.11) sha256=075cb79cc894f8be528a3aadbcd778cca0bd510aee749884936cb58f5cf9bf7e + logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + match (0.11.1) sha256=4d767f760215c9005a33a1fa9e5dc33db730cf83510ac09b2aea2e1b1c0f5c86 + memoist (0.16.2) sha256=a52c53a3f25b5875151670b2f3fd44388633486dc0f09f9a7150ead1e3bf3c45 + mime-types (3.7.0) sha256=dcebf61c246f08e15a4de34e386ebe8233791e868564a470c3fe77c00eed5e56 + mime-types-data (3.2026.0113) sha256=8c88fa7b1af91c87098f666b7ffbd4794799a71c05765be2c1f6df337d41b04c + mini_magick (4.5.1) sha256=17352cb1fc709eacfee886af2946c87e9797c119132ba63d3040ee246899a9a8 + multi_json (1.19.1) sha256=7aefeff8f2c854bf739931a238e4aea64592845e0c0395c8a7d2eea7fdd631b7 + multi_xml (0.8.1) sha256=addba0290bac34e9088bfe73dc4878530297a82a7bbd66cb44dcd0a4b86edf5a + multipart-post (2.0.0) sha256=3dc44e50d3df3d42da2b86272c568fd7b75c928d8af3cc5f9834e2e5d9586026 + mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 + nanaimo (0.4.0) sha256=faf069551bab17f15169c1f74a1c73c220657e71b6e900919897a10d991d0723 + net-sftp (2.1.2) sha256=3e70b8130b1c86039b0847aeb088a2254df49053023546a5923e5763c923c710 + net-ssh (7.3.0) sha256=172076c4b30ce56fb25a03961b0c4da14e1246426401b0f89cba1a3b54bf3ef0 + os (1.1.4) sha256=57816d6a334e7bd6aed048f4b0308226c5fb027433b67d90a9ab435f35108d3f + pem (1.4.1) sha256=36156268d5b45198e7bca6f9f52b8f8668cfbad9e30b8e3d8d033cffda9c809e + pilot (1.12.1) sha256=00dbe1d2036f2571ca09fddae02d87ae37a368ead4fb2ac2d18641affddd72e7 + plist (3.1.0) sha256=9ae1a010cab13bb533af87d5a1aca23958e5dae8911317244248f9c65bb30866 + produce (1.3.2) sha256=44b93b7ebeb83397bf23c01763d2e2785fa55579c9c2a08fe4332a7d9b8192c0 + public_suffix (7.0.2) sha256=9114090c8e4e7135c1fd0e7acfea33afaab38101884320c65aaa0ffb8e26a857 + representable (2.3.0) sha256=93dc8bf4a4d8308e6caca4c7e48088a5bdec50e77b4e0c7d80483543166d899c + retriable (2.1.0) sha256=c1e309cd29ca451e9e8aea7685368db0da490d519ced16f79867fae12b9e4384 + rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 + rouge (3.28.0) sha256=0d6de482c7624000d92697772ab14e48dca35629f8ddf3f4b21c99183fd70e20 + rubyzip (1.1.7) sha256=24ab7c93f05eb8f6ec1c6c110f60bb5f0f2fa54b09e95eaa3b097e0fe5640133 + scan (0.14.2) sha256=b3c713f7f2ec37a7a35a501f8282635f3e2abf6f6456400247db000fbbc0bbf9 + screengrab (0.5.6) sha256=22c2fb7b5f8cdefcfc02ae367f594ff81ba862e93057ba4e9f9fc01dc0e444a7 + security (0.1.5) sha256=3a977a0eca7706e804c96db0dd9619e0a94969fe3aac9680fcfc2bf9b8a833b7 + sigh (1.12.1) sha256=fe31b7ef50ac54dd4aa4ac8146c8e223bbdc5ca8d1a6c5348482f97e130a3fca + signet (0.21.0) sha256=d617e9fbf24928280d39dcfefba9a0372d1c38187ffffd0a9283957a10a8cd5b + slack-notifier (1.5.1) sha256=062aee1c1abf78ec305568ba885b958d3a41538b86a653ab30fe0100fb8a5b75 + snapshot (1.16.4) sha256=794a735fef143b2b0a853c1327c601f06954209a0770b6b2db5293d48b30e119 + spaceship (0.39.0) sha256=36f23aa0880f40f7c7444f5d5d282224b6bfe27d1a67bf18df7029b3902cd372 + supply (0.8.0) sha256=c4e0726e5bc04c3654f0bec578f64a0cfe294fc4910345c8813bd2874c355ec7 + terminal-notifier (1.6.3) sha256=907e6fdfc6ca0cbecdd62d0b617f807e6107c6ff573bc8a86e1d1af59422a1da + terminal-table (1.4.5) sha256=bf81561a406d3389fcd08fc44447fb980f2810d1aaf99b9e06fc1916c83d1999 + thor (0.20.3) sha256=49bc217fe28f6af34c6e60b003e3405c27595a55689077d82e9e61d4d3b519fa + uber (0.0.15) sha256=01b757dc7f2d0367b32388bb10d4f93550bb688ddbdd19e895feff7eeb7979eb + xcode-install (1.4.0) sha256=a0f5dffe89d4ffe5958611c11d5731ad83b8e863fa387075f73307d749c69262 + xcodeproj (1.27.0) sha256=8cc7a73b4505c227deab044dce118ede787041c702bc47636856a2e566f854d3 + xcpretty (0.4.1) sha256=b14c50e721f6589ee3d6f5353e2c2cfcd8541fa1ea16d6c602807dd7327f3892 + xcpretty-travis-formatter (1.0.1) sha256=aacc332f17cb7b2cba222994e2adc74223db88724fe76341483ad3098e232f93 + +BUNDLED WITH + 4.0.3 diff --git a/fastlane/Appfile b/fastlane/Appfile new file mode 100644 index 0000000..42682db --- /dev/null +++ b/fastlane/Appfile @@ -0,0 +1,8 @@ +app_identifier(ENV['APP_IDENTIFIER']) # The bundle identifier of your app +apple_id(ENV['APPLE_ID']) # Your Apple Developer Portal username + +itc_team_id(ENV['FASTLANE_ITC_TEAM_ID']) # App Store Connect Team ID +team_id(ENV['TEAM_ID']) # Developer Portal 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..39fa3c5 --- /dev/null +++ b/fastlane/Fastfile @@ -0,0 +1,24 @@ +# This file contains the fastlane.tools configuration +# You can find the documentation at https://docs.fastlane.tools +# +# For a list of all available actions, check out +# +# https://docs.fastlane.tools/actions +# +# For a list of all available plugins, check out +# +# https://docs.fastlane.tools/plugins/available-plugins +# + +# Uncomment the line if you want fastlane to automatically update itself +# update_fastlane + +default_platform(:ios) + +platform :ios do + desc "Push a new release build to the App Store" + lane :release do + build_app(scheme: "NDGL-iOS-Workspace") + upload_to_app_store(skip_metadata: true, skip_screenshots: true) + end +end diff --git a/fastlane/Matchfile b/fastlane/Matchfile new file mode 100644 index 0000000..604f000 --- /dev/null +++ b/fastlane/Matchfile @@ -0,0 +1,13 @@ +git_url(ENV['REPOSITORY']) + +type "development" # The default type, can be: appstore, adhoc or development + +app_identifier(ENV['APP_IDENTIFIER']) +team_id(ENV['TEAM_ID']) +git_branch(ENV['BRANCH']) + +# app_identifier ["tools.fastlane.app", "tools.fastlane.app2"] +# username "user@fastlane.tools" # Your Apple Developer Portal username + +# For all available options run `match --help` +# Remove the # in the beginning of the line to enable the other options diff --git a/fastlane/README.md b/fastlane/README.md new file mode 100644 index 0000000..87ffeb2 --- /dev/null +++ b/fastlane/README.md @@ -0,0 +1,32 @@ +fastlane documentation +---- + +# Installation + +Make sure you have the latest version of the Xcode command line tools installed: + +```sh +xcode-select --install +``` + +For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane) + +# Available Actions + +## iOS + +### ios release + +```sh +[bundle exec] fastlane ios release +``` + +Push a new release build to the App Store + +---- + +This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run. + +More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools). + +The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools). From a845eac8327548d2fb9d6ebd5f8a7fa9358f7911 Mon Sep 17 00:00:00 2001 From: ChoiAnYong Date: Mon, 19 Jan 2026 11:59:25 +0900 Subject: [PATCH 05/16] =?UTF-8?q?chore:=20#1=20-=20fastlane=20=EB=B2=84?= =?UTF-8?q?=EC=A0=84=20=EB=AA=85=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile | 2 +- Gemfile.lock | 464 ++++++++++++++++++++++++++------------------------- 2 files changed, 240 insertions(+), 226 deletions(-) diff --git a/Gemfile b/Gemfile index 7a118b4..9a24c97 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,3 @@ source "https://rubygems.org" -gem "fastlane" +gem "fastlane", "~> 2.230" diff --git a/Gemfile.lock b/Gemfile.lock index fc5caa6..ec5668b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,220 +2,215 @@ GEM remote: https://rubygems.org/ specs: CFPropertyList (3.0.8) + abbrev (0.1.2) addressable (2.8.8) public_suffix (>= 2.0.2, < 8.0) + artifactory (3.0.17) atomos (0.1.3) - babosa (1.0.2) - base64 (0.3.0) + aws-eventstream (1.4.0) + aws-partitions (1.1206.0) + aws-sdk-core (3.241.4) + 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.121.0) + aws-sdk-core (~> 3, >= 3.241.4) + aws-sigv4 (~> 1.5) + aws-sdk-s3 (1.212.0) + aws-sdk-core (~> 3, >= 3.241.4) + 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.2.0) bigdecimal (4.0.1) - cert (1.4.4) - fastlane_core (>= 0.55.0, < 1.0.0) - spaceship (>= 0.37.0, < 1.0.0) - claide (1.0.3) + claide (1.1.0) colored (1.2) colored2 (3.1.2) commander (4.6.0) highline (~> 2.0.0) - credentials_manager (0.16.4) - colored - commander (>= 4.3.5) - highline (>= 1.7.1) - security - deliver (1.16.1) - credentials_manager (>= 0.16.2, < 1.0.0) - fastimage (~> 1.6) - fastlane_core (>= 0.58.0, < 1.0.0) - plist (>= 3.1.0, < 4.0.0) - spaceship (>= 0.38.5, < 1.0.0) + csv (3.3.5) + declarative (0.0.20) + digest-crc (0.7.0) + rake (>= 12.0.0, < 14.0.0) domain_name (0.6.20240107) - dotenv (3.2.0) + dotenv (2.8.1) + emoji_regex (3.2.3) excon (0.112.0) - faraday (0.17.6) - multipart-post (>= 1.2, < 3) + 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.8) faraday (>= 0.8.0) http-cookie (>= 1.0.0) - faraday_middleware (0.14.0) - faraday (>= 0.7.4, < 1.0) - fastimage (1.6.8) - addressable (~> 2.3, >= 2.3.5) - fastlane (1.92.0) - addressable (~> 2.3) - cert (>= 1.4.1, < 2.0.0) - credentials_manager (>= 0.16.0, < 1.0.0) - deliver (>= 1.11.3, < 2.0.0) - fastlane_core (>= 0.44.2, < 1.0.0) - frameit (>= 2.6.2, < 3.0.0) - gym (>= 1.6.3, < 2.0.0) - krausefx-shenzhen (>= 0.14.7) - match (>= 0.6.0, < 1.0.0) - multipart-post (~> 2.0.0) - pem (>= 1.3.1, < 2.0.0) - pilot (>= 1.7.0, < 2.0.0) - plist (~> 3.1.0) - produce (>= 1.1.2, < 2.0.0) - scan (>= 0.7.1, < 1.0.0) - screengrab (>= 0.3.2, < 1.0.0) - sigh (>= 1.8.0, < 2.0.0) - slack-notifier (~> 1.3) - snapshot (>= 1.12.1, < 2.0.0) - spaceship (>= 0.27.1, < 1.0.0) - supply (>= 0.7.0, < 1.0.0) - terminal-notifier (~> 1.6.2) - terminal-table (~> 1.4.5) - xcode-install (~> 1.4.0) - xcodeproj (>= 0.20, < 2.0.0) - xcpretty (>= 0.2.1) - fastlane_core (0.59.0) - colored - commander (>= 4.4.0, <= 5.0.0) - credentials_manager (>= 0.16.2, < 1.0.0) - excon (>= 0.45.0, < 1.0) - gh_inspector (>= 1.0.1, < 2.0.0) - highline (>= 1.7.2) - json - multi_json + 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.2.0) + 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.231.0) + CFPropertyList (>= 2.3, < 4.0.0) + abbrev (~> 0.1.2) + addressable (>= 2.8, < 3.0.0) + artifactory (~> 3.0) + aws-sdk-s3 (~> 1.0) + babosa (>= 1.0.3, < 2.0.0) + base64 (~> 0.2.0) + bundler (>= 1.17.3, < 5.0.0) + colored (~> 1.2) + commander (~> 4.6) + csv (~> 3.3) + 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) + logger (>= 1.6, < 2.0) + mini_magick (>= 4.9.4, < 5.0.0) + multipart-post (>= 2.0.0, < 3.0.0) + mutex_m (~> 0.3.0) + naturally (~> 2.2) + nkf (~> 0.2.0) + optparse (>= 0.1.1, < 1.0.0) plist (>= 3.1.0, < 4.0.0) - rubyzip (~> 1.1.6) - terminal-table (>= 1.4.5, < 2.0.0) - frameit (2.8.0) - deliver (> 0.3) - fastimage (~> 1.6.3) - fastlane_core (>= 0.52.1, < 1.0.0) - mini_magick (~> 4.5.1) + 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-api-client (0.9.4) - addressable (~> 2.3) - googleauth (~> 0.5) - httpclient (~> 2.7) - hurley (~> 0.1) - memoist (~> 0.11) - mime-types (>= 1.6) - representable (~> 2.3.0) - retriable (~> 2.0) - thor (~> 0.19) - googleauth (0.17.1) - faraday (>= 0.17.3, < 2.0) + 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) - memoist (~> 0.16) multi_json (~> 1.11) os (>= 0.9, < 2.0) - signet (~> 0.15) - gym (1.12.1) - fastlane_core (>= 0.57.0, < 1.0.0) - plist (>= 3.1.0, < 4.0.0) - rubyzip (>= 1.1.7) - terminal-table (>= 1.4.5, < 2.0.0) - xcpretty (>= 0.2.4, < 1.0.0) + signet (>= 0.16, < 2.a) highline (2.0.3) - http-cookie (1.1.0) + http-cookie (1.0.8) domain_name (~> 0.5) httpclient (2.9.0) mutex_m - hurley (0.2) - json (1.8.6) + jmespath (1.6.2) + json (2.18.0) jwt (2.10.2) base64 - krausefx-shenzhen (0.14.11) - commander (>= 4.3, < 5.0) - dotenv (>= 0.7) - faraday (~> 0.9) - faraday_middleware (~> 0.9) - highline (>= 1.7.2) - json (~> 1.8) - net-sftp (~> 2.1.2) - plist (>= 3.1.0, < 4.0.0) - rubyzip (~> 1.1) - security (~> 0.1.3) - terminal-table (~> 1.4.5) logger (1.7.0) - match (0.11.1) - cert (>= 1.4.4, < 2.0.0) - credentials_manager (>= 0.16.2, < 1.0.0) - fastlane_core (>= 0.58.0, < 1.0.0) - security - sigh (>= 1.12.1, < 2.0.0) - spaceship (>= 0.38.5, < 1.0.0) - memoist (0.16.2) - mime-types (3.7.0) - logger - mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2026.0113) - mini_magick (4.5.1) + mini_magick (4.13.2) + mini_mime (1.1.5) multi_json (1.19.1) - multi_xml (0.8.1) - bigdecimal (>= 3.1, < 5) - multipart-post (2.0.0) + multipart-post (2.4.1) mutex_m (0.3.0) nanaimo (0.4.0) - net-sftp (2.1.2) - net-ssh (>= 2.6.5) - net-ssh (7.3.0) + naturally (2.3.0) + nkf (0.2.0) + optparse (0.8.1) os (1.1.4) - pem (1.4.1) - fastlane_core (>= 0.58.0, < 1.0.0) - spaceship (>= 0.38.5, < 1.0.0) - pilot (1.12.1) - credentials_manager (>= 0.16.0) - fastlane_core (>= 0.56.0, < 1.0.0) - spaceship (>= 0.37.0, < 1.0.0) - terminal-table (>= 1.4.5, < 2.0.0) - plist (3.1.0) - produce (1.3.2) - fastlane_core (>= 0.57.2, < 1.0.0) - spaceship (>= 0.38.4, < 1.0.0) + plist (3.7.2) public_suffix (7.0.2) - representable (2.3.0) - uber (~> 0.0.7) - retriable (2.1.0) + rake (13.3.1) + 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) - rubyzip (1.1.7) - scan (0.14.2) - fastlane_core (>= 0.57.0, < 1.0.0) - slack-notifier (~> 1.3) - terminal-table (>= 1.4.5, < 2.0.0) - xcpretty (>= 0.2.4, < 1.0.0) - xcpretty-travis-formatter (>= 0.0.3) - screengrab (0.5.6) - fastlane_core (>= 0.55.0, < 1.0.0) + ruby2_keywords (0.0.5) + rubyzip (2.4.1) security (0.1.5) - sigh (1.12.1) - fastlane_core (>= 0.57.2, < 1.0.0) - plist (>= 3.1.0, < 4.0.0) - spaceship (>= 0.38.4, < 1.0.0) signet (0.21.0) addressable (~> 2.8) faraday (>= 0.17.5, < 3.a) jwt (>= 1.5, < 4.0) multi_json (~> 1.10) - slack-notifier (1.5.1) - snapshot (1.16.4) - fastimage (~> 1.6.3) - fastlane_core (>= 0.57.0, < 1.0.0) - plist (>= 3.1.0, < 4.0.0) - xcpretty (>= 0.2.4, < 1.0.0) - spaceship (0.39.0) - babosa (= 1.0.2) - colored - credentials_manager (>= 0.16.0) - faraday (~> 0.9) - faraday-cookie_jar (~> 0.0.6) - faraday_middleware (~> 0.9) - fastimage (>= 1.6) - multi_xml (~> 0.5) - plist (>= 3.1.0, < 4.0.0) - supply (0.8.0) - credentials_manager (>= 0.16.0) - fastlane_core (>= 0.52.0) - google-api-client (~> 0.9.1) - terminal-notifier (1.6.3) - terminal-table (1.4.5) - thor (0.20.3) - uber (0.0.15) - xcode-install (1.4.0) - claide (>= 0.9.1, < 1.1.0) - spaceship (>= 0.25.1, < 1.0.0) + 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) @@ -233,81 +228,100 @@ PLATFORMS ruby DEPENDENCIES - fastlane + fastlane (~> 2.230) CHECKSUMS CFPropertyList (3.0.8) sha256=2c99d0d980536d3d7ab252f7bd59ac8be50fbdd1ff487c98c949bb66bb114261 + abbrev (0.1.2) sha256=ad1b4eaaaed4cb722d5684d63949e4bde1d34f2a95e20db93aecfe7cbac74242 addressable (2.8.8) sha256=7c13b8f9536cf6364c03b9d417c19986019e28f7c00ac8132da4eb0fe393b057 + artifactory (3.0.17) sha256=3023d5c964c31674090d655a516f38ca75665c15084140c08b7f2841131af263 atomos (0.1.3) sha256=7d43b22f2454a36bace5532d30785b06de3711399cb1c6bf932573eda536789f - babosa (1.0.2) sha256=4edc28885e0cbf3e1c258887531c274986ebc1ceaf703266276c917fc9eb2f17 - base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b + aws-eventstream (1.4.0) sha256=116bf85c436200d1060811e6f5d2d40c88f65448f2125bc77ffce5121e6e183b + aws-partitions (1.1206.0) sha256=9016c2d4f5d633aeb95d4cfeb936b5de3d752a5dbae4838bc19d53f202749301 + aws-sdk-core (3.241.4) sha256=a42ccba8c24ea9800e7b6c40aa201c967458f7c460044a6eebf64fbf1226e4fd + aws-sdk-kms (1.121.0) sha256=d563c1cfb4b5754efbc671216c8eca875338748adad0f42518c28dfa0a2d01e0 + aws-sdk-s3 (1.212.0) sha256=1e8ec4eee6914818dc79840e05c04fba9e61e8aa4822eef283fe593b93397c19 + aws-sigv4 (1.12.1) sha256=6973ff95cb0fd0dc58ba26e90e9510a2219525d07620c8babeb70ef831826c00 + babosa (1.0.4) sha256=18dea450f595462ed7cb80595abd76b2e535db8c91b350f6c4b3d73986c5bc99 + base64 (0.2.0) sha256=0f25e9b21a02a0cc0cea8ef92b2041035d39350946e8789c562b2d1a3da01507 bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7 - cert (1.4.4) sha256=6dfd045c7ecd3ec8258b29cabf5901bee6161e9ce654a82f20b8e26757019b9f - claide (1.0.3) sha256=1fbc84bad66bbde2058d13875f73a25fd1d252fa1620837563cf11a1abee5a4d + claide (1.1.0) sha256=6d3c5c089dde904d96aa30e73306d0d4bd444b1accb9b3125ce14a3c0183f82e colored (1.2) sha256=9d82b47ac589ce7f6cab64b1f194a2009e9fd00c326a5357321f44afab2c1d2c colored2 (3.1.2) sha256=b13c2bd7eeae2cf7356a62501d398e72fde78780bd26aec6a979578293c28b4a commander (4.6.0) sha256=7d1ddc3fccae60cc906b4131b916107e2ef0108858f485fdda30610c0f2913d9 - credentials_manager (0.16.4) sha256=2f15b5e380fdceb7ce415e3ce492045c04193166c3056efb9064e836e4e916b3 - deliver (1.16.1) sha256=2c915c2fe68514960ef7bc3ada80ce20d4a5652913fdc147c57a2265ea2c7190 + csv (3.3.5) sha256=6e5134ac3383ef728b7f02725d9872934f523cb40b961479f69cf3afa6c8e73f + declarative (0.0.20) sha256=8021dd6cb17ab2b61233c56903d3f5a259c5cf43c80ff332d447d395b17d9ff9 + digest-crc (0.7.0) sha256=64adc23a26a241044cbe6732477ca1b3c281d79e2240bcff275a37a5a0d78c07 domain_name (0.6.20240107) sha256=5f693b2215708476517479bf2b3802e49068ad82167bcd2286f899536a17d933 - dotenv (3.2.0) sha256=e375b83121ea7ca4ce20f214740076129ab8514cd81378161f11c03853fe619d + dotenv (2.8.1) sha256=c5944793349ae03c432e1780a2ca929d60b88c7d14d52d630db0508c3a8a17d8 + emoji_regex (3.2.3) sha256=ecd8be856b7691406c6bf3bb3a5e55d6ed683ffab98b4aa531bb90e1ddcc564b excon (0.112.0) sha256=daf9ac3a4c2fc9aa48383a33da77ecb44fa395111e973084d5c52f6f214ae0f0 - faraday (0.17.6) sha256=a572118695fce2937e3a8bed33498ac0c25a263cdb570ea5cd2e41b36c821c34 + faraday (1.10.4) sha256=a384c541cde688d68bf85055723aecb4100c3fa41b53beb2011b245960ab2f19 faraday-cookie_jar (0.0.8) sha256=0140605823f8cc63c7028fccee486aaed8e54835c360cffc1f7c8c07c4299dbb - faraday_middleware (0.14.0) sha256=4cb37ddd656b2c4de0bd684b72b08c34486f70560c31cb303cd506faef7ef2f4 - fastimage (1.6.8) sha256=3721806a38cd42762c5cd0fd123509ae9687bbf7bd3f413480d085ab1f824099 - fastlane (1.92.0) sha256=9c41c5bc1aae2f47a09e7bac4e9a0dfcca450e3812d8e39884ffd789983f9dc5 - fastlane_core (0.59.0) sha256=2572887ddf99fbe92e5e46219302a4ac35501d52e435438a59ef279f34cd7ccb - frameit (2.8.0) sha256=b2403d26f1e6f5636b89a4c29fa37d678ada2b612acb409e419fca5453dc38e0 + faraday-em_http (1.0.0) sha256=7a3d4c7079789121054f57e08cd4ef7e40ad1549b63101f38c7093a9d6c59689 + faraday-em_synchrony (1.0.1) sha256=bf3ce45dcf543088d319ab051f80985ea6d294930635b7a0b966563179f81750 + faraday-excon (1.1.0) sha256=b055c842376734d7f74350fe8611542ae2000c5387348d9ba9708109d6e40940 + faraday-httpclient (1.0.1) sha256=4c8ff1f0973ff835be8d043ef16aaf54f47f25b7578f6d916deee8399a04d33b + faraday-multipart (1.2.0) sha256=7d89a949693714176f612323ca13746a2ded204031a6ba528adee788694ef757 + faraday-net_http (1.0.2) sha256=63992efea42c925a20818cf3c0830947948541fdcf345842755510d266e4c682 + faraday-net_http_persistent (1.2.0) sha256=0b0cbc8f03dab943c3e1cc58d8b7beb142d9df068b39c718cd83e39260348335 + faraday-patron (1.0.0) sha256=dc2cd7b340bb3cc8e36bcb9e6e7eff43d134b6d526d5f3429c7a7680ddd38fa7 + faraday-rack (1.0.0) sha256=ef60ec969a2bb95b8dbf24400155aee64a00fc8ba6c6a4d3968562bcc92328c0 + faraday-retry (1.0.3) sha256=add154f4f399243cbe070806ed41b96906942e7f5259bb1fe6daf2ec8f497194 + faraday_middleware (1.2.1) sha256=d45b78c8ee864c4783fbc276f845243d4a7918a67301c052647bacabec0529e9 + fastimage (2.4.0) sha256=5fce375e27d3bdbb46c18dbca6ba9af29d3304801ae1eb995771c4796c5ac7e8 + fastlane (2.231.0) sha256=69523272108f1212d0c6a6e6985f22341d0828c11ebc62a7a55a08f595d7721c + fastlane-sirp (1.0.0) sha256=66478f25bcd039ec02ccf65625373fca29646fa73d655eb533c915f106c5e641 gh_inspector (1.1.3) sha256=04cca7171b87164e053aa43147971d3b7f500fcb58177698886b48a9fc4a1939 - google-api-client (0.9.4) sha256=55c8d701a989b38fe5ea0d16d645a4590d75f34a187211648310aa48f743d817 - googleauth (0.17.1) sha256=d4a9cbce0d6b5fbb9e6f8e42c18ab44ea38594757952d94706461dabc4c28922 - gym (1.12.1) sha256=78cfe1e4bbac3dd7c1fbba097392175b44d487769cc1dd27367be613eb5393b7 + google-apis-androidpublisher_v3 (0.54.0) sha256=8970a72839c8dfa87d290bdf935c641bf18cbd4323bf71d182adc04c0108d210 + google-apis-core (0.11.3) sha256=43217013b129d7d52c31ebf94146646c55f463ed25e68ad7523fb644d5a9cc97 + google-apis-iamcredentials_v1 (0.17.0) sha256=9a6525cfd6ef1c9a355f593bfef11bd0fb30e1d785ef9e5c9da51c3817a0517b + google-apis-playcustomapp_v1 (0.13.0) sha256=959e51f90454b51adc72e5c322b4b4a573f869520c4d7c7c20efd1d262e48fd6 + google-apis-storage_v1 (0.31.0) sha256=03e8cc775e12403e5878899dd4bfb90957e7281e894937f03641c3857262db8f + google-cloud-core (1.8.0) sha256=e572edcbf189cfcab16590628a516cec3f4f63454b730e59f0b36575120281cf + google-cloud-env (1.6.0) sha256=6179acb946975892c7908748df5722a4ebadfc8cf5bb7b0d8d933ca67183fa15 + google-cloud-errors (1.5.0) sha256=b56be28b8c10628125214dde571b925cfcebdbc58619e598250c37a2114f7b4b + google-cloud-storage (1.47.0) sha256=b543d01a9c83495149accd2da77b2cf365d5b6aac21bf3fa21e69dfc8f1eeb76 + googleauth (1.8.1) sha256=814adadaaa1221dce72a67131e3ecbd6d23491a161ec84fb15fd353b87d8c9e7 highline (2.0.3) sha256=2ddd5c127d4692721486f91737307236fe005352d12a4202e26c48614f719479 - http-cookie (1.1.0) sha256=38a5e60d1527eebc396831b8c4b9455440509881219273a6c99943d29eadbb19 + http-cookie (1.0.8) sha256=b14fe0445cf24bf9ae098633e9b8d42e4c07c3c1f700672b09fbfe32ffd41aa6 httpclient (2.9.0) sha256=4b645958e494b2f86c2f8a2f304c959baa273a310e77a2931ddb986d83e498c8 - hurley (0.2) sha256=6f44cd30f47141ef3c5dbc799c6613e45d52ce9c1a499dc64bc165db9692ee92 - json (1.8.6) sha256=65af27ca985f70eb0d083aab0f75712c771871222af021ce533bad77bd3bb262 + jmespath (1.6.2) sha256=238d774a58723d6c090494c8879b5e9918c19485f7e840f2c1c7532cf84ebcb1 + json (2.18.0) sha256=b10506aee4183f5cf49e0efc48073d7b75843ce3782c68dbeb763351c08fd505 jwt (2.10.2) sha256=31e1ee46f7359883d5e622446969fe9c118c3da87a0b1dca765ce269c3a0c4f4 - krausefx-shenzhen (0.14.11) sha256=075cb79cc894f8be528a3aadbcd778cca0bd510aee749884936cb58f5cf9bf7e logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 - match (0.11.1) sha256=4d767f760215c9005a33a1fa9e5dc33db730cf83510ac09b2aea2e1b1c0f5c86 - memoist (0.16.2) sha256=a52c53a3f25b5875151670b2f3fd44388633486dc0f09f9a7150ead1e3bf3c45 - mime-types (3.7.0) sha256=dcebf61c246f08e15a4de34e386ebe8233791e868564a470c3fe77c00eed5e56 - mime-types-data (3.2026.0113) sha256=8c88fa7b1af91c87098f666b7ffbd4794799a71c05765be2c1f6df337d41b04c - mini_magick (4.5.1) sha256=17352cb1fc709eacfee886af2946c87e9797c119132ba63d3040ee246899a9a8 + mini_magick (4.13.2) sha256=71d6258e0e8a3d04a9a0a09784d5d857b403a198a51dd4f882510435eb95ddd9 + mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef multi_json (1.19.1) sha256=7aefeff8f2c854bf739931a238e4aea64592845e0c0395c8a7d2eea7fdd631b7 - multi_xml (0.8.1) sha256=addba0290bac34e9088bfe73dc4878530297a82a7bbd66cb44dcd0a4b86edf5a - multipart-post (2.0.0) sha256=3dc44e50d3df3d42da2b86272c568fd7b75c928d8af3cc5f9834e2e5d9586026 + multipart-post (2.4.1) sha256=9872d03a8e552020ca096adadbf5e3cb1cd1cdd6acd3c161136b8a5737cdb4a8 mutex_m (0.3.0) sha256=cfcb04ac16b69c4813777022fdceda24e9f798e48092a2b817eb4c0a782b0751 nanaimo (0.4.0) sha256=faf069551bab17f15169c1f74a1c73c220657e71b6e900919897a10d991d0723 - net-sftp (2.1.2) sha256=3e70b8130b1c86039b0847aeb088a2254df49053023546a5923e5763c923c710 - net-ssh (7.3.0) sha256=172076c4b30ce56fb25a03961b0c4da14e1246426401b0f89cba1a3b54bf3ef0 + naturally (2.3.0) sha256=459923cf76c2e6613048301742363200c3c7e4904c324097d54a67401e179e01 + nkf (0.2.0) sha256=fbc151bda025451f627fafdfcb3f4f13d0b22ae11f58c6d3a2939c76c5f5f126 + optparse (0.8.1) sha256=42bea10d53907ccff4f080a69991441d611fbf8733b60ed1ce9ee365ce03bd1a os (1.1.4) sha256=57816d6a334e7bd6aed048f4b0308226c5fb027433b67d90a9ab435f35108d3f - pem (1.4.1) sha256=36156268d5b45198e7bca6f9f52b8f8668cfbad9e30b8e3d8d033cffda9c809e - pilot (1.12.1) sha256=00dbe1d2036f2571ca09fddae02d87ae37a368ead4fb2ac2d18641affddd72e7 - plist (3.1.0) sha256=9ae1a010cab13bb533af87d5a1aca23958e5dae8911317244248f9c65bb30866 - produce (1.3.2) sha256=44b93b7ebeb83397bf23c01763d2e2785fa55579c9c2a08fe4332a7d9b8192c0 + plist (3.7.2) sha256=d37a4527cc1116064393df4b40e1dbbc94c65fa9ca2eec52edf9a13616718a42 public_suffix (7.0.2) sha256=9114090c8e4e7135c1fd0e7acfea33afaab38101884320c65aaa0ffb8e26a857 - representable (2.3.0) sha256=93dc8bf4a4d8308e6caca4c7e48088a5bdec50e77b4e0c7d80483543166d899c - retriable (2.1.0) sha256=c1e309cd29ca451e9e8aea7685368db0da490d519ced16f79867fae12b9e4384 + rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c + representable (3.2.0) sha256=cc29bf7eebc31653586849371a43ffe36c60b54b0a6365b5f7d95ec34d1ebace + retriable (3.1.2) sha256=0a5a5d0ca4ba61a76fb31a17ab8f7f80281beb040c329d34dfc137a1398688e0 rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 rouge (3.28.0) sha256=0d6de482c7624000d92697772ab14e48dca35629f8ddf3f4b21c99183fd70e20 - rubyzip (1.1.7) sha256=24ab7c93f05eb8f6ec1c6c110f60bb5f0f2fa54b09e95eaa3b097e0fe5640133 - scan (0.14.2) sha256=b3c713f7f2ec37a7a35a501f8282635f3e2abf6f6456400247db000fbbc0bbf9 - screengrab (0.5.6) sha256=22c2fb7b5f8cdefcfc02ae367f594ff81ba862e93057ba4e9f9fc01dc0e444a7 + ruby2_keywords (0.0.5) sha256=ffd13740c573b7301cf7a2e61fc857b2a8e3d3aff32545d6f8300d8bae10e3ef + rubyzip (2.4.1) sha256=8577c88edc1fde8935eb91064c5cb1aef9ad5494b940cf19c775ee833e075615 security (0.1.5) sha256=3a977a0eca7706e804c96db0dd9619e0a94969fe3aac9680fcfc2bf9b8a833b7 - sigh (1.12.1) sha256=fe31b7ef50ac54dd4aa4ac8146c8e223bbdc5ca8d1a6c5348482f97e130a3fca signet (0.21.0) sha256=d617e9fbf24928280d39dcfefba9a0372d1c38187ffffd0a9283957a10a8cd5b - slack-notifier (1.5.1) sha256=062aee1c1abf78ec305568ba885b958d3a41538b86a653ab30fe0100fb8a5b75 - snapshot (1.16.4) sha256=794a735fef143b2b0a853c1327c601f06954209a0770b6b2db5293d48b30e119 - spaceship (0.39.0) sha256=36f23aa0880f40f7c7444f5d5d282224b6bfe27d1a67bf18df7029b3902cd372 - supply (0.8.0) sha256=c4e0726e5bc04c3654f0bec578f64a0cfe294fc4910345c8813bd2874c355ec7 - terminal-notifier (1.6.3) sha256=907e6fdfc6ca0cbecdd62d0b617f807e6107c6ff573bc8a86e1d1af59422a1da - terminal-table (1.4.5) sha256=bf81561a406d3389fcd08fc44447fb980f2810d1aaf99b9e06fc1916c83d1999 - thor (0.20.3) sha256=49bc217fe28f6af34c6e60b003e3405c27595a55689077d82e9e61d4d3b519fa - uber (0.0.15) sha256=01b757dc7f2d0367b32388bb10d4f93550bb688ddbdd19e895feff7eeb7979eb - xcode-install (1.4.0) sha256=a0f5dffe89d4ffe5958611c11d5731ad83b8e863fa387075f73307d749c69262 + simctl (1.6.10) sha256=b99077f4d13ad81eace9f86bf5ba4df1b0b893a4d1b368bd3ed59b5b27f9236b + sysrandom (1.0.5) sha256=5ac1ac3c2ec64ef76ac91018059f541b7e8f437fbda1ccddb4f2c56a9ccf1e75 + terminal-notifier (2.0.0) sha256=7a0d2b2212ab9835c07f4b2e22a94cff64149dba1eed203c04835f7991078cea + terminal-table (3.0.2) sha256=f951b6af5f3e00203fb290a669e0a85c5dd5b051b3b023392ccfd67ba5abae91 + trailblazer-option (0.1.2) sha256=20e4f12ea4e1f718c8007e7944ca21a329eee4eed9e0fa5dde6e8ad8ac4344a3 + tty-cursor (0.7.1) sha256=79534185e6a777888d88628b14b6a1fdf5154a603f285f80b1753e1908e0bf48 + tty-screen (0.8.2) sha256=c090652115beae764336c28802d633f204fb84da93c6a968aa5d8e319e819b50 + tty-spinner (0.9.3) sha256=0e036f047b4ffb61f2aa45f5a770ec00b4d04130531558a94bfc5b192b570542 + uber (0.1.0) sha256=5beeb407ff807b5db994f82fa9ee07cfceaa561dad8af20be880bc67eba935dc + unicode-display_width (2.6.0) sha256=12279874bba6d5e4d2728cef814b19197dbb10d7a7837a869bab65da943b7f5a + word_wrap (1.0.0) sha256=f556d4224c812e371000f12a6ee8102e0daa724a314c3f246afaad76d82accc7 xcodeproj (1.27.0) sha256=8cc7a73b4505c227deab044dce118ede787041c702bc47636856a2e566f854d3 xcpretty (0.4.1) sha256=b14c50e721f6589ee3d6f5353e2c2cfcd8541fa1ea16d6c602807dd7327f3892 xcpretty-travis-formatter (1.0.1) sha256=aacc332f17cb7b2cba222994e2adc74223db88724fe76341483ad3098e232f93 From 182ccd1dbe3f892e2bdefffebec21e665fe83535 Mon Sep 17 00:00:00 2001 From: ChoiAnYong Date: Mon, 19 Jan 2026 11:59:56 +0900 Subject: [PATCH 06/16] =?UTF-8?q?chore:=20#1=20-=20=EB=94=94=EB=B0=94?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4=20=EC=B6=94=EA=B0=80=20=EB=AA=85=EB=A0=B9?= =?UTF-8?q?=EC=96=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 4 ++++ Projects/Modules/DSKit/Project.swift | 2 +- fastlane/Fastfile | 12 ++++++++++ fastlane/README.md | 35 ++++++++++++---------------- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index e5b1ba6..254bead 100644 --- a/Makefile +++ b/Makefile @@ -25,3 +25,7 @@ feature: setup: @chmod +x Scripts/onboarding.sh @/bin/bash Scripts/onboarding.sh + +# 디바이스 추가 +device: + bundle exec fastlane register_new_device diff --git a/Projects/Modules/DSKit/Project.swift b/Projects/Modules/DSKit/Project.swift index f993ce1..8aae264 100644 --- a/Projects/Modules/DSKit/Project.swift +++ b/Projects/Modules/DSKit/Project.swift @@ -15,7 +15,7 @@ let project = Project.makeModule( .makeFrameworkTarget( name: "DSKit", dependencies: [ - .core + .core ], scripts: [.swiftLint], hasResources: false diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 39fa3c5..d39e4e8 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -22,3 +22,15 @@ platform :ios do upload_to_app_store(skip_metadata: true, skip_screenshots: true) end end + +### Device Management + + desc "Register Devices" + lane :register_new_device do |options| + device_name = prompt(text: "Enter the device name: ") + device_udid = prompt(text: "Enter the device UDID: ") + device_hash = {} + device_hash[device_name] = device_udid + register_devices(devices: device_hash) + match(type: "development", force_for_new_devices: true) + end \ No newline at end of file diff --git a/fastlane/README.md b/fastlane/README.md index 87ffeb2..0b13b9b 100644 --- a/fastlane/README.md +++ b/fastlane/README.md @@ -1,32 +1,27 @@ fastlane documentation ----- - +================ # Installation - -Make sure you have the latest version of the Xcode command line tools installed: - -```sh -xcode-select --install ``` - -For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane) - +sudo gem install fastlane +``` # Available Actions +### register_new_device +``` +fastlane register_new_device +``` +Register Devices -## iOS +---- +## iOS ### ios release - -```sh -[bundle exec] fastlane ios release ``` - +fastlane ios release +``` Push a new release build to the App Store ---- -This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run. - -More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools). - -The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools). +This README.md is auto-generated and will be re-generated every time to run [fastlane](https://fastlane.tools). +More information about fastlane can be found on [https://fastlane.tools](https://fastlane.tools). +The documentation of fastlane can be found on [GitHub](https://github.com/fastlane/fastlane/tree/master/fastlane). \ No newline at end of file From d8c16a77068ca1966de09d9e73fe94288509b54f Mon Sep 17 00:00:00 2001 From: ChoiAnYong Date: Mon, 19 Jan 2026 13:50:31 +0900 Subject: [PATCH 07/16] =?UTF-8?q?chore:=20#1=20-=20private=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=9E=90=EB=8F=99=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .ruby-version | 1 + Makefile | 4 +- Projects/Modules/DSKit/Project.swift | 2 +- Scripts/Onboarding.sh | 136 +++++++++++++++++++++++++++ Scripts/Onboarding.swift | 84 ----------------- 5 files changed, 140 insertions(+), 87 deletions(-) create mode 100644 .ruby-version create mode 100755 Scripts/Onboarding.sh delete mode 100644 Scripts/Onboarding.swift diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..be94e6f --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +3.2.2 diff --git a/Makefile b/Makefile index 254bead..4baa2bf 100644 --- a/Makefile +++ b/Makefile @@ -23,8 +23,8 @@ feature: # 팀원이 파일을 모두 배치한 후 실행 setup: - @chmod +x Scripts/onboarding.sh - @/bin/bash Scripts/onboarding.sh + @chmod +x Scripts/Onboarding.sh + @/bin/bash Scripts/Onboarding.sh # 디바이스 추가 device: diff --git a/Projects/Modules/DSKit/Project.swift b/Projects/Modules/DSKit/Project.swift index 8aae264..f993ce1 100644 --- a/Projects/Modules/DSKit/Project.swift +++ b/Projects/Modules/DSKit/Project.swift @@ -15,7 +15,7 @@ let project = Project.makeModule( .makeFrameworkTarget( name: "DSKit", dependencies: [ - .core + .core ], scripts: [.swiftLint], hasResources: false diff --git a/Scripts/Onboarding.sh b/Scripts/Onboarding.sh new file mode 100755 index 0000000..72049fd --- /dev/null +++ b/Scripts/Onboarding.sh @@ -0,0 +1,136 @@ +#!/bin/bash + +# 에러 발생 시 즉시 중단 +set -e + +echo -e "🚀 Onboarding Start\n" + +# 0. 실행 경로 고정 (프로젝트 루트) +cd "$(dirname "$0")/.." + +# --------------------------------------------------------- +# 1. PrivateFile 레포지토리를 통한 보안 파일 자동 세팅 +# --------------------------------------------------------- +PRIVATE_REPO_URL="https://github.com/ChoiAnYong/fastlane-match.git" +TEMP_DIR="temp_private_configs" + +echo "🔐 보안 설정 파일을 가져오는 중 (PrivateFile 레포지토리)..." + +# 기존에 폴더가 있다면 삭제 후 새로 클론 +rm -rf "$TEMP_DIR" +git clone "$PRIVATE_REPO_URL" "$TEMP_DIR" + +# 레포지토리 내 PrivateFile 폴더가 있는지 확인 후 경로 설정 +SOURCE_PATH="$TEMP_DIR/PrivateFile" +if [ ! -d "$SOURCE_PATH" ]; then + SOURCE_PATH="$TEMP_DIR" +fi + +echo "📁 설정 파일 배치 중..." +mkdir -p xcconfigs +mkdir -p fastlane + +cp "$SOURCE_PATH/Debug.xcconfig" xcconfigs/ 2>/dev/null || echo "⚠️ Debug.xcconfig missing" +cp "$SOURCE_PATH/Release.xcconfig" xcconfigs/ 2>/dev/null || echo "⚠️ Release.xcconfig missing" +cp "$SOURCE_PATH/.env.default" fastlane/ 2>/dev/null || echo "⚠️ .env.default missing" +# entitlements 파일이 있다면 추가 (필요시 주석 해제) +# cp "$SOURCE_PATH/NDGL.entitlements" xcconfigs/ 2>/dev/null || echo "⚠️ NDGL.entitlements missing" + +# 임시 폴더 삭제 +rm -rf "$TEMP_DIR" + +# --------------------------------------------------------- +# 2. 필수 설정 파일 검증 +# --------------------------------------------------------- +REQUIRED_FILES=( + "fastlane/.env.default" + "xcconfigs/Debug.xcconfig" + "xcconfigs/Release.xcconfig" +) + +echo "🔍 가져온 파일 검증 중..." +MISSING_FILES=() + +for FILE in "${REQUIRED_FILES[@]}"; do + if [ ! -f "$FILE" ]; then + MISSING_FILES+=("$FILE") + fi +done + +if [ ${#MISSING_FILES[@]} -ne 0 ]; then + echo -e "\n❌ [Error] 아래 필수 파일이 누락되었습니다:" + for MISSING in "${MISSING_FILES[@]}"; do + echo " - $MISSING" + done + exit 1 +fi + +echo -e "✅ 모든 설정 파일이 정상적으로 배치되었습니다.\n" + +# --------------------------------------------------------- +# 3. 환경 변수 로드 +# --------------------------------------------------------- +export $(grep -v '^#' fastlane/.env.default | xargs) + +# --------------------------------------------------------- +# 4. mise 설치 및 활성화 (Bash 버전) +# --------------------------------------------------------- +if ! command -v mise &> /dev/null; then + echo -e "[mise] Installing mise..." + brew install mise +fi +# 중요: zsh가 아닌 bash로 활성화 +eval "$(mise activate bash)" + +# 5. 도구 설치 +if [ -f .mise.toml ]; then + echo -e "[mise] Installing tools from .mise.toml..." + mise install +fi + +# --------------------------------------------------------- +# 6. rbenv 및 Ruby 설정 (Bash 버전) +# --------------------------------------------------------- +if ! command -v rbenv &> /dev/null; then + echo -e "[rbenv] Installing rbenv..." + brew install rbenv +fi +export PATH="$HOME/.rbenv/bin:$PATH" +# 중요: bash로 초기화 +eval "$(rbenv init - bash)" + +RUBY_VERSION=$(cat .ruby-version 2>/dev/null || echo "3.2.2") +if ! rbenv versions | grep -q "$RUBY_VERSION"; then + echo -e "[rbenv] Installing Ruby $RUBY_VERSION..." + rbenv install "$RUBY_VERSION" +fi +rbenv local "$RUBY_VERSION" +rbenv rehash + +# --------------------------------------------------------- +# 7. Bundler 및 의존성 설치 +# --------------------------------------------------------- +echo -e "[Bundler] Installing gems..." +gem install bundler --no-document +bundle install + +# --------------------------------------------------------- +# 8. Tuist 설정 +# --------------------------------------------------------- +echo -e "\n📦 Tuist Setting..." +if [ -f Makefile ]; then + # Makefile의 generate 타겟 실행 (tuist install/generate 포함 권장) + make generate +else + tuist install + tuist generate +fi + +# --------------------------------------------------------- +# 9. Fastlane Match +# --------------------------------------------------------- +echo -e "\n🔐 Installing Certificates..." +bundle exec fastlane match development --readonly +bundle exec fastlane match appstore --readonly + +echo -e "\n✅ 온보딩 완료! 이제 Xcode에서 프로젝트를 빌드할 수 있습니다." diff --git a/Scripts/Onboarding.swift b/Scripts/Onboarding.swift deleted file mode 100644 index 2cf0b0f..0000000 --- a/Scripts/Onboarding.swift +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/bash - -# 에러 발생 시 즉시 중단 -set -e - -echo -e "🚀 Onboarding Start\n" - -# 0. 실행 경로 고정 (프로젝트 루트) -cd "$(dirname "$0")/.." - -# 1. 관리자에게 직접 전달받아야 할 필수 파일 체크 -REQUIRED_FILES=( - "fastlane/.env.default" - "xcconfigs/Debug.xcconfig" - "xcconfigs/Release.xcconfig" - "xcconfigs/NDGL.entitlements" -) - -echo "🔍 필수 설정 파일 확인 중..." -MISSING_FILES=() - -for FILE in "${REQUIRED_FILES[@]}"; do - if [ ! -f "$FILE" ]; then - MISSING_FILES+=("$FILE") - fi -done - -if [ ${#MISSING_FILES[@]} -ne 0 ]; then - echo -e "\n❌ [Error] 아래 파일이 누락되었습니다:" - for MISSING in "${MISSING_FILES[@]}"; do - echo " - $MISSING" - done - echo -e "\n👉 관리자에게 해당 파일들을 전달받아 정해진 경로에 넣어주세요." - exit 1 -fi - -echo -e "✅ 모든 필수 파일이 확인되었습니다.\n" - -# 2. .env.default 환경 변수 로드 (fastlane match 실행용) -# fastlane 폴더 안에 있는 설정을 로드합니다. -export $(grep -v '^#' fastlane/.env.default | xargs) - -# 3. mise 설치 및 활성화 -if ! command -v mise &> /dev/null; then - echo -e "[mise] Installing mise..." - brew install mise -fi -eval "$(mise activate zsh)" - -# 4. 도구 설치 (tuist 등) -if [ -f .mise.toml ]; then - echo -e "[mise] Installing tools from .mise.toml..." - mise install -fi - -# 5. rbenv 및 Ruby 설정 -if ! command -v rbenv &> /dev/null; then - brew install rbenv -fi -export PATH="$HOME/.rbenv/bin:$PATH" -eval "$(rbenv init - zsh)" - -RUBY_VERSION=$(cat .ruby-version 2>/dev/null || echo "3.2.2") -if ! rbenv versions | grep -q "$RUBY_VERSION"; then - rbenv install "$RUBY_VERSION" -fi -rbenv global "$RUBY_VERSION" -rbenv rehash - -# 6. Bundler 및 의존성 설치 -export PATH="$HOME/.rbenv/shims:$PATH" -bundle install - -# 7. Tuist 종속성 설치 및 프로젝트 생성 -echo -e "\n📦 Tuist Setting..." -tuist install -tuist generate - -# 8. Fastlane Match (인증서 설치) -echo -e "\n🔐 Installing Certificates..." -bundle exec fastlane match development --readonly -bundle exec fastlane match appstore --readonly - -echo -e "\n✅ 온보딩 완료! 이제 Xcode에서 프로젝트를 빌드할 수 있습니다." From b7f97e644d2bd83dee8eb3f2b692208bb3e51ffb Mon Sep 17 00:00:00 2001 From: ChoiAnYong Date: Mon, 19 Jan 2026 15:29:14 +0900 Subject: [PATCH 08/16] =?UTF-8?q?chore:=20#1=20-=20CI=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile | 3 ++ Scripts/Onboarding.sh | 10 +++++- fastlane/Fastfile | 77 ++++++++++++++++++++++++++++++++++++------- fastlane/Pluginfile | 5 +++ 4 files changed, 82 insertions(+), 13 deletions(-) create mode 100644 fastlane/Pluginfile diff --git a/Gemfile b/Gemfile index 9a24c97..f80c3f6 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,6 @@ source "https://rubygems.org" gem "fastlane", "~> 2.230" + +plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') +eval_gemfile(plugins_path) if File.exist?(plugins_path) diff --git a/Scripts/Onboarding.sh b/Scripts/Onboarding.sh index 72049fd..5c9ccff 100755 --- a/Scripts/Onboarding.sh +++ b/Scripts/Onboarding.sh @@ -11,7 +11,15 @@ cd "$(dirname "$0")/.." # --------------------------------------------------------- # 1. PrivateFile 레포지토리를 통한 보안 파일 자동 세팅 # --------------------------------------------------------- -PRIVATE_REPO_URL="https://github.com/ChoiAnYong/fastlane-match.git" + +# CI 환경인지 로컬 환경인지 확인하여 URL 분기 +if [ "$CI" = "true" ]; then + echo "🌐 CI 환경 감지: SSH 주소를 사용합니다." + PRIVATE_REPO_URL="git@github.com:ChoiAnYong/fastlane-match.git" +else + echo "💻 로컬 환경 감지: HTTPS 주소를 사용합니다." + PRIVATE_REPO_URL="https://github.com/ChoiAnYong/fastlane-match.git" +fi TEMP_DIR="temp_private_configs" echo "🔐 보안 설정 파일을 가져오는 중 (PrivateFile 레포지토리)..." diff --git a/fastlane/Fastfile b/fastlane/Fastfile index d39e4e8..b3c3247 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -16,21 +16,74 @@ default_platform(:ios) platform :ios do + + # --------------------------------------------------------- + # 1. CI 전용 레인 (PR 시 빌드 확인용) + # --------------------------------------------------------- + desc "Check Build (CI)" + lane :ci_check do + begin + xcodebuild( + workspace: "NDGL-iOS.xcworkspace", + scheme: "App", + configuration: "Debug", + sdk: "iphonesimulator", + xcargs: "CODE_SIGNING_ALLOWED=NO" + ) + # 성공 시 CI용 메시지 전송 + send_discord_message(message: "CI 빌드 체크 성공! 코드가 안전합니다. ✅", success: true, type: "CI") + rescue => exception + # 실패 시 에러 내용과 함께 알림 + send_discord_message(message: "CI 빌드 실패: #{exception}", success: false, type: "CI") + raise exception + end + end + + # --------------------------------------------------------- + # 2. 배포 전용 레인 (App Store / TestFlight 업로드) + # --------------------------------------------------------- desc "Push a new release build to the App Store" lane :release do - build_app(scheme: "NDGL-iOS-Workspace") - upload_to_app_store(skip_metadata: true, skip_screenshots: true) + begin + # match(type: "appstore", readonly: true) # CI 환경이라면 추가 권장 + build_app(scheme: "NDGL-iOS-Workspace") + upload_to_app_store(skip_metadata: true, skip_screenshots: true) + + send_discord_message(message: "TestFlight 업로드 완료! 테스터 알림이 전송되었습니다. 🚀", success: true, type: "배포") + rescue => exception + send_discord_message(message: "배포 실패 에러: #{exception}", success: false, type: "배포") + raise exception + end + end + + # --------------------------------------------------------- + # 3. 기기 관리 (로컬용) + # --------------------------------------------------------- + desc "Register Devices" + lane :register_new_device do |options| + device_name = prompt(text: "Enter the device name: ") + device_udid = prompt(text: "Enter the device UDID: ") + register_devices(devices: { device_name => device_udid }) + match(type: "development", force_for_new_devices: true) end end -### Device Management +# --------------------------------------------------------- +# 🔔 Discord 메시지 전송 함수 (공통) +# --------------------------------------------------------- +def send_discord_message(message:, success:, type: "CI") + project_path = "NDGL-iOS.xcodeproj" + + version = get_version_number(xcodeproj: project_path) + build_number = get_build_number(xcodeproj: project_path) + + emoji = success ? "✅" : "🚨" + title_text = success ? "#{type} 성공" : "#{type} 실패" - desc "Register Devices" - lane :register_new_device do |options| - device_name = prompt(text: "Enter the device name: ") - device_udid = prompt(text: "Enter the device UDID: ") - device_hash = {} - device_hash[device_name] = device_udid - register_devices(devices: device_hash) - match(type: "development", force_for_new_devices: true) - end \ No newline at end of file + discord_notifier( + webhook_url: ENV["DISCORD_URL"], + title: "#{emoji} #{title_text} — v#{version} (#{build_number})", + description: message, + success: success + ) +end \ No newline at end of file diff --git a/fastlane/Pluginfile b/fastlane/Pluginfile new file mode 100644 index 0000000..7ef2b02 --- /dev/null +++ b/fastlane/Pluginfile @@ -0,0 +1,5 @@ +# Autogenerated by fastlane +# +# Ensure this file is checked in to source control! + +gem 'fastlane-plugin-discord_notifier' From d9539b6c7a0613ec99df798e04469839d5382c9d Mon Sep 17 00:00:00 2001 From: AnYong <112386037+ChoiAnYong@users.noreply.github.com> Date: Mon, 19 Jan 2026 15:30:25 +0900 Subject: [PATCH 09/16] =?UTF-8?q?chore:=20#1=20-=20CI=20workflows=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/CI.yml diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml new file mode 100644 index 0000000..7937545 --- /dev/null +++ b/.github/workflows/CI.yml @@ -0,0 +1,36 @@ +# This workflow will build a Swift project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-swift + +name: CI + +on: + pull_request: + branches: [ "develop" ] + +jobs: + build: + runs-on: macos-14 + + steps: + - name: 1️⃣ Checkout Project + uses: actions/checkout@v4 + + - name: 2️⃣ SSH key 설치 + uses: shimataro/ssh-key-action@v2 + with: + key: ${{ secrets.SSH_KEY }} + known_hosts: ${{ secrets.KNOWN_HOSTS }}` + + - name: 3️⃣ Run Onboarding via Makefile + env: + CI: true # 스크립트가 SSH 주소를 선택하게 함 + MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} + run: | + make setup + + - name: 4️⃣ Build Check & Discord Notification + env: + DISCORD_URL: ${{ secrets.DISCORD_URL }} + MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} + run: | + bundle exec fastlane ci_check From cd229da2094c2d61e7745391fecfbb30e93f9bb0 Mon Sep 17 00:00:00 2001 From: ChoiAnYong Date: Mon, 19 Jan 2026 15:50:19 +0900 Subject: [PATCH 10/16] =?UTF-8?q?chore:#1=20-=20Onboarding=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Scripts/Onboarding.sh | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Scripts/Onboarding.sh b/Scripts/Onboarding.sh index 5c9ccff..672fc56 100755 --- a/Scripts/Onboarding.sh +++ b/Scripts/Onboarding.sh @@ -12,14 +12,7 @@ cd "$(dirname "$0")/.." # 1. PrivateFile 레포지토리를 통한 보안 파일 자동 세팅 # --------------------------------------------------------- -# CI 환경인지 로컬 환경인지 확인하여 URL 분기 -if [ "$CI" = "true" ]; then - echo "🌐 CI 환경 감지: SSH 주소를 사용합니다." - PRIVATE_REPO_URL="git@github.com:ChoiAnYong/fastlane-match.git" -else - echo "💻 로컬 환경 감지: HTTPS 주소를 사용합니다." - PRIVATE_REPO_URL="https://github.com/ChoiAnYong/fastlane-match.git" -fi +PRIVATE_REPO_URL="https://github.com/ChoiAnYong/fastlane-match.git" TEMP_DIR="temp_private_configs" echo "🔐 보안 설정 파일을 가져오는 중 (PrivateFile 레포지토리)..." From c4a1708525ba2ec56a1e0dfc8c0bbd7512adf0ae Mon Sep 17 00:00:00 2001 From: AnYong <112386037+ChoiAnYong@users.noreply.github.com> Date: Mon, 19 Jan 2026 15:51:07 +0900 Subject: [PATCH 11/16] =?UTF-8?q?chore:=20#1=20-=20CI=20workflows=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 7937545..5481153 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -19,16 +19,35 @@ jobs: uses: shimataro/ssh-key-action@v2 with: key: ${{ secrets.SSH_KEY }} - known_hosts: ${{ secrets.KNOWN_HOSTS }}` + known_hosts: ${{ secrets.KNOWN_HOSTS }} - - name: 3️⃣ Run Onboarding via Makefile - env: - CI: true # 스크립트가 SSH 주소를 선택하게 함 - MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} + - name: 3️⃣ 보안 설정 파일 가져오기 run: | - make setup + git clone $CONFIG_REPO $TEMP_DIR + + SOURCE_PATH="$TEMP_DIR/PrivateFile" - - name: 4️⃣ Build Check & Discord Notification + cp SOURCE_PATH/Debug.xcconfig xcconfigs/ + cp SOURCE_PATH/Release.xcconfig xcconfigs/ + cp SOURCE_PATH/.env.default fastlane/ + rm -rf temp_private_configs + env: + CONFIG_REPO: ${{ secrets.PRIVATE_REPO }} + TEMP_DIR: "temp_private_configs" + + # mise-action을 써서 tuist, ruby 등 도구 설치 (PATH 자동 등록) + - name: 4️⃣ mise를 통한 도구 설치 (Tuist/Ruby) + uses: jdx/mise-action@v2 + with: + install: true + + - name: 5️⃣ 의존성 설치 및 프로젝트 생성 + run: | + bundle install + tuist install + tuist generate --no-open + + - name: 6️⃣ Build Check & Discord Notification env: DISCORD_URL: ${{ secrets.DISCORD_URL }} MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }} From 707679dd324df6e6af3db7f6a72d1e2576cd7bb6 Mon Sep 17 00:00:00 2001 From: AnYong <112386037+ChoiAnYong@users.noreply.github.com> Date: Mon, 19 Jan 2026 15:55:34 +0900 Subject: [PATCH 12/16] =?UTF-8?q?chore:=20#1=20-=20CI=20workflows=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 5481153..996875e 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -22,18 +22,21 @@ jobs: known_hosts: ${{ secrets.KNOWN_HOSTS }} - name: 3️⃣ 보안 설정 파일 가져오기 + env: + CONFIG_REPO: ${{ secrets.PRIVATE_REPO }} + TEMP_DIR: "temp_private_configs" run: | git clone $CONFIG_REPO $TEMP_DIR SOURCE_PATH="$TEMP_DIR/PrivateFile" - - cp SOURCE_PATH/Debug.xcconfig xcconfigs/ - cp SOURCE_PATH/Release.xcconfig xcconfigs/ - cp SOURCE_PATH/.env.default fastlane/ - rm -rf temp_private_configs - env: - CONFIG_REPO: ${{ secrets.PRIVATE_REPO }} - TEMP_DIR: "temp_private_configs" + + echo "📁 파일 복사 중: $SOURCE_PATH" + cp "$SOURCE_PATH/Debug.xcconfig" xcconfigs/ + cp "$SOURCE_PATH/Release.xcconfig" xcconfigs/ + cp "$SOURCE_PATH/.env.default" fastlane/ + + rm -rf "$TEMP_DIR" + echo "✅ 보안 파일 배치 완료" # mise-action을 써서 tuist, ruby 등 도구 설치 (PATH 자동 등록) - name: 4️⃣ mise를 통한 도구 설치 (Tuist/Ruby) From 72eb6d5fa9ee6793bc77a4a407a40e862b623a4e Mon Sep 17 00:00:00 2001 From: AnYong <112386037+ChoiAnYong@users.noreply.github.com> Date: Mon, 19 Jan 2026 15:58:03 +0900 Subject: [PATCH 13/16] =?UTF-8?q?chore:=20#1=20-=20=EC=9A=B4=EC=98=81?= =?UTF-8?q?=EC=B2=B4=EC=A0=9C=20=EB=B2=84=EC=A0=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 996875e..d02df72 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -9,7 +9,7 @@ on: jobs: build: - runs-on: macos-14 + runs-on: macos-15 steps: - name: 1️⃣ Checkout Project From 9d257df13f3b8930d315167e0a59035eec880ae9 Mon Sep 17 00:00:00 2001 From: ChoiAnYong Date: Mon, 19 Jan 2026 16:12:55 +0900 Subject: [PATCH 14/16] =?UTF-8?q?chore:=20#1=20-=20fastfile=20discord=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=ED=95=A8=EC=88=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fastlane/Fastfile | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index b3c3247..174fe1b 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -68,12 +68,20 @@ platform :ios do end end +# --------------------------------------------------------- +# 🔔 Discord 메시지 전송 함수 (공통) +# --------------------------------------------------------- # --------------------------------------------------------- # 🔔 Discord 메시지 전송 함수 (공통) # --------------------------------------------------------- def send_discord_message(message:, success:, type: "CI") - project_path = "NDGL-iOS.xcodeproj" + project_path = "Projects/App/App.xcodeproj" + # 프로젝트 파일이 존재하는지 확인 (에러 방지용 로그) + unless File.exist?(project_path) + UI.important("⚠️ 프로젝트 파일을 찾을 수 없습니다: #{project_path}") + end + version = get_version_number(xcodeproj: project_path) build_number = get_build_number(xcodeproj: project_path) From 6c7d3f06ac7df317a98d6cca13adffc1545589a8 Mon Sep 17 00:00:00 2001 From: ChoiAnYong Date: Mon, 19 Jan 2026 16:27:53 +0900 Subject: [PATCH 15/16] =?UTF-8?q?chore:=20#1=20-=20fastfile=20discord=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=ED=95=A8=EC=88=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fastlane/Fastfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 174fe1b..8b0f4f7 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -31,7 +31,7 @@ platform :ios do xcargs: "CODE_SIGNING_ALLOWED=NO" ) # 성공 시 CI용 메시지 전송 - send_discord_message(message: "CI 빌드 체크 성공! 코드가 안전합니다. ✅", success: true, type: "CI") + send_discord_message(message: "CI 빌드 체크 성공!", success: true, type: "CI") rescue => exception # 실패 시 에러 내용과 함께 알림 send_discord_message(message: "CI 빌드 실패: #{exception}", success: false, type: "CI") @@ -75,7 +75,7 @@ end # 🔔 Discord 메시지 전송 함수 (공통) # --------------------------------------------------------- def send_discord_message(message:, success:, type: "CI") - project_path = "Projects/App/App.xcodeproj" + project_path = "./Projects/App/App.xcodeproj" # 프로젝트 파일이 존재하는지 확인 (에러 방지용 로그) unless File.exist?(project_path) From a7f1771b8ab3b19fc46e3d3f7e10b087981ad9c8 Mon Sep 17 00:00:00 2001 From: ChoiAnYong Date: Mon, 19 Jan 2026 16:44:33 +0900 Subject: [PATCH 16/16] =?UTF-8?q?chore:=20#1=20-=20fastfile=20discord=20?= =?UTF-8?q?=EC=95=8C=EB=A6=BC=20=ED=95=A8=EC=88=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fastlane/Fastfile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 8b0f4f7..ee0346e 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -76,11 +76,6 @@ end # --------------------------------------------------------- def send_discord_message(message:, success:, type: "CI") project_path = "./Projects/App/App.xcodeproj" - - # 프로젝트 파일이 존재하는지 확인 (에러 방지용 로그) - unless File.exist?(project_path) - UI.important("⚠️ 프로젝트 파일을 찾을 수 없습니다: #{project_path}") - end version = get_version_number(xcodeproj: project_path) build_number = get_build_number(xcodeproj: project_path)