project-auto-wizard 0.13.3 → 0.14.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 (112) hide show
  1. package/README.md +1 -1
  2. package/bin/project-auto-wizard.js +18 -4
  3. package/package.json +2 -2
  4. package/payload/config/breaking-changes.json +28 -14
  5. package/payload/config/wizard-prompts.yml +102 -46
  6. package/payload/flutter-app/android/fastlane/Fastfile.playstore +44 -32
  7. package/payload/flutter-app/ios/ExportOptions.plist +8 -8
  8. package/payload/flutter-app/ios/fastlane/Fastfile +57 -43
  9. package/payload/scripts/changelog_manager.py +296 -257
  10. package/payload/scripts/issue_helper.py +54 -50
  11. package/payload/scripts/messages.py +2279 -0
  12. package/payload/scripts/truncate_release_notes.py +7 -6
  13. package/payload/scripts/version_manager.py +64 -61
  14. package/payload/version.yml.template +2 -1
  15. package/payload/workflows/common/PROJECT-COMMON-AI-PR-SUMMARY.yaml +17 -12
  16. package/payload/workflows/common/PROJECT-COMMON-AUTO-CHANGELOG-CONTROL.yaml +59 -34
  17. package/payload/workflows/common/PROJECT-COMMON-ISSUE-HELPER.yaml +17 -15
  18. package/payload/workflows/common/PROJECT-COMMON-README-VERSION-UPDATE.yaml +17 -10
  19. package/payload/workflows/common/PROJECT-COMMON-RELEASE-PUBLISH.yaml +54 -44
  20. package/payload/workflows/common/PROJECT-COMMON-VERSION-CONTROL.yaml +24 -17
  21. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-FIREBASE-CICD.yaml +194 -184
  22. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-PLAYSTORE-CICD.yaml +226 -213
  23. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-SELFHOSTED-CICD.yaml +46 -42
  24. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-TEST-APK.yaml +334 -241
  25. package/payload/workflows/flutter/PROJECT-FLUTTER-APP-BUILD-TRIGGER.yaml +152 -128
  26. package/payload/workflows/flutter/PROJECT-FLUTTER-CI.yaml +246 -188
  27. package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TEST-TESTFLIGHT.yaml +353 -238
  28. package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TESTFLIGHT.yaml +96 -85
  29. package/payload/workflows/go/PROJECT-GO-CI.yaml +47 -36
  30. package/payload/workflows/go/PROJECT-GO-PR-PREVIEW.yaml +945 -508
  31. package/payload/workflows/go/PROJECT-GO-SIMPLE-CICD.yaml +155 -133
  32. package/payload/workflows/next/PROJECT-NEXT-CI.yaml +76 -60
  33. package/payload/workflows/next/PROJECT-NEXT-CICD.yaml +97 -77
  34. package/payload/workflows/python/PROJECT-PYTHON-CI.yaml +62 -47
  35. package/payload/workflows/python/PROJECT-PYTHON-PR-PREVIEW.yaml +942 -505
  36. package/payload/workflows/python/PROJECT-PYTHON-SIMPLE-CICD.yaml +148 -126
  37. package/payload/workflows/react/PROJECT-REACT-CI.yaml +86 -70
  38. package/payload/workflows/react/PROJECT-REACT-CICD.yaml +112 -92
  39. package/payload/workflows/spring/PROJECT-SPRING-CI.yml +112 -82
  40. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-NGINX-CICD.yaml +180 -150
  41. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-TRAEFIK-CICD.yaml +161 -131
  42. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-PR-PREVIEW.yaml +970 -549
  43. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-SIMPLE-CICD.yaml +193 -162
  44. package/src/cli/args.js +98 -52
  45. package/src/cli/help.js +8 -41
  46. package/src/commands/doctor.js +85 -89
  47. package/src/commands/dry-run.js +63 -43
  48. package/src/commands/full.js +79 -77
  49. package/src/commands/install-settings.js +16 -15
  50. package/src/commands/interactive-flutter.js +20 -19
  51. package/src/commands/interactive.js +135 -132
  52. package/src/commands/purge.js +47 -42
  53. package/src/commands/status.js +36 -36
  54. package/src/commands/uninstall.js +43 -41
  55. package/src/context.js +12 -11
  56. package/src/core/assets.js +12 -11
  57. package/src/core/baseline.js +27 -27
  58. package/src/core/branches.js +29 -27
  59. package/src/core/branding.js +7 -6
  60. package/src/core/breaking-check.js +22 -21
  61. package/src/core/breaking.js +15 -8
  62. package/src/core/copy/app-files.js +5 -4
  63. package/src/core/copy/flutter-app.js +8 -8
  64. package/src/core/copy/gitignore.js +58 -50
  65. package/src/core/copy/readme.js +45 -35
  66. package/src/core/copy/simple.js +16 -15
  67. package/src/core/copy/workflows.js +131 -124
  68. package/src/core/deploy-style.js +51 -48
  69. package/src/core/detect-fs.js +57 -57
  70. package/src/core/detect.js +67 -65
  71. package/src/core/errors.js +2 -2
  72. package/src/core/flutter-doctor.js +17 -16
  73. package/src/core/flutter-hooks.js +33 -32
  74. package/src/core/flutter-options.js +34 -33
  75. package/src/core/fsutil.js +12 -12
  76. package/src/core/installed-stores.js +4 -4
  77. package/src/core/logger.js +42 -40
  78. package/src/core/paths-resolve.js +88 -86
  79. package/src/core/paths.js +10 -10
  80. package/src/core/release-options.js +8 -8
  81. package/src/core/removal-exec.js +14 -13
  82. package/src/core/removal-plan.js +37 -37
  83. package/src/core/types.js +47 -47
  84. package/src/core/verify.js +44 -38
  85. package/src/core/version-yml.js +76 -68
  86. package/src/core/wizard-env.js +46 -46
  87. package/src/core/wizard-labels.js +63 -41
  88. package/src/i18n/catalog/en/cli.js +50 -0
  89. package/src/i18n/catalog/en/commands.js +187 -0
  90. package/src/i18n/catalog/en/copy.js +19 -0
  91. package/src/i18n/catalog/en/core.js +74 -0
  92. package/src/i18n/catalog/en/core2.js +15 -0
  93. package/src/i18n/catalog/en/ui.js +221 -0
  94. package/src/i18n/catalog/en.js +12 -0
  95. package/src/i18n/catalog/index.js +5 -0
  96. package/src/i18n/catalog/ko/cli.js +50 -0
  97. package/src/i18n/catalog/ko/commands.js +187 -0
  98. package/src/i18n/catalog/ko/copy.js +19 -0
  99. package/src/i18n/catalog/ko/core.js +74 -0
  100. package/src/i18n/catalog/ko/core2.js +15 -0
  101. package/src/i18n/catalog/ko/ui.js +221 -0
  102. package/src/i18n/catalog/ko.js +10 -0
  103. package/src/i18n/index.js +44 -0
  104. package/src/i18n/languages.js +9 -0
  105. package/src/index.js +128 -94
  106. package/src/ui/ansi.js +7 -7
  107. package/src/ui/banner.js +7 -6
  108. package/src/ui/env-plan.js +82 -81
  109. package/src/ui/prompts.js +97 -122
  110. package/src/ui/readline-engine.js +59 -58
  111. package/src/ui/status-cards.js +37 -31
  112. package/src/ui/summary.js +89 -88
@@ -1,77 +1,77 @@
1
1
  # project-auto-wizard:managed-workflow
2
- # Flutter Android Firebase App Distribution 배포
2
+ # Flutter Android Firebase App Distribution deploy
3
3
  #
4
- # {{MAIN_BRANCH}} 브랜치 푸시 시 Android AAB를 빌드하고
5
- # Firebase App Distribution에 자동 배포합니다.
4
+ # On a push to the {{MAIN_BRANCH}} branch, builds the Android AAB and
5
+ # deploys it to Firebase App Distribution.
6
6
  #
7
- # PlayStore CICD와 동일한 빌드 과정(AAB + 버전 검증)을 거친 후
8
- # Play Store 대신 Firebase App Distribution에 업로드합니다.
7
+ # After the same build process as the PlayStore CICD (AAB + version check),
8
+ # it uploads to Firebase App Distribution instead of the Play Store.
9
9
  #
10
- # 필수 GitHub Secrets
10
+ # Required GitHub Secrets
11
11
  #
12
12
  # Release Keystore:
13
- # RELEASE_KEYSTORE_BASE64: 서명용 keystore (base64)
14
- # RELEASE_KEYSTORE_PASSWORD: keystore 비밀번호
13
+ # RELEASE_KEYSTORE_BASE64: signing keystore (base64)
14
+ # RELEASE_KEYSTORE_PASSWORD: keystore password
15
15
  # RELEASE_KEY_ALIAS: key alias
16
- # RELEASE_KEY_PASSWORD: key 비밀번호
16
+ # RELEASE_KEY_PASSWORD: key password
17
17
  #
18
18
  # Firebase:
19
- # FIREBASE_SERVICE_ACCOUNT_JSON_BASE64: Firebase 서비스 계정 JSON (base64)
19
+ # FIREBASE_SERVICE_ACCOUNT_JSON_BASE64: Firebase service account JSON (base64)
20
20
  #
21
- # 환경 설정 (선택):
22
- # ENV_FILE 또는 ENV: .env 파일 내용 (둘 중 하나, ENV_FILE 우선)
23
- # GOOGLE_SERVICES_JSON (선택): Firebase google-services.json
21
+ # Environment settings (optional):
22
+ # ENV_FILE or ENV: contents of the .env file (either one; ENV_FILE takes precedence)
23
+ # GOOGLE_SERVICES_JSON (optional): Firebase google-services.json
24
24
  #
25
- # ※ 위 Secrets는 저장소 Settings → Secrets and variables → Actions에 등록하세요.
26
- # FIREBASE_APP_ID·FIREBASE_TESTER_GROUP은 아래 env 섹션 값을 직접 수정합니다.
25
+ # Note: register the Secrets above under the repository Settings → Secrets and variables → Actions.
26
+ # Edit FIREBASE_APP_ID and FIREBASE_TESTER_GROUP directly in the env section below.
27
27
  #
28
- # 프로젝트별 설정 (env 섹션에서 수정)
29
- # APP_ARTIFACT_NAME : 프로젝트 이름
30
- # FLUTTER_VERSION : Flutter SDK 버전 (빈 값 = stable 최신)
31
- # JAVA_VERSION : Java 버전
32
- # FIREBASE_APP_ID : Firebase 앱 ID (Firebase Console에서 확인)
33
- # FIREBASE_TESTER_GROUP : Firebase 테스터 그룹명
28
+ # Project settings (edit in the env section)
29
+ # APP_ARTIFACT_NAME : project name
30
+ # FLUTTER_VERSION : Flutter SDK version (empty = latest stable)
31
+ # JAVA_VERSION : Java version
32
+ # FIREBASE_APP_ID : Firebase app ID (see the Firebase Console)
33
+ # FIREBASE_TESTER_GROUP : Firebase tester group name
34
34
  #
35
- # 사전 설정:
36
- # 1. Firebase Console → App Distribution → 테스터 그룹 생성
37
- # 2. Firebase 서비스 계정 JSON 생성 (base64 인코딩)
38
- # 3. GitHub Secrets에 FIREBASE_SERVICE_ACCOUNT_JSON_BASE64 등록
39
- # 4. env 섹션의 FIREBASE_APP_ID, FIREBASE_TESTER_GROUP 수정
35
+ # Setup:
36
+ # 1. Firebase Console → App Distribution → create a tester group
37
+ # 2. Create the Firebase service account JSON (base64 encoded)
38
+ # 3. Register FIREBASE_SERVICE_ACCOUNT_JSON_BASE64 in GitHub Secrets
39
+ # 4. Edit FIREBASE_APP_ID and FIREBASE_TESTER_GROUP in the env section
40
40
 
41
41
  name: PROJECT-FLUTTER-ANDROID-FIREBASE-APPDIST-CICD
42
42
 
43
43
  on:
44
44
  push:
45
45
  branches: ["{{MAIN_BRANCH}}"]
46
- # @wizard paths-anchor (모노레포일 때 integrator가 paths 필터를 여기 주입)
46
+ # @wizard paths-anchor (in a monorepo the installer injects a paths filter here)
47
47
  workflow_dispatch:
48
48
 
49
49
  env:
50
- # 프로젝트별 설정 (아래 값들을 수정하세요)
51
- # 프로젝트 이름
50
+ # Project settings (edit the values below)
51
+ # Project name
52
52
  APP_ARTIFACT_NAME: "__APP_ARTIFACT_NAME__" # @wizard ask:@repo
53
- # Flutter/Java 버전
54
- # Flutter SDK 버전 — 비워 두면 stable 채널 최신을 쓴다(최신 flutter create 프로젝트의 SDK 제약과 맞음).
55
- # 특정 버전에 고정하려면 "3.38.9"처럼 적는다. pubspec.yaml의 environment.sdk 범위를 만족해야 한다.
53
+ # Flutter/Java versions
54
+ # Flutter SDK version - leave empty to use the latest stable channel (matches the SDK constraint of a fresh flutter create project).
55
+ # To pin a version, write it like "3.38.9". It must satisfy the environment.sdk range in pubspec.yaml.
56
56
  FLUTTER_VERSION: ""
57
57
  JAVA_VERSION: "__JAVA_VERSION__" # @wizard ask:17
58
58
  PROJECT_TYPE: "flutter"
59
- # Flutter 루트 경로(레포 루트 기준). 단일레포면 ".", 모노레포면 "app" 등 — 설치 시 자동 설정
59
+ # Flutter root path (relative to the repo root): "." for a single repo, "app" etc. for a monorepo - set automatically at install
60
60
  FLUTTER_PROJECT_DIR: "." # @wizard auto:flutter-root
61
- # 환경변수 전달 방식 (dart-define | dotenv) — 설치 시 선택값으로 자동 설정
61
+ # How env vars are passed (dart-define | dotenv) - set automatically from the install-time choice
62
62
  ENV_MODE: "dart-define" # @wizard auto:flutter-env-mode
63
- # Firebase App Distribution 설정
63
+ # Firebase App Distribution settings
64
64
  FIREBASE_APP_ID: "your-firebase-app-id"
65
65
  FIREBASE_TESTER_GROUP: "testers"
66
66
 
67
67
  jobs:
68
68
  prepare-build:
69
- name: 환경 설정 및 준비
69
+ name: Environment setup and preparation
70
70
  runs-on: ubuntu-latest
71
71
  defaults:
72
72
  run:
73
73
  working-directory: ${{ env.FLUTTER_PROJECT_DIR }}
74
- # CHANGELOG 워크플로우가 성공한 경우에만 실행
74
+ # Run only when the CHANGELOG workflow succeeded
75
75
  if: ${{ github.event.workflow_run.conclusion == 'success' || github.event_name != 'workflow_run' }}
76
76
 
77
77
  outputs:
@@ -86,9 +86,9 @@ jobs:
86
86
  ref: "{{MAIN_BRANCH}}"
87
87
  fetch-depth: 0
88
88
 
89
- # 서명·업로드 Secret이 없으면 빌드를 한참 진행한 뒤에야 실패하므로, 빠진 이름을 먼저 모두 알려 주고 멈춘다
90
- # ENV_FILE·GOOGLE_SERVICES_JSON은 선택이라 점검하지 않는다
91
- - name: 배포 사전 점검 (Secret)
89
+ # Without the signing/upload Secrets the run would only fail well into the build, so report all missing names first and stop
90
+ # ENV_FILE and GOOGLE_SERVICES_JSON are optional, so they are not checked
91
+ - name: Pre-deploy check (Secrets)
92
92
  env:
93
93
  RELEASE_KEYSTORE_BASE64: ${{ secrets.RELEASE_KEYSTORE_BASE64 }}
94
94
  RELEASE_KEYSTORE_PASSWORD: ${{ secrets.RELEASE_KEYSTORE_PASSWORD }}
@@ -96,24 +96,25 @@ jobs:
96
96
  RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}
97
97
  FIREBASE_SERVICE_ACCOUNT_JSON_BASE64: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_JSON_BASE64 }}
98
98
  run: |
99
+ m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
99
100
  MISSING=""
100
101
  for NAME in RELEASE_KEYSTORE_BASE64 RELEASE_KEYSTORE_PASSWORD RELEASE_KEY_ALIAS RELEASE_KEY_PASSWORD FIREBASE_SERVICE_ACCOUNT_JSON_BASE64; do
101
102
  [ -n "${!NAME}" ] || MISSING="$MISSING $NAME"
102
103
  done
103
104
  FAILED=false
104
105
  if [ -n "$MISSING" ]; then
105
- echo "::error title=필수 Secret 누락::등록되지 않은 GitHub Secret:$MISSING — Settings → Secrets and variables → Actions에서 등록하세요"
106
+ echo "::error title=$(m flutter_a.precheck_missing_title)::$(m flutter_a.precheck_missing_body missing="$MISSING")"
106
107
  FAILED=true
107
108
  fi
108
- # 업로드 대상 앱 ID는 Secret이 아니라 이 파일 env 섹션 값이다
109
+ # The target app ID is not a Secret; it is the value in this file's env section
109
110
  if [ -z "$FIREBASE_APP_ID" ] || [ "$FIREBASE_APP_ID" = "your-firebase-app-id" ]; then
110
- echo "::error title=FIREBASE_APP_ID 미설정::워크플로우 env 섹션의 FIREBASE_APP_ID를 Firebase Console의 앱 ID로 바꾸세요"
111
+ echo "::error title=$(m flutter_a.precheck_firebase_app_id_title)::$(m flutter_a.precheck_firebase_app_id_body)"
111
112
  FAILED=true
112
113
  fi
113
114
  if [ "$FAILED" = "true" ]; then
114
115
  exit 1
115
116
  fi
116
- echo "✅ 사전 점검 통과: 필수 Secret과 FIREBASE_APP_ID가 모두 있습니다"
117
+ m flutter_a.precheck_passed_firebase
117
118
 
118
119
  - name: Pull latest changes
119
120
  run: git pull origin {{MAIN_BRANCH}}
@@ -153,63 +154,65 @@ jobs:
153
154
  dart run build_runner build --delete-conflicting-outputs
154
155
  fi
155
156
 
156
- - name: 현재 버전 정보 가져오기
157
+ - name: Get current version
157
158
  id: current_version
158
- working-directory: ${{ github.workspace }} # version_manager.py가 레포 루트 version.yml을 읽어야 함
159
+ working-directory: ${{ github.workspace }} # version_manager.py must read the repo-root version.yml
159
160
  run: |
160
- # VERSION 가져오기 (x.y.z 형식)
161
+ m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
162
+ # Get VERSION (x.y.z format)
161
163
  VERSION=$(python3 .github/scripts/version_manager.py get | tail -n 1)
162
164
 
163
- # VERSION_CODE 가져오기 (version.yml에서 관리되는 단순 증가 번호)
165
+ # Get VERSION_CODE (a simple incrementing number managed in version.yml)
164
166
  VERSION_CODE=$(python3 .github/scripts/version_manager.py get-code | tail -n 1)
165
167
 
166
- # 결과 출력
168
+ # Print the result
167
169
  echo "✅ VERSION: $VERSION"
168
170
  echo "✅ VERSION_CODE: $VERSION_CODE"
169
- echo "🔧 프로젝트 타입: ${{ env.PROJECT_TYPE }}"
171
+ m flutter_a.project_type project_type="${{ env.PROJECT_TYPE }}"
170
172
 
171
- # GitHub outputs 설정
173
+ # Set GitHub outputs
172
174
  echo "version=$VERSION" >> $GITHUB_OUTPUT
173
175
  echo "version_code=$VERSION_CODE" >> $GITHUB_OUTPUT
174
176
  echo "project_type=${{ env.PROJECT_TYPE }}" >> $GITHUB_OUTPUT
175
177
 
176
- # 환경변수로도 설정 (스크립트에서 사용)
178
+ # Also set as environment variables (used by scripts)
177
179
  echo "VERSION=$VERSION" >> $GITHUB_ENV
178
180
  echo "VERSION_CODE=$VERSION_CODE" >> $GITHUB_ENV
179
181
  echo "TODAY=$(date '+%Y-%m-%d')" >> $GITHUB_ENV
180
182
  echo "TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')" >> $GITHUB_ENV
181
183
  echo "PROJECT_TYPE=${{ env.PROJECT_TYPE }}" >> $GITHUB_ENV
182
184
 
183
- - name: 릴리즈 노트 생성
185
+ - name: Generate release notes
184
186
  id: release_notes
185
- working-directory: ${{ github.workspace }} # CHANGELOG.json·changelog_manager.py·final_release_notes.txt(upload 짝)는 레포 루트 기준
187
+ working-directory: ${{ github.workspace }} # CHANGELOG.json, changelog_manager.py and final_release_notes.txt (paired with the upload) are relative to the repo root
186
188
  run: |
189
+ m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
187
190
  VERSION="${{ steps.current_version.outputs.version }}"
188
191
 
189
192
  if [ -f "CHANGELOG.json" ]; then
190
- echo "📄 CHANGELOG.json에서 v$VERSION 릴리즈 노트 추출 중..."
191
- # CHANGELOG.md 생성
193
+ m flutter_a.extracting_v_release_notes_changelog version="$VERSION"
194
+ # Generate CHANGELOG.md
192
195
  python3 ./.github/scripts/changelog_manager.py generate-md
193
196
 
194
- # changelog_manager.py export로 릴리즈 노트 추출
197
+ # Extract the release notes with changelog_manager.py export
195
198
  python3 ./.github/scripts/changelog_manager.py export --version $VERSION --output final_release_notes.txt
196
199
 
197
200
  if [ -s final_release_notes.txt ]; then
198
- echo "✅ 릴리즈 노트 추출 성공!"
199
- echo "📋 추출된 릴리즈 노트:"
201
+ m flutter_a.release_notes_extracted
202
+ m flutter_a.extracted_release_notes
200
203
  echo "----------------------------------------"
201
204
  cat final_release_notes.txt
202
205
  echo "----------------------------------------"
203
206
  echo "RELEASE_NOTES_FOUND=true" >> $GITHUB_ENV
204
207
  else
205
- echo "❌ 릴리즈 노트 추출 실패"
208
+ m flutter_a.failed_extract_release_notes
206
209
  echo "RELEASE_NOTES_FOUND=false" >> $GITHUB_ENV
207
- echo "v$VERSION 업데이트" > final_release_notes.txt
210
+ m flutter_a.default_release_note version="$VERSION" > final_release_notes.txt
208
211
  fi
209
212
  else
210
- echo "⚠️ CHANGELOG.json 파일이 없습니다. 기본 릴리즈 노트를 사용합니다."
213
+ m flutter_a.changelog_json_not_found_using
211
214
  echo "RELEASE_NOTES_FOUND=false" >> $GITHUB_ENV
212
- echo "v$VERSION 업데이트" > final_release_notes.txt
215
+ m flutter_a.default_release_note version="$VERSION" > final_release_notes.txt
213
216
  fi
214
217
 
215
218
  - name: Upload release notes
@@ -219,8 +222,8 @@ jobs:
219
222
  path: final_release_notes.txt
220
223
  retention-days: 1
221
224
 
222
- # 프로젝트 파일들을 아티팩트로 업로드
223
- # .env는 보안상 아티팩트에 포함하지 않고, 각 job에서 secrets로 재생성
225
+ # Upload the project files as an artifact
226
+ # .env is not included in the artifact for security; each job recreates it from secrets
224
227
  - name: Upload project files
225
228
  uses: actions/upload-artifact@v7
226
229
  with:
@@ -232,7 +235,7 @@ jobs:
232
235
  retention-days: 1
233
236
 
234
237
  build-android:
235
- name: Android AAB 빌드
238
+ name: Build Android AAB
236
239
  runs-on: ubuntu-latest
237
240
  needs: prepare-build
238
241
  defaults:
@@ -255,7 +258,7 @@ jobs:
255
258
  name: project-files
256
259
  path: ${{ env.FLUTTER_PROJECT_DIR }}
257
260
 
258
- # 환경변수 준비 (보안을 위해 아티팩트가 아닌 시크릿에서 생성) — ENV_MODE=dotenv면 .env 파일, dart-define이면 임시 파일
261
+ # Prepare env vars (created from secrets rather than the artifact, for security) - a .env file when ENV_MODE=dotenv, a temp file for dart-define
259
262
  - name: Prepare env file
260
263
  env:
261
264
  ENV_CONTENT: ${{ secrets.ENV_FILE || secrets.ENV }}
@@ -277,35 +280,37 @@ jobs:
277
280
  RELEASE_KEY_ALIAS: ${{ secrets.RELEASE_KEY_ALIAS }}
278
281
  RELEASE_KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}
279
282
  run: |
280
- # 빈 Secret으로 빈 keystore를 만들면 어떤 키로 서명됐는지 알 수 없거나 뒤 단계에서 엉뚱한 오류로 끝난다
283
+ m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
284
+ # An empty keystore built from an empty Secret leaves it unclear which key signed the build, or ends in a misleading error in a later step
281
285
  MISSING=""
282
286
  for name in RELEASE_KEYSTORE_BASE64 RELEASE_KEYSTORE_PASSWORD RELEASE_KEY_ALIAS RELEASE_KEY_PASSWORD; do
283
287
  [ -n "${!name}" ] || MISSING="$MISSING $name"
284
288
  done
285
289
  if [ -n "$MISSING" ]; then
286
- echo "::error::서명 Secret이 비어 있습니다:$MISSING (워크플로우 상단 주석 참고)"
290
+ echo "::error::$(m flutter_a.signing_secrets_empty missing="$MISSING")"
287
291
  exit 1
288
292
  fi
289
293
  mkdir -p android/app/keystore
290
294
  printf '%s' "$RELEASE_KEYSTORE_BASE64" | base64 -d > android/app/keystore/key.jks
291
295
  if [ ! -s android/app/keystore/key.jks ]; then
292
- echo "::error::RELEASE_KEYSTORE_BASE64를 디코딩한 keystore가 비어 있습니다"
296
+ echo "::error::$(m flutter_a.keystore_decoded_empty)"
293
297
  exit 1
294
298
  fi
295
- echo "✅ Release Keystore 생성 완료"
299
+ m flutter_a.release_keystore_created
296
300
  ls -la android/app/keystore/
297
301
 
298
302
  - name: Create key.properties
299
303
  run: |
304
+ m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
300
305
  cat > android/key.properties << EOF
301
306
  storeFile=app/keystore/key.jks
302
307
  storePassword=${{ secrets.RELEASE_KEYSTORE_PASSWORD }}
303
308
  keyAlias=${{ secrets.RELEASE_KEY_ALIAS }}
304
309
  keyPassword=${{ secrets.RELEASE_KEY_PASSWORD }}
305
310
  EOF
306
- echo "✅ key.properties 생성 완료"
311
+ m flutter_a.key_properties_created
307
312
 
308
- # google-services.json 생성 (선택) — 비어 있으면 빈 파일을 만들지 않는다
313
+ # Create google-services.json (optional) - no empty file is written when the Secret is empty
309
314
  - name: Create google-services.json
310
315
  env:
311
316
  GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }}
@@ -357,55 +362,57 @@ jobs:
357
362
 
358
363
  - name: Configure Android build for release
359
364
  run: |
360
- # build.gradle.kts에 release 서명 설정이 없으면 추가
365
+ m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
366
+ # Add the release signing config to build.gradle.kts if it is missing
361
367
  if ! grep -q "signingConfigs" android/app/build.gradle.kts; then
362
- echo "⚠️ build.gradle.kts에 서명 설정 추가 필요"
363
- # 서명 설정은 이미 되어있다고 가정 (수동으로 미리 설정해야 함)
368
+ m flutter_a.signing_config_must_added_build
369
+ # Assume signing is already configured (it must be set up manually beforehand)
364
370
  fi
365
- echo "✅ Android 빌드 설정 확인 완료"
371
+ m flutter_a.android_build_config_check_complete
366
372
 
367
- # pubspec.yaml은 x.y.z 형식 그대로 유지
368
- # Flutter build 명령어의 --build-name, --build-number 플래그가 pubspec.yaml을 오버라이드함
373
+ # Keep pubspec.yaml in the x.y.z format as is
374
+ # The --build-name and --build-number flags of flutter build override pubspec.yaml
369
375
 
370
376
  - name: Build Android App Bundle (AAB)
371
377
  run: |
378
+ m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
372
379
  VERSION_NAME="${{ needs.prepare-build.outputs.version }}"
373
380
  VERSION_CODE="${{ needs.prepare-build.outputs.version_code }}"
374
381
 
375
382
  echo "=========================================="
376
- echo "🚀 AAB 빌드 시작"
383
+ m flutter_a.starting_aab_build
377
384
  echo "=========================================="
378
- echo "🎯 빌드 버전: $VERSION_NAME"
379
- echo "🎯 빌드 코드: $VERSION_CODE"
385
+ m flutter_a.build_version version_name="$VERSION_NAME"
386
+ m flutter_a.build_code version_code="$VERSION_CODE"
380
387
 
381
- # 입력 검증
388
+ # Validate inputs
382
389
  if [ -z "$VERSION_NAME" ] || [ -z "$VERSION_CODE" ]; then
383
- echo "❌ VERSION_NAME 또는 VERSION_CODE가 비어있습니다!"
390
+ m flutter_a.version_name_or_version_code
384
391
  exit 1
385
392
  fi
386
393
 
387
- # Flutter 환경 정보 출력
388
- echo "🔍 Flutter 환경 정보:"
394
+ # Print Flutter environment info
395
+ m flutter_a.flutter_environment_info
389
396
  flutter --version
390
397
  flutter doctor -v | head -20
391
398
 
392
- # 빌드 디렉토리 정리
393
- echo "🧹 이전 빌드 결과물 정리..."
399
+ # Clean the build directory
400
+ m flutter_a.cleaning_previous_build_output
394
401
  rm -rf build/app/outputs/bundle/release/
395
402
  mkdir -p build/app/outputs/bundle/release/
396
403
 
397
- # Flutter clean 및 pub get
398
- echo "🔄 Flutter clean 및 의존성 재설치..."
404
+ # Flutter clean and pub get
405
+ m flutter_a.running_flutter_clean_reinstalling_dependencies
399
406
  flutter clean
400
407
  flutter pub get
401
408
  if grep -q "build_runner" pubspec.yaml; then
402
409
  dart run build_runner build --delete-conflicting-outputs
403
410
  fi
404
411
 
405
- # local.properties에 버전 정보 추가 (Flutter 플래그가 무시되는 문제 해결)
406
- echo "🔧 local.properties에 버전 정보 설정..."
412
+ # Add version info to local.properties (works around the Flutter flags being ignored)
413
+ m flutter_a.setting_version_info_local_properties
407
414
 
408
- # 기존 local.properties가 있으면 버전 정보 제거
415
+ # Remove existing version info if local.properties exists
409
416
  if [ -f "android/local.properties" ]; then
410
417
  grep -v "flutter.versionName\|flutter.versionCode" android/local.properties > android/local.properties.tmp || true
411
418
  mv android/local.properties.tmp android/local.properties
@@ -413,24 +420,24 @@ jobs:
413
420
  touch android/local.properties
414
421
  fi
415
422
 
416
- # 버전 정보 추가
423
+ # Add version info
417
424
  echo "flutter.versionName=$VERSION_NAME" >> android/local.properties
418
425
  echo "flutter.versionCode=$VERSION_CODE" >> android/local.properties
419
426
 
420
- echo "✅ local.properties 업데이트 완료"
421
- echo "📋 버전 정보: VERSION_NAME=$VERSION_NAME, VERSION_CODE=$VERSION_CODE"
427
+ m flutter_a.local_properties_updated
428
+ m flutter_a.version_info_version_name_version version_name="$VERSION_NAME" version_code="$VERSION_CODE"
422
429
 
423
- # Gradle 성능 최적화 설정
430
+ # Gradle performance tuning
424
431
  export GRADLE_OPTS="-Dorg.gradle.daemon=false -Dorg.gradle.parallel=true -Dorg.gradle.workers.max=4"
425
432
  export JAVA_OPTS="-Xmx4g"
426
- echo "✅ Gradle 최적화 설정 완료"
433
+ m flutter_a.gradle_tuning_applied
427
434
 
428
- # Flutter build 명령어에 버전 정보 전달
429
- # --build-name과 --build-number 플래그가 pubspec.yaml의 version을 오버라이드함
430
- # pubspec.yaml은 x.y.z 형식 유지, VERSION_CODE는 version.yml에서 자동 관리
431
- echo "🔨 Flutter build 실행..."
432
- echo "📋 명령어: flutter build appbundle --release --build-name=$VERSION_NAME --build-number=$VERSION_CODE --verbose"
433
- echo "⏱️ 빌드 시작 시간: $(date '+%Y-%m-%d %H:%M:%S')"
435
+ # Pass the version info to the flutter build command
436
+ # The --build-name and --build-number flags override the version in pubspec.yaml
437
+ # pubspec.yaml stays in x.y.z format; VERSION_CODE is managed automatically in version.yml
438
+ m flutter_a.running_flutter_build
439
+ m flutter_a.command_flutter_build_appbundle_release version_name="$VERSION_NAME" version_code="$VERSION_CODE"
440
+ m flutter_a.build_start_time cmd1="$(date '+%Y-%m-%d %H:%M:%S')"
434
441
 
435
442
  flutter build appbundle \
436
443
  --release \
@@ -442,144 +449,144 @@ jobs:
442
449
  BUILD_EXIT_CODE=$?
443
450
 
444
451
  if [ $BUILD_EXIT_CODE -ne 0 ]; then
445
- echo "❌ Flutter build 실패! Exit code: $BUILD_EXIT_CODE"
446
- echo "🔍 빌드 디렉토리 상태:"
447
- find build/ -name "*.aab" -o -name "*.apk" 2>/dev/null || echo "AAB/APK 파일을 찾을 수 없습니다"
452
+ m flutter_a.flutter_build_failed_exit_code build_exit_code="$BUILD_EXIT_CODE"
453
+ m flutter_a.build_directory_state
454
+ find build/ -name "*.aab" -o -name "*.apk" 2>/dev/null || m flutter_a.aab_apk_not_found
448
455
  exit 1
449
456
  fi
450
457
 
451
- echo "✅ Flutter build 성공!"
458
+ m flutter_a.flutter_build_succeeded
452
459
 
453
- # 빌드 결과 확인
454
- echo "🔍 빌드 결과 확인:"
460
+ # Check the build result
461
+ m flutter_a.checking_build_result
455
462
  ls -lah build/app/outputs/bundle/release/
456
463
 
457
- # AAB 파일 존재 확인
464
+ # Check that the AAB file exists
458
465
  AAB_FILE="build/app/outputs/bundle/release/app-release.aab"
459
466
  if [ ! -f "$AAB_FILE" ]; then
460
- echo "❌ AAB 파일이 생성되지 않았습니다!"
461
- echo "🔍 전체 빌드 디렉토리 내용:"
462
- find build/ -type f -name "*.aab" -o -name "*.apk" 2>/dev/null || echo "AAB/APK 파일을 찾을 수 없습니다"
463
- echo "🔍 outputs 디렉토리 구조:"
464
- find build/app/outputs/ -type f 2>/dev/null || echo "outputs 디렉토리가 없습니다"
467
+ m flutter_a.aab_file_not_created
468
+ m flutter_a.full_build_directory_contents
469
+ find build/ -type f -name "*.aab" -o -name "*.apk" 2>/dev/null || m flutter_a.aab_apk_not_found
470
+ m flutter_a.outputs_directory_structure
471
+ find build/app/outputs/ -type f 2>/dev/null || m flutter_a.outputs_directory_does_not_exist
465
472
  exit 1
466
473
  fi
467
474
 
468
- echo "✅ AAB 파일 생성 확인"
469
- echo "📱 AAB 파일 크기: $(du -h "$AAB_FILE" | cut -f1)"
470
- echo "📋 AAB 파일 정보: $(ls -lah "$AAB_FILE")"
475
+ m flutter_a.aab_file_creation_confirmed
476
+ m flutter_a.aab_file_size cmd1="$(du -h "$AAB_FILE" | cut -f1)"
477
+ m flutter_a.aab_file_info cmd1="$(ls -lah "$AAB_FILE")"
471
478
 
472
- # bundletool 다운로드 및 설치
473
- echo "📦 bundletool 다운로드 중..."
479
+ # Download and install bundletool
480
+ m flutter_a.downloading_bundletool
474
481
  BUNDLETOOL_VERSION="1.15.6"
475
482
  BUNDLETOOL_URL="https://github.com/google/bundletool/releases/download/${BUNDLETOOL_VERSION}/bundletool-all-${BUNDLETOOL_VERSION}.jar"
476
483
 
477
- echo "📋 다운로드 URL: $BUNDLETOOL_URL"
484
+ m flutter_a.download_url bundletool_url="$BUNDLETOOL_URL"
478
485
  wget -q "$BUNDLETOOL_URL" -O bundletool.jar
479
486
 
480
487
  if [ ! -f "bundletool.jar" ]; then
481
- echo "❌ bundletool 다운로드 실패"
482
- echo "🔄 대체 URL로 재시도..."
488
+ m flutter_a.bundletool_download_failed
489
+ m flutter_a.retrying_fallback_url
483
490
  wget -q "https://github.com/google/bundletool/releases/latest/download/bundletool-all-1.15.6.jar" -O bundletool.jar
484
491
 
485
492
  if [ ! -f "bundletool.jar" ]; then
486
- echo "❌ bundletool 다운로드 완전 실패"
493
+ m flutter_a.bundletool_download_failed_completely
487
494
  exit 1
488
495
  fi
489
496
  fi
490
497
 
491
- echo "✅ bundletool 다운로드 완료"
492
- echo "📋 bundletool 파일 크기: $(du -h bundletool.jar | cut -f1)"
498
+ m flutter_a.bundletool_downloaded
499
+ m flutter_a.bundletool_file_size cmd1="$(du -h bundletool.jar | cut -f1)"
493
500
 
494
- # Java 환경 확인
495
- echo "🔍 Java 환경 확인:"
501
+ # Check the Java environment
502
+ m flutter_a.checking_java_environment
496
503
  java -version
497
504
 
498
- # AAB 파일 내부의 실제 버전 정보 확인
499
- # Flutter CLI 플래그로 전달한 VERSION_CODE가 제대로 적용되었는지 검증
505
+ # Check the actual version info inside the AAB file
506
+ # Verify that the VERSION_CODE passed via the Flutter CLI flags was applied correctly
500
507
  echo "=========================================="
501
- echo "🔍 AAB 파일 내부 버전 정보 검증"
508
+ m flutter_a.verifying_version_info_inside_aab
502
509
  echo "=========================================="
503
510
 
504
- # AndroidManifest.xml에서 버전 정보 추출
505
- echo "📋 AAB에서 실제 버전 정보 추출 중..."
506
- echo "📋 실행할 명령어: java -jar bundletool.jar dump manifest --bundle='$AAB_FILE'"
511
+ # Extract the version info from AndroidManifest.xml
512
+ m flutter_a.extracting_actual_version_info_aab
513
+ m flutter_a.command_run_java_jar_bundletool aab_file="$AAB_FILE"
507
514
 
508
515
  MANIFEST_OUTPUT=$(java -jar bundletool.jar dump manifest --bundle="$AAB_FILE" 2>&1)
509
516
  MANIFEST_EXIT_CODE=$?
510
517
 
511
- echo "📋 bundletool 실행 결과 (Exit code: $MANIFEST_EXIT_CODE):"
518
+ m flutter_a.bundletool_result_exit_code manifest_exit_code="$MANIFEST_EXIT_CODE"
512
519
  echo "$MANIFEST_OUTPUT"
513
520
 
514
521
  if [ $MANIFEST_EXIT_CODE -eq 0 ]; then
515
- echo "✅ Manifest 추출 성공"
522
+ m flutter_a.manifest_extracted
516
523
 
517
- # 실제 버전 코드와 버전 이름 추출
524
+ # Extract the actual version code and version name
518
525
  ACTUAL_VERSION_CODE=$(echo "$MANIFEST_OUTPUT" | grep -o 'android:versionCode="[0-9]*"' | grep -o '[0-9]*' | head -1)
519
526
  ACTUAL_VERSION_NAME=$(echo "$MANIFEST_OUTPUT" | grep -o 'android:versionName="[^"]*"' | sed 's/android:versionName="//;s/"//' | head -1)
520
527
 
521
- echo "🎯 버전 정보 비교:"
522
- echo " 예상 VERSION_CODE: '$VERSION_CODE'"
523
- echo " 실제 VERSION_CODE: '$ACTUAL_VERSION_CODE'"
524
- echo " 예상 VERSION_NAME: '$VERSION_NAME'"
525
- echo " 실제 VERSION_NAME: '$ACTUAL_VERSION_NAME'"
528
+ m flutter_a.version_info_comparison
529
+ m flutter_a.expected_version_code version_code="$VERSION_CODE"
530
+ m flutter_a.actual_version_code actual_version_code="$ACTUAL_VERSION_CODE"
531
+ m flutter_a.expected_version_name version_name="$VERSION_NAME"
532
+ m flutter_a.actual_version_name actual_version_name="$ACTUAL_VERSION_NAME"
526
533
 
527
- # VERSION_CODE 검증 - version.yml에서 관리되는 단순 증가 번호
534
+ # Verify VERSION_CODE - a simple incrementing number managed in version.yml
528
535
  if [ -z "$ACTUAL_VERSION_CODE" ]; then
529
- echo "❌ 치명적 오류: AAB에서 VERSION_CODE를 추출할 수 없습니다!"
530
- echo "🔍 전체 Manifest 내용:"
536
+ m flutter_a.fatal_error_version_code_could
537
+ m flutter_a.full_manifest_contents
531
538
  echo "$MANIFEST_OUTPUT"
532
539
  exit 1
533
540
  elif [ "$ACTUAL_VERSION_CODE" != "$VERSION_CODE" ]; then
534
- echo "❌ 치명적 오류: AAB의 VERSION_CODE가 예상과 다릅니다!"
535
- echo " 이는 Google Play에서 '이미 사용된 버전 코드' 오류를 발생시킵니다."
541
+ m flutter_a.fatal_error_version_code_aab
542
+ m flutter_a.google_play_would_reject_version
536
543
  echo ""
537
- echo "🔍 디버깅 정보:"
538
- echo " version.yml의 VERSION_CODE: $VERSION_CODE"
539
- echo " AAB 파일 내부의 VERSION_CODE: $ACTUAL_VERSION_CODE"
544
+ m flutter_a.debugging_info
545
+ m flutter_a.version_code_version_yml version_code="$VERSION_CODE"
546
+ m flutter_a.version_code_inside_aab_file actual_version_code="$ACTUAL_VERSION_CODE"
540
547
  echo ""
541
- echo " Flutter build 명령어에 전달된 플래그:"
548
+ m flutter_a.flags_passed_flutter_build_command
542
549
  echo " --build-name='$VERSION_NAME'"
543
550
  echo " --build-number='$VERSION_CODE'"
544
551
  echo ""
545
- echo " 전체 Manifest 내용:"
552
+ m flutter_a.full_manifest_contents_2
546
553
  echo "$MANIFEST_OUTPUT" | grep -E "versionCode|versionName|package"
547
554
  exit 1
548
555
  else
549
- echo "✅ VERSION_CODE 검증 성공: $ACTUAL_VERSION_CODE"
556
+ m flutter_a.version_code_check_passed actual_version_code="$ACTUAL_VERSION_CODE"
550
557
  fi
551
558
 
552
- # 버전 이름도 확인 (경고만)
559
+ # Check the version name too (warning only)
553
560
  if [ -z "$ACTUAL_VERSION_NAME" ]; then
554
- echo "⚠️ 경고: AAB에서 VERSION_NAME을 추출할 수 없습니다"
561
+ m flutter_a.warning_version_name_could_not
555
562
  elif [ "$ACTUAL_VERSION_NAME" != "$VERSION_NAME" ]; then
556
- echo "⚠️ 경고: VERSION_NAME이 예상과 다릅니다 (치명적이지 않음)"
557
- echo " 예상: '$VERSION_NAME', 실제: '$ACTUAL_VERSION_NAME'"
563
+ m flutter_a.warning_version_name_differs_expected
564
+ m flutter_a.expected_actual version_name="$VERSION_NAME" actual_version_name="$ACTUAL_VERSION_NAME"
558
565
  else
559
- echo "✅ VERSION_NAME 검증 성공: $ACTUAL_VERSION_NAME"
566
+ m flutter_a.version_name_check_passed actual_version_name="$ACTUAL_VERSION_NAME"
560
567
  fi
561
568
 
562
569
  else
563
- echo "❌ bundletool로 Manifest 추출 실패"
564
- echo "🔄 대체 방법으로 검증 시도..."
570
+ m flutter_a.failed_extract_manifest_bundletool
571
+ m flutter_a.trying_verify_another_way
565
572
 
566
- # unzip으로 직접 확인 시도
567
- echo "📋 unzip을 사용한 직접 추출 시도..."
573
+ # Try checking directly with unzip
574
+ m flutter_a.trying_direct_extraction_unzip
568
575
  UNZIP_OUTPUT=$(unzip -p "$AAB_FILE" base/manifest/AndroidManifest.xml 2>/dev/null | strings | grep -E "versionCode|versionName")
569
576
 
570
577
  if [ -n "$UNZIP_OUTPUT" ]; then
571
- echo "✅ unzip으로 버전 정보 추출 성공:"
578
+ m flutter_a.version_info_extracted_unzip
572
579
  echo "$UNZIP_OUTPUT"
573
580
  else
574
- echo "❌ unzip을 사용한 직접 추출도 실패"
575
- echo "⚠️ AAB 검증을 건너뛰고 계속 진행합니다."
581
+ m flutter_a.direct_extraction_unzip_failed_too
582
+ m flutter_a.skipping_aab_verification_continuing
576
583
  fi
577
584
  fi
578
585
 
579
586
  echo "=========================================="
580
- echo "✅ AAB 빌드 및 검증 완료"
581
- echo "🎯 최종 AAB: $AAB_FILE"
582
- echo "📱 파일 크기: $(du -h "$AAB_FILE" | cut -f1)"
587
+ m flutter_a.aab_build_verification_complete
588
+ m flutter_a.final_aab aab_file="$AAB_FILE"
589
+ m flutter_a.file_size cmd1="$(du -h "$AAB_FILE" | cut -f1)"
583
590
  echo "=========================================="
584
591
 
585
592
  - name: Upload AAB artifact
@@ -590,7 +597,7 @@ jobs:
590
597
  retention-days: 1
591
598
 
592
599
  deploy-firebase:
593
- name: Firebase App Distribution 배포
600
+ name: Deploy to Firebase App Distribution
594
601
  runs-on: ubuntu-latest
595
602
  needs: [prepare-build, build-android]
596
603
 
@@ -617,18 +624,19 @@ jobs:
617
624
  env:
618
625
  SERVICE_ACCOUNT_BASE64: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_JSON_BASE64 }}
619
626
  run: |
627
+ m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
620
628
  if [ -z "$SERVICE_ACCOUNT_BASE64" ]; then
621
- echo "::error::FIREBASE_SERVICE_ACCOUNT_JSON_BASE64 Secret이 비어 있습니다"
629
+ echo "::error::$(m flutter_a.firebase_service_account_json_base64)"
622
630
  exit 1
623
631
  fi
624
632
  printf '%s' "$SERVICE_ACCOUNT_BASE64" | base64 --decode > firebase-service-account.json
625
- echo "✅ Firebase 서비스 계정 JSON 파일 생성 완료"
633
+ m flutter_a.firebase_service_account_json_file
626
634
 
627
- # Firebase App Distribution release notes 길이 제한 (안전망)
635
+ # Length limit for Firebase App Distribution release notes (safety net)
628
636
  - name: Truncate release notes
629
637
  run: |
630
638
  if [ -f "final_release_notes.txt" ]; then
631
- # Firebase App Distribution release notes 길이 제한 안전망 (4000자)
639
+ # Safety net for the Firebase App Distribution release notes length limit (4000 characters)
632
640
  python3 ./.github/scripts/truncate_release_notes.py final_release_notes.txt 4000 char
633
641
  fi
634
642
 
@@ -642,7 +650,7 @@ jobs:
642
650
  file: ${{ env.FLUTTER_PROJECT_DIR }}/build/app/outputs/bundle/release/app-release.aab
643
651
  releaseNotesFile: final_release_notes.txt
644
652
 
645
- # Firebase 인증 파일 삭제 (보안)
653
+ # Delete the Firebase credentials file (security)
646
654
  - name: Cleanup Firebase credentials
647
655
  if: always()
648
656
  run: rm -f firebase-service-account.json
@@ -650,17 +658,19 @@ jobs:
650
658
  - name: Notify Firebase Upload Success
651
659
  if: success()
652
660
  run: |
653
- echo "✅ Firebase App Distribution 배포 성공!"
654
- echo "버전: ${{ needs.prepare-build.outputs.version }} (${{ needs.prepare-build.outputs.version_code }})"
655
- echo "커밋: ${{ github.sha }}"
661
+ m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
662
+ m flutter_a.firebase_app_distribution_deployment_succeeded
663
+ m flutter_a.version version="${{ needs.prepare-build.outputs.version }}" version_code="${{ needs.prepare-build.outputs.version_code }}"
664
+ m flutter_a.commit sha="${{ github.sha }}"
656
665
  echo ""
657
- echo "📱 테스터 확인 방법:"
658
- echo "1. Firebase App Tester 앱 실행"
659
- echo "2. 앱 선택"
660
- echo "3. 최신 빌드 다운로드"
666
+ m flutter_a.how_testers_check_build
667
+ m flutter_a.launch_firebase_app_tester_app
668
+ m flutter_a.select_app
669
+ m flutter_a.download_latest_build
661
670
 
662
671
  - name: Notify on Failure
663
672
  if: failure()
664
673
  run: |
665
- echo "❌ Firebase App Distribution 배포 실패!"
666
- echo "로그를 확인해주세요."
674
+ m() { (cd "$GITHUB_WORKSPACE" && python3 .github/scripts/messages.py get "$@"); }
675
+ m flutter_a.firebase_app_distribution_deployment_failed
676
+ m flutter_a.please_check_logs