timsquad 3.3.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/README.ko.md +288 -0
  2. package/README.md +158 -151
  3. package/dist/commands/compile.d.ts +3 -0
  4. package/dist/commands/compile.d.ts.map +1 -0
  5. package/dist/commands/compile.js +170 -0
  6. package/dist/commands/compile.js.map +1 -0
  7. package/dist/commands/daemon.d.ts.map +1 -1
  8. package/dist/commands/daemon.js +95 -5
  9. package/dist/commands/daemon.js.map +1 -1
  10. package/dist/commands/full.js +1 -0
  11. package/dist/commands/full.js.map +1 -1
  12. package/dist/commands/git/pr.js +6 -5
  13. package/dist/commands/git/pr.js.map +1 -1
  14. package/dist/commands/git/release.js +2 -7
  15. package/dist/commands/git/release.js.map +1 -1
  16. package/dist/commands/improve.js +2 -2
  17. package/dist/commands/improve.js.map +1 -1
  18. package/dist/commands/init.d.ts.map +1 -1
  19. package/dist/commands/init.js +12 -3
  20. package/dist/commands/init.js.map +1 -1
  21. package/dist/commands/log.d.ts.map +1 -1
  22. package/dist/commands/log.js +2 -2
  23. package/dist/commands/log.js.map +1 -1
  24. package/dist/commands/metrics.d.ts.map +1 -1
  25. package/dist/commands/metrics.js +6 -2
  26. package/dist/commands/metrics.js.map +1 -1
  27. package/dist/commands/retro.js +8 -8
  28. package/dist/commands/retro.js.map +1 -1
  29. package/dist/commands/session.js +3 -3
  30. package/dist/commands/session.js.map +1 -1
  31. package/dist/commands/skills.d.ts +12 -0
  32. package/dist/commands/skills.d.ts.map +1 -0
  33. package/dist/commands/skills.js +228 -0
  34. package/dist/commands/skills.js.map +1 -0
  35. package/dist/commands/status.js +1 -1
  36. package/dist/commands/status.js.map +1 -1
  37. package/dist/commands/upgrade.d.ts.map +1 -1
  38. package/dist/commands/upgrade.js +23 -1
  39. package/dist/commands/upgrade.js.map +1 -1
  40. package/dist/daemon/entry.js +3 -3
  41. package/dist/daemon/entry.js.map +1 -1
  42. package/dist/daemon/event-queue.d.ts.map +1 -1
  43. package/dist/daemon/event-queue.js +2 -2
  44. package/dist/daemon/event-queue.js.map +1 -1
  45. package/dist/daemon/index.d.ts +4 -2
  46. package/dist/daemon/index.d.ts.map +1 -1
  47. package/dist/daemon/index.js +214 -52
  48. package/dist/daemon/index.js.map +1 -1
  49. package/dist/daemon/jsonl-watcher.d.ts +1 -0
  50. package/dist/daemon/jsonl-watcher.d.ts.map +1 -1
  51. package/dist/daemon/jsonl-watcher.js.map +1 -1
  52. package/dist/daemon/meta-cache.d.ts +1 -0
  53. package/dist/daemon/meta-cache.d.ts.map +1 -1
  54. package/dist/daemon/meta-cache.js +9 -0
  55. package/dist/daemon/meta-cache.js.map +1 -1
  56. package/dist/daemon/session-notes.d.ts +33 -0
  57. package/dist/daemon/session-notes.d.ts.map +1 -0
  58. package/dist/daemon/session-notes.js +74 -0
  59. package/dist/daemon/session-notes.js.map +1 -0
  60. package/dist/daemon/session-state.d.ts +27 -0
  61. package/dist/daemon/session-state.d.ts.map +1 -0
  62. package/dist/daemon/session-state.js +165 -0
  63. package/dist/daemon/session-state.js.map +1 -0
  64. package/dist/daemon/shutdown.d.ts.map +1 -1
  65. package/dist/daemon/shutdown.js +9 -1
  66. package/dist/daemon/shutdown.js.map +1 -1
  67. package/dist/index.js +4 -0
  68. package/dist/index.js.map +1 -1
  69. package/dist/lib/agent-generator.d.ts +4 -0
  70. package/dist/lib/agent-generator.d.ts.map +1 -1
  71. package/dist/lib/agent-generator.js +52 -3
  72. package/dist/lib/agent-generator.js.map +1 -1
  73. package/dist/lib/compile-rules.d.ts +66 -0
  74. package/dist/lib/compile-rules.d.ts.map +1 -0
  75. package/dist/lib/compile-rules.js +114 -0
  76. package/dist/lib/compile-rules.js.map +1 -0
  77. package/dist/lib/compiler.d.ts +105 -0
  78. package/dist/lib/compiler.d.ts.map +1 -0
  79. package/dist/lib/compiler.js +368 -0
  80. package/dist/lib/compiler.js.map +1 -0
  81. package/dist/lib/config.d.ts +1 -0
  82. package/dist/lib/config.d.ts.map +1 -1
  83. package/dist/lib/config.js +8 -1
  84. package/dist/lib/config.js.map +1 -1
  85. package/dist/lib/project.d.ts.map +1 -1
  86. package/dist/lib/project.js +8 -3
  87. package/dist/lib/project.js.map +1 -1
  88. package/dist/lib/skill-generator.d.ts.map +1 -1
  89. package/dist/lib/skill-generator.js +22 -1
  90. package/dist/lib/skill-generator.js.map +1 -1
  91. package/dist/lib/template.d.ts.map +1 -1
  92. package/dist/lib/template.js +6 -0
  93. package/dist/lib/template.js.map +1 -1
  94. package/dist/types/config.d.ts +1 -0
  95. package/dist/types/config.d.ts.map +1 -1
  96. package/dist/types/config.js +12 -1
  97. package/dist/types/config.js.map +1 -1
  98. package/dist/types/project.d.ts +1 -1
  99. package/dist/types/project.d.ts.map +1 -1
  100. package/dist/types/project.js +2 -0
  101. package/dist/types/project.js.map +1 -1
  102. package/package.json +4 -4
  103. package/templates/base/agents/base/tsq-architect.md +2 -2
  104. package/templates/base/agents/overlays/domain/mobile/_common.md +13 -0
  105. package/templates/base/knowledge/checklists/plan-quality.md +31 -0
  106. package/templates/base/knowledge/checklists/stability-verification.md +14 -0
  107. package/templates/base/skills/controller/SKILL.md +111 -0
  108. package/templates/base/skills/controller/references/README.md +35 -0
  109. package/templates/base/skills/controller/rules/README.md +18 -0
  110. package/templates/base/skills/mobile/dart/SKILL.md +69 -0
  111. package/templates/base/skills/mobile/dart/rules/async-patterns.md +112 -0
  112. package/templates/base/skills/mobile/dart/rules/code-style.md +96 -0
  113. package/templates/base/skills/mobile/dart/rules/null-safety.md +84 -0
  114. package/templates/base/skills/mobile/dart/rules/type-system.md +111 -0
  115. package/templates/base/skills/mobile/flutter/SKILL.md +89 -0
  116. package/templates/base/skills/mobile/flutter/ci-cd/SKILL.md +82 -0
  117. package/templates/base/skills/mobile/flutter/ci-cd/references/ci-cd-pipeline.md +314 -0
  118. package/templates/base/skills/mobile/flutter/ci-cd/rules/code-signing.md +106 -0
  119. package/templates/base/skills/mobile/flutter/ci-cd/rules/codemagic-setup.md +116 -0
  120. package/templates/base/skills/mobile/flutter/ci-cd/rules/fastlane-setup.md +105 -0
  121. package/templates/base/skills/mobile/flutter/ci-cd/rules/github-actions.md +112 -0
  122. package/templates/base/skills/mobile/flutter/ci-cd/rules/store-deployment.md +106 -0
  123. package/templates/base/skills/mobile/flutter/ci-cd/rules/versioning.md +107 -0
  124. package/templates/base/skills/mobile/flutter/i18n/SKILL.md +78 -0
  125. package/templates/base/skills/mobile/flutter/i18n/references/i18n-architecture.md +225 -0
  126. package/templates/base/skills/mobile/flutter/i18n/rules/arb-files.md +182 -0
  127. package/templates/base/skills/mobile/flutter/i18n/rules/locale-switching.md +226 -0
  128. package/templates/base/skills/mobile/flutter/i18n/rules/localization-setup.md +137 -0
  129. package/templates/base/skills/mobile/flutter/i18n/rules/plural-gender.md +159 -0
  130. package/templates/base/skills/mobile/flutter/i18n/rules/text-direction.md +199 -0
  131. package/templates/base/skills/mobile/flutter/monitoring/SKILL.md +81 -0
  132. package/templates/base/skills/mobile/flutter/monitoring/references/monitoring-architecture.md +269 -0
  133. package/templates/base/skills/mobile/flutter/monitoring/rules/analytics.md +227 -0
  134. package/templates/base/skills/mobile/flutter/monitoring/rules/crashlytics-setup.md +195 -0
  135. package/templates/base/skills/mobile/flutter/monitoring/rules/logging.md +258 -0
  136. package/templates/base/skills/mobile/flutter/monitoring/rules/performance-monitoring.md +248 -0
  137. package/templates/base/skills/mobile/flutter/monitoring/rules/sentry-integration.md +249 -0
  138. package/templates/base/skills/mobile/flutter/networking/SKILL.md +88 -0
  139. package/templates/base/skills/mobile/flutter/networking/references/api-client-architecture.md +305 -0
  140. package/templates/base/skills/mobile/flutter/networking/rules/caching.md +212 -0
  141. package/templates/base/skills/mobile/flutter/networking/rules/connectivity.md +213 -0
  142. package/templates/base/skills/mobile/flutter/networking/rules/dio-setup.md +159 -0
  143. package/templates/base/skills/mobile/flutter/networking/rules/error-handling.md +209 -0
  144. package/templates/base/skills/mobile/flutter/networking/rules/interceptors.md +205 -0
  145. package/templates/base/skills/mobile/flutter/networking/rules/retrofit-patterns.md +194 -0
  146. package/templates/base/skills/mobile/flutter/push-notifications/SKILL.md +87 -0
  147. package/templates/base/skills/mobile/flutter/push-notifications/references/notification-architecture.md +340 -0
  148. package/templates/base/skills/mobile/flutter/push-notifications/references/platform-setup.md +286 -0
  149. package/templates/base/skills/mobile/flutter/push-notifications/rules/background-processing.md +308 -0
  150. package/templates/base/skills/mobile/flutter/push-notifications/rules/deep-linking.md +217 -0
  151. package/templates/base/skills/mobile/flutter/push-notifications/rules/fcm-setup.md +164 -0
  152. package/templates/base/skills/mobile/flutter/push-notifications/rules/local-notifications.md +262 -0
  153. package/templates/base/skills/mobile/flutter/push-notifications/rules/notification-handling.md +210 -0
  154. package/templates/base/skills/mobile/flutter/push-notifications/rules/notification-permissions.md +246 -0
  155. package/templates/base/skills/mobile/flutter/push-notifications/rules/rich-notifications.md +320 -0
  156. package/templates/base/skills/mobile/flutter/references/freezed-patterns.md +162 -0
  157. package/templates/base/skills/mobile/flutter/references/project-structure.md +170 -0
  158. package/templates/base/skills/mobile/flutter/rules/animations.md +112 -0
  159. package/templates/base/skills/mobile/flutter/rules/architecture.md +121 -0
  160. package/templates/base/skills/mobile/flutter/rules/navigation-routing.md +117 -0
  161. package/templates/base/skills/mobile/flutter/rules/performance.md +112 -0
  162. package/templates/base/skills/mobile/flutter/rules/platform-adaptive.md +126 -0
  163. package/templates/base/skills/mobile/flutter/rules/state-management.md +110 -0
  164. package/templates/base/skills/mobile/flutter/rules/testing.md +131 -0
  165. package/templates/base/skills/mobile/flutter/rules/widget-conventions.md +122 -0
  166. package/templates/base/skills/mobile/flutter/security/SKILL.md +86 -0
  167. package/templates/base/skills/mobile/flutter/security/references/mobile-security-checklist.md +168 -0
  168. package/templates/base/skills/mobile/flutter/security/rules/api-key-protection.md +206 -0
  169. package/templates/base/skills/mobile/flutter/security/rules/authentication.md +248 -0
  170. package/templates/base/skills/mobile/flutter/security/rules/data-protection.md +271 -0
  171. package/templates/base/skills/mobile/flutter/security/rules/obfuscation.md +213 -0
  172. package/templates/base/skills/mobile/flutter/security/rules/secure-storage.md +171 -0
  173. package/templates/base/skills/mobile/flutter/security/rules/ssl-pinning.md +197 -0
  174. package/templates/base/skills/stability-verification/SKILL.md +64 -0
  175. package/templates/base/skills/stability-verification/references/release-checklist.md +34 -0
  176. package/templates/base/skills/stability-verification/references/security-fix-patterns.md +112 -0
  177. package/templates/base/skills/stability-verification/rules/verification-layers.md +67 -0
  178. package/templates/base/skills/stability-verification/rules/verification-workflow.md +69 -0
  179. package/templates/base/skills/stability-verification/scripts/verify.sh +294 -0
  180. package/templates/platforms/claude-code/CLAUDE.md.template +25 -0
  181. package/templates/platforms/claude-code/rules/build-gate.md +28 -0
  182. package/templates/platforms/claude-code/rules/completion-verification.md +30 -0
  183. package/templates/platforms/claude-code/rules/context-monitor.md +23 -0
  184. package/templates/platforms/claude-code/rules/plan-review.md +45 -0
  185. package/templates/platforms/claude-code/rules/quality-guards.md +43 -0
  186. package/templates/platforms/claude-code/rules/session-notes.md +18 -0
  187. package/templates/platforms/claude-code/rules/skill-suggest.md +27 -0
  188. package/templates/platforms/claude-code/scripts/build-gate.sh +73 -0
  189. package/templates/platforms/claude-code/scripts/completion-guard.sh +93 -0
  190. package/templates/platforms/claude-code/scripts/phase-guard.sh +79 -0
  191. package/templates/platforms/claude-code/scripts/safe-guard.sh +83 -0
  192. package/templates/platforms/claude-code/scripts/skill-rules.json +85 -0
  193. package/templates/platforms/claude-code/scripts/skill-suggest.sh +105 -0
  194. package/templates/platforms/claude-code/settings.json +111 -3
  195. package/templates/project-types/mobile-app/config.yaml +123 -0
  196. package/templates/project-types/mobile-app/process/workflow.xml +191 -0
@@ -0,0 +1,314 @@
1
+ ---
2
+ title: CI/CD Pipeline Architecture
3
+ category: reference
4
+ source: internal
5
+ tags: pipeline, architecture, environment, secrets, rollback, diagram
6
+ ---
7
+
8
+ # CI/CD Pipeline Architecture
9
+
10
+ 파이프라인 아키텍처 다이어그램, 환경별 설정, 시크릿 관리 전략, 롤백 절차.
11
+
12
+ ## Key Concepts
13
+
14
+ - **파이프라인**: 코드 변경 → 테스트 → 빌드 → 배포 자동화 흐름
15
+ - **환경 분리**: dev/staging/prod 각각 독립 설정, 시크릿, 배포 대상
16
+ - **시크릿 관리**: 서명 키, API 키, 서비스 계정을 안전하게 저장/주입
17
+ - **롤백**: 문제 발생 시 이전 버전으로 빠르게 복원
18
+
19
+ ## Pipeline Architecture
20
+
21
+ ```
22
+ 코드 변경 흐름:
23
+
24
+ Feature Branch PR (→ main) Tag (v*) Store
25
+ │ │ │ │
26
+ ▼ ▼ ▼ ▼
27
+ [Lint] [Test] [Build] [Deploy]
28
+ 분석 + 단위 테스트 iOS IPA TestFlight
29
+ 포맷 검사 통합 테스트 Android AAB Play Store
30
+ 커버리지 단계적 출시
31
+ │ │ │ │
32
+ ▼ ▼ ▼ ▼
33
+ 피드백 PR 체크 Artifact Notify
34
+ 즉시 알림 통과/실패 저장 Slack/Email
35
+ ```
36
+
37
+ ### 상세 파이프라인
38
+
39
+ ```
40
+ PR 생성/업데이트:
41
+ ├─ 1. Checkout
42
+ ├─ 2. flutter pub get (캐시)
43
+ ├─ 3. flutter analyze
44
+ ├─ 4. flutter test --coverage
45
+ ├─ 5. 커버리지 리포트 업로드
46
+ └─ 6. PR 상태 업데이트 (pass/fail)
47
+
48
+ 태그 푸시 (v1.2.3):
49
+ ├─ 1. Checkout + 태그에서 버전 추출
50
+ ├─ 2. flutter pub get
51
+ ├─ 3. flutter test (릴리스 전 최종 검증)
52
+ ├─ 4. 코드 서명 설정
53
+ │ ├─ iOS: match (provisioning + 인증서)
54
+ │ └─ Android: keystore 복원
55
+ ├─ 5. 빌드
56
+ │ ├─ iOS: flutter build ipa --release
57
+ │ └─ Android: flutter build appbundle --release
58
+ ├─ 6. 스토어 업로드
59
+ │ ├─ iOS: upload_to_testflight
60
+ │ └─ Android: supply (internal track)
61
+ ├─ 7. Artifact 저장 (30일)
62
+ ├─ 8. GitHub Release 생성 + CHANGELOG
63
+ └─ 9. Slack 알림 (#deployments)
64
+ ```
65
+
66
+ ## Environment Configuration
67
+
68
+ ### Flavor/Scheme 기반 환경 분리
69
+
70
+ ```dart
71
+ // lib/config/environment.dart
72
+ enum Environment { dev, staging, prod }
73
+
74
+ class EnvConfig {
75
+ final Environment env;
76
+ final String apiBaseUrl;
77
+ final String sentryDsn;
78
+ final bool enableAnalytics;
79
+
80
+ const EnvConfig({
81
+ required this.env,
82
+ required this.apiBaseUrl,
83
+ required this.sentryDsn,
84
+ required this.enableAnalytics,
85
+ });
86
+
87
+ static const dev = EnvConfig(
88
+ env: Environment.dev,
89
+ apiBaseUrl: 'https://api-dev.yourapp.com',
90
+ sentryDsn: '',
91
+ enableAnalytics: false,
92
+ );
93
+
94
+ static const staging = EnvConfig(
95
+ env: Environment.staging,
96
+ apiBaseUrl: 'https://api-staging.yourapp.com',
97
+ sentryDsn: 'https://xxx@sentry.io/staging',
98
+ enableAnalytics: false,
99
+ );
100
+
101
+ static const prod = EnvConfig(
102
+ env: Environment.prod,
103
+ apiBaseUrl: 'https://api.yourapp.com',
104
+ sentryDsn: 'https://xxx@sentry.io/prod',
105
+ enableAnalytics: true,
106
+ );
107
+ }
108
+ ```
109
+
110
+ ### --dart-define 으로 빌드 시 주입
111
+
112
+ ```bash
113
+ # Dev
114
+ flutter run \
115
+ --dart-define=ENV=dev \
116
+ --dart-define=API_URL=https://api-dev.yourapp.com
117
+
118
+ # Staging
119
+ flutter build apk \
120
+ --dart-define=ENV=staging \
121
+ --dart-define=API_URL=https://api-staging.yourapp.com
122
+
123
+ # Production
124
+ flutter build appbundle \
125
+ --release \
126
+ --dart-define=ENV=prod \
127
+ --dart-define=API_URL=https://api.yourapp.com
128
+ ```
129
+
130
+ ```dart
131
+ // 빌드 시 주입된 값 읽기
132
+ class BuildConfig {
133
+ static const env = String.fromEnvironment('ENV', defaultValue: 'dev');
134
+ static const apiUrl = String.fromEnvironment('API_URL');
135
+
136
+ static bool get isProduction => env == 'prod';
137
+ static bool get isDev => env == 'dev';
138
+ }
139
+ ```
140
+
141
+ ### CI 환경별 워크플로우
142
+
143
+ ```yaml
144
+ # Codemagic: 환경별 워크플로우
145
+ workflows:
146
+ dev-build:
147
+ triggering:
148
+ events: [push]
149
+ branch_patterns:
150
+ - pattern: "develop"
151
+ scripts:
152
+ - name: Build dev
153
+ script: |
154
+ flutter build apk --dart-define=ENV=dev
155
+
156
+ staging-build:
157
+ triggering:
158
+ events: [push]
159
+ branch_patterns:
160
+ - pattern: "release/*"
161
+ scripts:
162
+ - name: Build staging
163
+ script: |
164
+ flutter build appbundle --dart-define=ENV=staging
165
+
166
+ prod-build:
167
+ triggering:
168
+ events: [tag]
169
+ tag_patterns:
170
+ - pattern: "v*"
171
+ scripts:
172
+ - name: Build production
173
+ script: |
174
+ flutter build appbundle --release --dart-define=ENV=prod
175
+ ```
176
+
177
+ ## Secrets Management
178
+
179
+ ### 시크릿 분류
180
+
181
+ ```
182
+ Level 1 — 최고 기밀 (유출 시 앱 탈취):
183
+ ├── Android keystore + 비밀번호
184
+ ├── iOS Distribution 인증서 + 개인키
185
+ └── App Store Connect API Key (.p8)
186
+
187
+ Level 2 — 기밀 (유출 시 서비스 악용):
188
+ ├── Google Play 서비스 계정 키
189
+ ├── Firebase 서비스 계정
190
+ ├── Sentry DSN (prod)
191
+ └── match 암호화 비밀번호
192
+
193
+ Level 3 — 일반 (유출 시 정보 노출):
194
+ ├── Slack Webhook URL
195
+ ├── Codecov Token
196
+ └── Firebase App ID
197
+ ```
198
+
199
+ ### 시크릿 저장 위치
200
+
201
+ ```
202
+ GitHub Actions:
203
+ Repository > Settings > Secrets and variables > Actions
204
+ ├── Repository secrets (레포 전체)
205
+ └── Environment secrets (환경별 분리)
206
+ ├── production (승인 필요 설정 가능)
207
+ └── staging
208
+
209
+ Codemagic:
210
+ App Settings > Environment variables
211
+ ├── Variable groups (그룹별 관리)
212
+ └── Secure 체크 → 로그에 마스킹
213
+
214
+ Fastlane:
215
+ .env 파일 (로컬) + CI 환경변수 (CI)
216
+ ├── .env.default (공통, .gitignore)
217
+ └── .env.production (.gitignore)
218
+ ```
219
+
220
+ ### 시크릿 접근 제한
221
+
222
+ ```yaml
223
+ # GitHub Actions: 환경별 보호 규칙
224
+ # Repository > Settings > Environments > production
225
+ # ├── Required reviewers: 2명
226
+ # ├── Wait timer: 5분
227
+ # └── Deployment branches: main only
228
+
229
+ jobs:
230
+ deploy-production:
231
+ runs-on: ubuntu-latest
232
+ environment: production # 승인 필요
233
+ steps:
234
+ - name: Deploy
235
+ env:
236
+ # production 환경의 시크릿만 접근 가능
237
+ KEYSTORE: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}
238
+ run: ...
239
+ ```
240
+
241
+ ## Rollback Procedures
242
+
243
+ ### iOS 롤백
244
+
245
+ ```
246
+ App Store:
247
+ 1. 이전 버전으로 롤백 불가 (Apple 정책)
248
+ 2. 대안: 핫픽스 빌드를 새 버전으로 긴급 제출
249
+ - Expedited Review 요청 (App Store Connect)
250
+ - 심사 시간: 보통 24시간 → 긴급 시 수시간
251
+ 3. TestFlight: 이전 빌드 재활성화 가능
252
+
253
+ 긴급 핫픽스 절차:
254
+ git checkout -b hotfix/v1.2.4 v1.2.3
255
+ # 수정 적용
256
+ git tag v1.2.4
257
+ git push origin v1.2.4
258
+ # → CI 자동 빌드 → TestFlight 업로드 → 긴급 심사 요청
259
+ ```
260
+
261
+ ### Android 롤백
262
+
263
+ ```
264
+ Play Store:
265
+ 1. Console > Release > Production > Release history
266
+ 2. 이전 릴리스의 "..." > "Release to Production"
267
+ (이전 버전을 새 릴리스로 재배포)
268
+ 3. 또는 단계적 출시 중이라면 "Halt rollout"
269
+
270
+ 자동 롤백 (Fastlane):
271
+ lane :rollback do |options|
272
+ version_code = options[:version_code]
273
+ # Play Store에서 이전 AAB 다운로드 후 재배포
274
+ # 또는 CI artifact에서 이전 빌드 가져와 재업로드
275
+ supply(
276
+ track: "production",
277
+ rollout: "1.0",
278
+ version_code: version_code,
279
+ json_key: ENV["GOOGLE_PLAY_JSON_KEY_PATH"],
280
+ )
281
+ end
282
+ ```
283
+
284
+ ### 롤백 판단 기준
285
+
286
+ ```
287
+ 즉시 롤백 (< 1시간 이내 판단):
288
+ ├── 크래시율 > 2% (이전 버전 대비 3배 이상 증가)
289
+ ├── ANR 비율 > 1%
290
+ ├── 결제/인증 등 핵심 기능 장애
291
+ └── 데이터 손실 발생
292
+
293
+ 모니터링 후 판단 (24시간):
294
+ ├── 크래시율 1-2%
295
+ ├── 특정 기기/OS 버전에서만 발생
296
+ ├── 사용자 리뷰 평점 급락
297
+ └── 비핵심 기능 장애
298
+
299
+ 유지 + 핫픽스:
300
+ ├── 크래시율 < 1% (경미)
301
+ ├── UI 버그 (기능 작동)
302
+ └── 성능 저하 (크래시 아님)
303
+ ```
304
+
305
+ ## Common Pitfalls
306
+
307
+ 1. **빌드 넘버 충돌**: iOS/Android 빌드 넘버를 별도 관리 → 동일 CI 변수 사용 권장
308
+ 2. **캐시 오염**: Flutter/Gradle/CocoaPods 캐시가 오래되면 빌드 실패 → 주기적 캐시 무효화
309
+ 3. **시크릿 로그 노출**: `echo $SECRET` → CI 로그에 노출 → 항상 마스킹 확인
310
+ 4. **인증서 만료**: match 인증서 1년 만료 → 알림 설정 필수
311
+ 5. **Xcode 버전 차이**: CI와 로컬 Xcode 버전 불일치 → `xcode: 16.2` 고정
312
+ 6. **Gradle 메모리**: Android 빌드 OOM → `org.gradle.jvmargs=-Xmx4g` 설정
313
+ 7. **동시 빌드**: 같은 브랜치 여러 빌드 → `cancel_previous_builds` 설정
314
+ 8. **태그 실수**: 잘못된 태그 푸시 → production 빌드 트리거 → 태그 보호 규칙 설정
@@ -0,0 +1,106 @@
1
+ ---
2
+ title: Code Signing
3
+ impact: CRITICAL
4
+ impactDescription: "서명 누락 → 스토어 업로드 불가, 키 유출 → 앱 탈취 위험"
5
+ tags: code-signing, ios, android, provisioning, keystore, match
6
+ ---
7
+
8
+ ## Code Signing
9
+
10
+ **Impact: CRITICAL (서명 누락 → 스토어 업로드 불가, 키 유출 → 앱 탈취 위험)**
11
+
12
+ iOS provisioning profile, Android keystore 관리. CI 환경에서 안전한 서명 키 주입.
13
+
14
+ ### iOS 코드 서명 (match)
15
+
16
+ **Incorrect (수동 관리):**
17
+ ```
18
+ Xcode > Automatically manage signing 체크
19
+ → 개발자마다 다른 profile, CI 빌드 실패, 인증서 충돌
20
+ ```
21
+
22
+ **Correct (match로 중앙 관리):**
23
+ ```ruby
24
+ # fastlane/Matchfile
25
+ git_url(ENV["MATCH_GIT_URL"])
26
+ storage_mode("git")
27
+ type("appstore")
28
+ app_identifier("com.yourapp.id")
29
+
30
+ # CI에서 실행
31
+ create_keychain(
32
+ name: "ci_keychain",
33
+ password: ENV["KEYCHAIN_PASSWORD"],
34
+ default_keychain: true, unlock: true, timeout: 3600,
35
+ )
36
+ match(
37
+ type: "appstore",
38
+ keychain_name: "ci_keychain",
39
+ keychain_password: ENV["KEYCHAIN_PASSWORD"],
40
+ readonly: true, # CI에서는 readonly — 인증서 생성 금지
41
+ )
42
+ ```
43
+
44
+ ### Android 코드 서명
45
+
46
+ **Incorrect (keystore를 레포에 포함):**
47
+ ```
48
+ android/app/release.keystore # 절대 금지!
49
+ android/key.properties # 비밀번호 하드코딩
50
+ ```
51
+
52
+ **Correct (CI 환경변수로 주입):**
53
+ ```groovy
54
+ // android/app/build.gradle
55
+ android {
56
+ signingConfigs {
57
+ release {
58
+ if (System.getenv("ANDROID_KEYSTORE_BASE64")) {
59
+ storeFile file("../release.keystore")
60
+ storePassword System.getenv("ANDROID_KEYSTORE_PASSWORD")
61
+ keyAlias System.getenv("ANDROID_KEY_ALIAS")
62
+ keyPassword System.getenv("ANDROID_KEY_PASSWORD")
63
+ }
64
+ }
65
+ }
66
+ }
67
+ ```
68
+
69
+ ```bash
70
+ # CI에서 keystore 복원
71
+ echo "$ANDROID_KEYSTORE_BASE64" | base64 --decode > android/release.keystore
72
+ ```
73
+
74
+ ### 개발/배포 인증서 분리
75
+
76
+ ```
77
+ ├── Development — 디버그/테스트 (iOS provisioning, Android debug.keystore)
78
+ ├── Ad Hoc — 내부 테스트 배포 (iOS only)
79
+ └── Distribution — 스토어 제출 (iOS App Store, Android release.keystore)
80
+ ```
81
+
82
+ ### 키 로테이션
83
+
84
+ - iOS: Apple 인증서 1년 만료 → `match nuke distribution` → `match appstore`
85
+ - Android: Play App Signing 활성화 → Google이 앱 서명 키 관리, upload key만 팀 관리
86
+ - Upload Key 분실 시 → Google Play Console에서 리셋 요청
87
+
88
+ ### .gitignore 필수 항목
89
+
90
+ ```gitignore
91
+ *.mobileprovision
92
+ *.p12
93
+ *.cer
94
+ *.keystore
95
+ *.jks
96
+ key.properties
97
+ ```
98
+
99
+ ### 규칙
100
+
101
+ - `match` 로 iOS 인증서 관리 — 수동 Xcode 서명 관리 금지
102
+ - CI에서 `match(readonly: true)` — 인증서 신규 생성 방지
103
+ - Android keystore → base64 → CI 환경변수 주입
104
+ - `key.properties` `.gitignore` 추가 — 레포 커밋 금지
105
+ - Play App Signing 활성화 — upload key만 팀 관리
106
+ - 개발/배포 인증서 분리 — 동일 인증서 혼용 금지
@@ -0,0 +1,116 @@
1
+ ---
2
+ title: Codemagic Setup
3
+ impact: HIGH
4
+ impactDescription: "CI 미구성 → 수동 빌드, Codemagic 자동화 → Flutter 네이티브 지원"
5
+ tags: codemagic, ci, yaml, workflow, artifact, trigger
6
+ ---
7
+
8
+ ## Codemagic Setup
9
+
10
+ **Impact: HIGH (CI 미구성 → 수동 빌드, Codemagic 자동화 → Flutter 네이티브 지원)**
11
+
12
+ codemagic.yaml 워크플로우 구성, 환경변수/시크릿, 빌드 트리거, artifact 배포.
13
+
14
+ ### codemagic.yaml
15
+
16
+ **Incorrect (GUI만 사용):**
17
+ ```
18
+ Codemagic 웹 UI에서 빌드 설정 → 코드 관리 불가, 롤백 불가, 팀 차이 발생
19
+ ```
20
+
21
+ **Correct (yaml 코드 관리):**
22
+ ```yaml
23
+ workflows:
24
+ ios-release:
25
+ name: iOS Release
26
+ max_build_duration: 30
27
+ instance_type: mac_mini_m2
28
+ environment:
29
+ groups: [ios_credentials, app_store_connect]
30
+ flutter: "3.27.0"
31
+ xcode: latest
32
+ cocoapods: default
33
+ triggering:
34
+ events: [tag]
35
+ tag_patterns:
36
+ - pattern: "v*"
37
+ include: true
38
+ cancel_previous_builds: true
39
+ scripts:
40
+ - name: Set up code signing
41
+ script: |
42
+ keychain initialize
43
+ app-store-connect fetch-signing-files $(BUNDLE_ID) --type IOS_APP_STORE --create
44
+ keychain add-certificates
45
+ - name: Build
46
+ script: |
47
+ xcode-project use-profiles
48
+ flutter packages pub get
49
+ flutter build ipa --release --build-number=$PROJECT_BUILD_NUMBER \
50
+ --export-options-plist=/Users/builder/export_options.plist
51
+ artifacts:
52
+ - build/ios/ipa/*.ipa
53
+ publishing:
54
+ app_store_connect:
55
+ auth: integration
56
+ submit_to_testflight: true
57
+ slack:
58
+ channel: "#deployments"
59
+ notify:
60
+ success: true
61
+ failure: true
62
+
63
+ android-release:
64
+ name: Android Release
65
+ instance_type: linux_x2
66
+ environment:
67
+ groups: [android_credentials, google_play]
68
+ flutter: "3.27.0"
69
+ triggering:
70
+ events: [tag]
71
+ tag_patterns:
72
+ - pattern: "v*"
73
+ scripts:
74
+ - name: Set up signing + Build
75
+ script: |
76
+ echo $ANDROID_KEYSTORE_BASE64 | base64 --decode > android/release.keystore
77
+ flutter packages pub get
78
+ flutter build appbundle --release --build-number=$PROJECT_BUILD_NUMBER
79
+ artifacts:
80
+ - build/app/outputs/bundle/release/*.aab
81
+ publishing:
82
+ google_play:
83
+ credentials: $GCLOUD_SERVICE_ACCOUNT_CREDENTIALS
84
+ track: internal
85
+
86
+ test:
87
+ name: Test & Analyze
88
+ instance_type: linux_x2
89
+ environment:
90
+ flutter: "3.27.0"
91
+ triggering:
92
+ events: [pull_request]
93
+ scripts:
94
+ - name: Test
95
+ script: |
96
+ flutter packages pub get && flutter analyze && flutter test --coverage
97
+ ```
98
+
99
+ ### 환경변수/시크릿
100
+
101
+ ```
102
+ Codemagic UI > Environment variables:
103
+ ├── ios_credentials: CERTIFICATE_PRIVATE_KEY, BUNDLE_ID, PROVISIONING_PROFILE
104
+ ├── app_store_connect: ASC_KEY_ID, ASC_ISSUER_ID, ASC_API_KEY (.p8)
105
+ ├── android_credentials: ANDROID_KEYSTORE_BASE64, PASSWORD, ALIAS, KEY_PASSWORD
106
+ └── google_play: GCLOUD_SERVICE_ACCOUNT_CREDENTIALS (JSON)
107
+ ```
108
+
109
+ ### 규칙
110
+
111
+ - `codemagic.yaml` 로 워크플로우 정의 — GUI 설정 대신 코드 관리
112
+ - 시크릿은 Codemagic UI에서만 설정 — yaml에 비밀값 금지
113
+ - `instance_type: mac_mini_m2` — iOS 빌드는 macOS 필수
114
+ - `cancel_previous_builds: true` — 동일 브랜치 중복 빌드 방지
115
+ - PR → test, 태그 → release 워크플로우 분리
116
+ - `PROJECT_BUILD_NUMBER` 활용 — 자동 증가 빌드 넘버
@@ -0,0 +1,105 @@
1
+ ---
2
+ title: Fastlane Setup
3
+ impact: HIGH
4
+ impactDescription: "수동 배포 → 휴먼 에러, Fastlane 자동화 → 일관된 빌드/배포"
5
+ tags: fastlane, match, supply, deliver, ios, android, automation
6
+ ---
7
+
8
+ ## Fastlane Setup
9
+
10
+ **Impact: HIGH (수동 배포 → 휴먼 에러, Fastlane 자동화 → 일관된 빌드/배포)**
11
+
12
+ Fastfile 구성, match (iOS 인증서), supply (Google Play), deliver (App Store), 환경 관리.
13
+
14
+ ### Fastfile 구성
15
+
16
+ **Incorrect (빌드와 배포 혼합, 하드코딩):**
17
+ ```ruby
18
+ lane :deploy do
19
+ build_app(scheme: "Runner")
20
+ upload_to_testflight(username: "me@email.com")
21
+ # → 인증서 관리 없음, 환경 분리 없음, 2FA 문제
22
+ end
23
+ ```
24
+
25
+ **Correct (레인 분리, API Key):**
26
+ ```ruby
27
+ # ios/fastlane/Fastfile
28
+ platform :ios do
29
+ lane :setup_signing do
30
+ create_keychain(name: "ci_keychain", password: ENV["KEYCHAIN_PASSWORD"],
31
+ default_keychain: true, unlock: true, timeout: 3600)
32
+ match(type: "appstore", keychain_name: "ci_keychain",
33
+ keychain_password: ENV["KEYCHAIN_PASSWORD"], readonly: true)
34
+ end
35
+
36
+ lane :beta do
37
+ setup_signing
38
+ build_app(workspace: "Runner.xcworkspace", scheme: "Runner",
39
+ export_method: "app-store")
40
+ upload_to_testflight(
41
+ skip_waiting_for_build_processing: true,
42
+ api_key_path: "fastlane/api_key.json",
43
+ )
44
+ end
45
+ end
46
+ ```
47
+
48
+ ```ruby
49
+ # android/fastlane/Fastfile
50
+ platform :android do
51
+ lane :beta do
52
+ sh("cd ../.. && flutter build appbundle --release")
53
+ supply(
54
+ track: "internal",
55
+ aab: "../build/app/outputs/bundle/release/app-release.aab",
56
+ json_key: ENV["GOOGLE_PLAY_JSON_KEY_PATH"],
57
+ skip_upload_metadata: true,
58
+ skip_upload_images: true,
59
+ )
60
+ end
61
+
62
+ lane :release do |options|
63
+ sh("cd ../.. && flutter build appbundle --release")
64
+ supply(
65
+ track: "production",
66
+ aab: "../build/app/outputs/bundle/release/app-release.aab",
67
+ json_key: ENV["GOOGLE_PLAY_JSON_KEY_PATH"],
68
+ rollout: options[:rollout] || "0.1",
69
+ )
70
+ end
71
+ end
72
+ ```
73
+
74
+ ### App Store Connect API Key
75
+
76
+ ```json
77
+ // fastlane/api_key.json (CI 환경변수로 생성, .gitignore 필수)
78
+ {
79
+ "key_id": "YOUR_KEY_ID",
80
+ "issuer_id": "YOUR_ISSUER_ID",
81
+ "key": "-----BEGIN EC PRIVATE KEY-----\n...\n-----END EC PRIVATE KEY-----",
82
+ "in_house": false
83
+ }
84
+ ```
85
+
86
+ ### .env 관리
87
+
88
+ ```bash
89
+ # ios/fastlane/.env.default (.gitignore 추가)
90
+ APPLE_ID=ci@yourteam.com
91
+ TEAM_ID=XXXXXXXXXX
92
+ MATCH_GIT_URL=https://github.com/your-org/certificates
93
+
94
+ # ios/fastlane/.env.production
95
+ APP_IDENTIFIER=com.yourapp.id
96
+ ```
97
+
98
+ ### 규칙
99
+
100
+ - `Fastfile` 레인 분리 — `setup_signing`, `beta`, `release` 독립
101
+ - `match(readonly: true)` — CI에서 인증서 신규 생성 금지
102
+ - App Store Connect API Key — 2FA 우회, CI 호환
103
+ - `supply` 에 `json_key` — Google Play 서비스 계정 키
104
+ - `.env` 로 환경 분리 — 하드코딩 금지, `.gitignore` 추가
105
+ - 단계적 출시 — `supply(rollout: "0.1")` 소규모 배포 후 확대