project-auto-wizard 0.12.0 → 0.12.1

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 (78) hide show
  1. package/README.md +3 -7
  2. package/package.json +1 -1
  3. package/payload/config/breaking-changes.json +1 -1
  4. package/payload/scripts/__pycache__/changelog_manager.cpython-314.pyc +0 -0
  5. package/payload/scripts/__pycache__/issue_helper.cpython-314.pyc +0 -0
  6. package/payload/scripts/__pycache__/version_manager.cpython-314.pyc +0 -0
  7. package/payload/scripts/changelog_manager.py +1 -1
  8. package/payload/scripts/version_manager.py +2 -2
  9. package/payload/version.yml.template +0 -2
  10. package/payload/workflows/common/PROJECT-COMMON-AI-PR-SUMMARY.yaml +0 -3
  11. package/payload/workflows/common/PROJECT-COMMON-AUTO-CHANGELOG-CONTROL.yaml +1 -4
  12. package/payload/workflows/common/PROJECT-COMMON-ISSUE-HELPER.yaml +3 -6
  13. package/payload/workflows/common/PROJECT-COMMON-README-VERSION-UPDATE.yaml +0 -12
  14. package/payload/workflows/common/PROJECT-COMMON-RELEASE-PUBLISH.yaml +2 -5
  15. package/payload/workflows/common/PROJECT-COMMON-VERSION-CONTROL.yaml +3 -7
  16. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-FIREBASE-CICD.yaml +7 -34
  17. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-PLAYSTORE-CICD.yaml +2 -25
  18. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-SELFHOSTED-CICD.yaml +2 -20
  19. package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-TEST-APK.yaml +5 -30
  20. package/payload/workflows/flutter/PROJECT-FLUTTER-APP-BUILD-TRIGGER.yaml +0 -4
  21. package/payload/workflows/flutter/PROJECT-FLUTTER-CI.yaml +7 -51
  22. package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TEST-TESTFLIGHT.yaml +5 -29
  23. package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TESTFLIGHT.yaml +9 -29
  24. package/payload/workflows/go/PROJECT-GO-CI.yaml +5 -28
  25. package/payload/workflows/go/PROJECT-GO-PR-PREVIEW.yaml +19 -99
  26. package/payload/workflows/go/PROJECT-GO-SIMPLE-CICD.yaml +18 -89
  27. package/payload/workflows/next/PROJECT-NEXT-CI.yaml +11 -41
  28. package/payload/workflows/next/PROJECT-NEXT-CICD.yaml +9 -45
  29. package/payload/workflows/python/PROJECT-PYTHON-CI.yaml +1 -27
  30. package/payload/workflows/python/PROJECT-PYTHON-PR-PREVIEW.yaml +14 -97
  31. package/payload/workflows/python/PROJECT-PYTHON-SIMPLE-CICD.yaml +14 -92
  32. package/payload/workflows/react/PROJECT-REACT-CI.yaml +11 -40
  33. package/payload/workflows/react/PROJECT-REACT-CICD.yaml +9 -43
  34. package/payload/workflows/spring/{nexus/PROJECT-SPRING-NEXUS-CI.yml → PROJECT-SPRING-CI.yml} +2 -25
  35. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-NGINX-CICD.yaml +19 -63
  36. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-TRAEFIK-CICD.yaml +19 -59
  37. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-PR-PREVIEW.yaml +23 -86
  38. package/payload/workflows/spring/server-deploy/PROJECT-SPRING-SIMPLE-CICD.yaml +20 -80
  39. package/src/cli/args.js +1 -15
  40. package/src/cli/help.js +0 -2
  41. package/src/commands/doctor.js +5 -5
  42. package/src/commands/dry-run.js +1 -1
  43. package/src/commands/full.js +9 -10
  44. package/src/commands/interactive-flutter.js +1 -1
  45. package/src/commands/interactive.js +25 -46
  46. package/src/commands/purge.js +2 -2
  47. package/src/commands/status.js +4 -6
  48. package/src/commands/uninstall.js +3 -4
  49. package/src/context.js +4 -6
  50. package/src/core/assets.js +2 -2
  51. package/src/core/baseline.js +1 -1
  52. package/src/core/branches.js +3 -3
  53. package/src/core/breaking-check.js +1 -1
  54. package/src/core/breaking.js +1 -1
  55. package/src/core/copy/flutter-app.js +2 -2
  56. package/src/core/copy/gitignore.js +8 -8
  57. package/src/core/copy/workflows.js +24 -69
  58. package/src/core/deploy-style.js +2 -2
  59. package/src/core/detect-fs.js +11 -11
  60. package/src/core/detect.js +7 -7
  61. package/src/core/flutter-options.js +1 -1
  62. package/src/core/installed-stores.js +1 -1
  63. package/src/core/logger.js +1 -1
  64. package/src/core/paths-resolve.js +1 -1
  65. package/src/core/removal-plan.js +4 -4
  66. package/src/core/verify.js +3 -3
  67. package/src/core/version-yml.js +17 -33
  68. package/src/core/wizard-env.js +4 -4
  69. package/src/index.js +12 -14
  70. package/src/ui/banner.js +2 -2
  71. package/src/ui/env-plan.js +10 -16
  72. package/src/ui/prompts.js +9 -14
  73. package/src/ui/status-cards.js +10 -12
  74. package/src/ui/summary.js +9 -9
  75. package/payload/workflows/common/secret-backup/PROJECT-COMMON-SECRET-FILE-UPLOAD.yaml +0 -210
  76. package/payload/workflows/spring/nexus/PROJECT-SPRING-GITHUB-PACKAGES-PUBLISH.yml +0 -92
  77. package/payload/workflows/spring/nexus/PROJECT-SPRING-NEXUS-PUBLISH.yml +0 -70
  78. package/src/core/options-ask.js +0 -102
@@ -1,14 +1,7 @@
1
1
  # project-auto-wizard:managed-workflow
2
- # ===================================================================
3
- # Spring Nexus CI 워크플로우
4
- # ===================================================================
5
- #
6
- # 🔑 필수 GitHub Secrets
7
- # ===================================================================
8
- # GRADLE_PROPERTIES: gradle.properties 파일 내용 (Nexus 인증 정보 포함)
9
- # ===================================================================
2
+ # Spring CI 워크플로우
10
3
 
11
- name: PROJECT-SPRING-NEXUS-CI
4
+ name: PROJECT-SPRING-CI
12
5
 
13
6
  on:
14
7
  pull_request:
@@ -30,9 +23,7 @@ env:
30
23
  PROJECT_PATH: "." # @wizard auto:project-path
31
24
 
32
25
  jobs:
33
- # ===================================================================
34
26
  # 변경 감지 (모노레포에서 이 프로젝트 경로가 바뀌었는지 판별)
35
- # ===================================================================
36
27
  changes:
37
28
  name: 변경 감지
38
29
  runs-on: ubuntu-latest
@@ -76,10 +67,6 @@ jobs:
76
67
  uses: gradle/wrapper-validation-action@v2
77
68
  continue-on-error: true
78
69
 
79
- - name: Create gradle.properties from secret
80
- run: |
81
- echo -e "${{ secrets.GRADLE_PROPERTIES }}" > gradle.properties
82
-
83
70
  - name: Setup Gradle
84
71
  uses: gradle/actions/setup-gradle@v4
85
72
  with:
@@ -119,30 +106,25 @@ jobs:
119
106
  id: report
120
107
  if: always()
121
108
  run: |
122
- # 빌드 상태 확인 (exit code 기반)
123
109
  COMPILE_STATUS="✅ 성공"
124
110
  TEST_STATUS="✅ 성공"
125
111
  BUILD_STATUS="✅ 성공"
126
112
 
127
- # 컴파일 상태 확인
128
113
  COMPILE_EXIT_CODE="${{ steps.compile.outputs.compile_exit_code }}"
129
114
  if [ "$COMPILE_EXIT_CODE" != "0" ] && [ "$COMPILE_EXIT_CODE" != "" ]; then
130
115
  COMPILE_STATUS="❌ 실패"
131
116
  fi
132
117
 
133
- # 테스트 상태 확인
134
118
  TEST_EXIT_CODE="${{ steps.test.outputs.test_exit_code }}"
135
119
  if [ "$TEST_EXIT_CODE" != "0" ] && [ "$TEST_EXIT_CODE" != "" ]; then
136
120
  TEST_STATUS="❌ 실패"
137
121
  fi
138
122
 
139
- # 빌드 상태 확인
140
123
  BUILD_EXIT_CODE="${{ steps.build.outputs.build_exit_code }}"
141
124
  if [ "$BUILD_EXIT_CODE" != "0" ] && [ "$BUILD_EXIT_CODE" != "" ]; then
142
125
  BUILD_STATUS="❌ 실패"
143
126
  fi
144
127
 
145
- # 전체 빌드 상태
146
128
  OVERALL_STATUS="✅ 성공"
147
129
  if [ "$COMPILE_EXIT_CODE" != "0" ] || [ "$TEST_EXIT_CODE" != "0" ] || [ "$BUILD_EXIT_CODE" != "0" ]; then
148
130
  OVERALL_STATUS="❌ 실패"
@@ -157,7 +139,6 @@ jobs:
157
139
  id: errors
158
140
  if: always()
159
141
  run: |
160
- # 컴파일 에러 추출
161
142
  if [ -f compile_output.txt ] && [ "${{ steps.compile.outputs.compile_exit_code }}" != "0" ]; then
162
143
  echo "compile_errors<<EOF" >> $GITHUB_OUTPUT
163
144
  echo "## 🚨 컴파일 에러" >> $GITHUB_OUTPUT
@@ -168,7 +149,6 @@ jobs:
168
149
  echo "EOF" >> $GITHUB_OUTPUT
169
150
  fi
170
151
 
171
- # 테스트 에러 추출
172
152
  if [ -f test_output.txt ] && [ "${{ steps.test.outputs.test_exit_code }}" != "0" ]; then
173
153
  echo "test_errors<<EOF" >> $GITHUB_OUTPUT
174
154
  echo "## 🧪 테스트 실패" >> $GITHUB_OUTPUT
@@ -179,7 +159,6 @@ jobs:
179
159
  echo "EOF" >> $GITHUB_OUTPUT
180
160
  fi
181
161
 
182
- # 빌드 에러 추출
183
162
  if [ -f build_output.txt ] && [ "${{ steps.build.outputs.build_exit_code }}" != "0" ]; then
184
163
  echo "build_errors<<EOF" >> $GITHUB_OUTPUT
185
164
  echo "## 📦 빌드 에러" >> $GITHUB_OUTPUT
@@ -347,9 +326,7 @@ jobs:
347
326
  echo "❌ 빌드가 실패했습니다. 위의 에러 메시지를 확인해주세요."
348
327
  exit 1
349
328
 
350
- # ===================================================================
351
329
  # CI Gate (required check로 등록할 단일 job)
352
- # ===================================================================
353
330
  ci-gate:
354
331
  name: CI Gate
355
332
  if: ${{ always() }}
@@ -1,7 +1,5 @@
1
1
  # project-auto-wizard:managed-workflow
2
- # ===================================================================
3
2
  # Spring Boot 무중단 배포 (Nginx Blue-Green, SSH + Docker)
4
- # ===================================================================
5
3
  #
6
4
  # deploy 브랜치 푸시 시 Docker 이미지를 빌드하고
7
5
  # nginx config 의 proxy_pass 포트 토글로 Blue-Green 무중단 배포합니다.
@@ -10,9 +8,7 @@
10
8
  # 기본 배포는 PROJECT-SPRING-SIMPLE-CICD.yaml 입니다.
11
9
  # 전환하려면 아래 push.branches 주석 해제 + SIMPLE-CICD 의 push 트리거 주석 처리.
12
10
  #
13
- # ===================================================================
14
- # 🔑 필수 GitHub Secrets
15
- # ===================================================================
11
+ # 필수 GitHub Secrets
16
12
  # APPLICATION_PROD_YML (선택): application-prod.yml 내용
17
13
  # DOCKERHUB_USERNAME: DockerHub 사용자명
18
14
  # DOCKERHUB_TOKEN: DockerHub 액세스 토큰
@@ -20,34 +16,32 @@
20
16
  # SERVER_USER: SSH 사용자명
21
17
  # SERVER_PASSWORD: SSH 비밀번호 (SSH_AUTH_METHOD=password일 때)
22
18
  # SSH_KEY: SSH 개인키 .pem 내용 (SSH_AUTH_METHOD=key일 때, AWS EC2 등)
23
- # ===================================================================
24
19
  #
25
- # 🔧 환경변수 설정 (env 섹션에서 설정)
26
- # ===================================================================
20
+ # 환경변수 설정 (env 섹션에서 설정)
27
21
  #
28
- # 🌐 포트 및 컨테이너:
22
+ # 포트 및 컨테이너:
29
23
  # PROJECT_NAME: 프로젝트명 (컨테이너/이미지 이름)
30
24
  # SERVICE_DOMAIN: 외부 도메인 (nginx server_name 과 일치)
31
25
  # CONTAINER_INTERNAL_PORT: Spring Boot 내부 포트 (기본: 8080)
32
26
  # BLUE_PORT: Blue 호스트 노출 포트 (기본: 8080)
33
27
  # GREEN_PORT: Green 호스트 노출 포트 (기본: 8081)
34
28
  #
35
- # 🔧 Nginx:
29
+ # Nginx:
36
30
  # NGINX_RP_CONF: nginx 역방향 프록시 config 파일 경로
37
31
  # NGINX_BACKUP_DIR: nginx config 백업 디렉토리
38
32
  # NGINX_BACKUP_KEEP: 백업 보존 개수 (기본: 10)
39
33
  #
40
- # 📦 볼륨/스토리지:
34
+ # 볼륨/스토리지:
41
35
  # ENABLE_VOLUME_MOUNT: 볼륨 마운트 여부 (true/false)
42
36
  # VOLUME_HOST_PATH: 호스트 볼륨 경로
43
37
  # VOLUME_CONTAINER_PATH: 컨테이너 내부 마운트 경로
44
38
  #
45
- # 🔌 SSH 연결:
39
+ # SSH 연결:
46
40
  # SSH_PORT: SSH 포트 (기본: 2022)
47
41
  # SSH_COMMAND_TIMEOUT: 명령 타임아웃 (기본: 600s)
48
42
  # SSH_CONNECTION_TIMEOUT: 연결 타임아웃 (기본: 60s)
49
43
  #
50
- # ⏱️ 헬스체크:
44
+ # 헬스체크:
51
45
  # HEALTHCHECK_PATH: HTTP 경로 (기본: /actuator/health, fallback: /)
52
46
  # HEALTHCHECK_MAX_RETRIES: 컨테이너 헬스체크 최대 횟수 (기본: 120)
53
47
  # HEALTHCHECK_RETRY_INTERVAL: 재시도 간격 초 (기본: 1)
@@ -55,19 +49,16 @@
55
49
  # DOMAIN_CHECK_INTERVAL: 도메인 검증 간격 초 (기본: 2)
56
50
  # IN_FLIGHT_WAIT: old 컨테이너 제거 전 대기 초 (기본: 5)
57
51
  #
58
- # 💡 사전 조건:
52
+ # 사전 조건:
59
53
  # - 서버에 nginx 설치 + sites-enabled config 존재
60
54
  # - 해당 config 의 server 블록에 다음 라인 존재:
61
55
  # server_name ${SERVICE_DOMAIN};
62
56
  # proxy_pass http://127.0.0.1:${BLUE_PORT}; # 또는 ${GREEN_PORT}
63
57
  # - SSH 사용자가 sudo 로 nginx -t / reload, docker 명령 실행 가능
64
- # ===================================================================
65
58
 
66
59
  name: PROJECT-SPRING-NONSTOP-NGINX-CICD
67
60
 
68
- # ===================================================================
69
61
  # 트리거 설정
70
- # ===================================================================
71
62
  # deploy 브랜치 push 자동 트리거는 주석 처리되어 있습니다.
72
63
  # 본 워크플로우로 전환하려면 아래 push.branches 주석을 해제하세요.
73
64
  on:
@@ -76,51 +67,48 @@ on:
76
67
  # - {{MAIN_BRANCH}}
77
68
  workflow_dispatch:
78
69
 
79
- # ===================================================================
80
- # 환경 변수 설정
81
- # ===================================================================
82
70
  env:
83
- # 🔧 프로젝트 설정 - 실제 프로젝트명으로 변경하세요
71
+ # 프로젝트 설정 - 실제 프로젝트명으로 변경하세요
84
72
  PROJECT_NAME: "__PROJECT_NAME__" # @wizard ask:@repo
85
73
  SERVICE_DOMAIN: "__SERVICE_DOMAIN__" # @wizard ask:example.com
86
74
 
87
- # ☁️ Spring Boot 설정
75
+ # Spring Boot 설정
88
76
  SPRING_PROFILE: "prod"
89
77
  JAVA_VERSION: "__JAVA_VERSION__" # @wizard ask:@jdk
90
78
  GRADLE_OPTS: "-Dspring.profiles.active=prod"
91
79
 
92
- # 📁 경로 설정
80
+ # 경로 설정
93
81
  APPLICATION_YML_DIR: "__APPLICATION_YML_DIR__" # @wizard auto:spring-app-yml-dir
94
82
  DOCKERFILE_PATH: "./Dockerfile"
95
83
 
96
- # 🌐 포트 및 컨테이너 설정
84
+ # 포트 및 컨테이너 설정
97
85
  # BLUE/GREEN은 서버에서 번갈아 뜨는 두 컨테이너의 호스트 포트다 — 다른 서비스와 겹치면 배포가 실패한다.
98
86
  CONTAINER_INTERNAL_PORT: "8080"
99
87
  BLUE_PORT: "__BLUE_PORT__" # @wizard ask:8080
100
88
  GREEN_PORT: "__GREEN_PORT__" # @wizard ask:8081
101
89
 
102
- # 🔧 Nginx 설정
90
+ # Nginx 설정
103
91
  # NGINX_RP_CONF 경로가 틀리면 무중단 전환(proxy_pass 포트 토글) 자체가 동작하지 않는다.
104
92
  NGINX_RP_CONF: "__NGINX_RP_CONF__" # @wizard ask:/etc/nginx/sites-enabled/__PROJECT_NAME__.conf
105
93
  NGINX_BACKUP_DIR: "__NGINX_BACKUP_DIR__" # @wizard ask:/volume1/projects/nginx/backups
106
94
  NGINX_BACKUP_KEEP: "10"
107
95
 
108
- # 📦 볼륨 마운트 설정
96
+ # 볼륨 마운트 설정
109
97
  ENABLE_VOLUME_MOUNT: "false" # @wizard ask:false
110
98
  VOLUME_HOST_PATH: "/volume1/projects/__PROJECT_NAME__" # @wizard ask:/volume1/projects/__PROJECT_NAME__
111
99
  VOLUME_CONTAINER_PATH: "/app" # @wizard ask:/app
112
100
 
113
- # 🔐 SSH 인증 방식: "password"(Synology·일반 서버) | "key"(AWS EC2·.pem)
101
+ # SSH 인증 방식: "password"(Synology·일반 서버) | "key"(AWS EC2·.pem)
114
102
  # password → SERVER_PASSWORD secret 사용
115
103
  # key → SSH_KEY secret 사용 (.pem 파일 전체 내용을 secret 값으로)
116
104
  SSH_AUTH_METHOD: "password" # @wizard ask:password
117
105
 
118
- # 🔌 SSH 연결 설정
106
+ # SSH 연결 설정
119
107
  SSH_PORT: "__SSH_PORT__" # @wizard ask:2022
120
108
  SSH_COMMAND_TIMEOUT: "600s"
121
109
  SSH_CONNECTION_TIMEOUT: "60s"
122
110
 
123
- # ⏱️ 헬스체크 설정
111
+ # 헬스체크 설정
124
112
  HEALTHCHECK_PATH: "/actuator/health"
125
113
  HEALTHCHECK_MAX_RETRIES: "120"
126
114
  HEALTHCHECK_RETRY_INTERVAL: "1"
@@ -129,9 +117,7 @@ env:
129
117
  IN_FLIGHT_WAIT: "5"
130
118
 
131
119
  jobs:
132
- # ===================================================================
133
120
  # 빌드 작업
134
- # ===================================================================
135
121
  build:
136
122
  name: Spring Boot 애플리케이션 빌드
137
123
  runs-on: ubuntu-latest
@@ -193,9 +179,7 @@ jobs:
193
179
  rm -rf /tmp/.buildx-cache
194
180
  mv /tmp/.buildx-cache-new /tmp/.buildx-cache
195
181
 
196
- # ===================================================================
197
182
  # 배포 작업 (Blue-Green 무중단)
198
- # ===================================================================
199
183
  deploy:
200
184
  name: Blue-Green 무중단 배포
201
185
  needs: build
@@ -241,7 +225,7 @@ jobs:
241
225
  export PATH=$PATH:/usr/local/bin
242
226
  export PW="${SERVER_PASSWORD}"
243
227
 
244
- # 🔐 SSH 인증 방식에 따른 sudo 추상화
228
+ # SSH 인증 방식에 따른 sudo 추상화
245
229
  SSH_AUTH_METHOD="${SSH_AUTH_METHOD:-password}"
246
230
  if [ "${SSH_AUTH_METHOD}" = "key" ]; then
247
231
  SUDO() { sudo "$@"; }
@@ -264,15 +248,11 @@ jobs:
264
248
  echo "🔧 Nginx config: ${NGINX_RP_CONF}"
265
249
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
266
250
 
267
- # ============================================================
268
251
  # 1. 최신 이미지 Pull
269
- # ============================================================
270
252
  echo "📥 이미지 Pull: ${IMAGE}"
271
253
  SUDO docker pull "${IMAGE}"
272
254
 
273
- # ============================================================
274
255
  # 2. nginx 설정 백업
275
- # ============================================================
276
256
  echo "📁 nginx 백업 디렉토리 생성: ${NGINX_BACKUP_DIR}"
277
257
  SUDO mkdir -p "${NGINX_BACKUP_DIR}"
278
258
 
@@ -280,9 +260,7 @@ jobs:
280
260
  echo "💾 nginx config 백업: ${BACKUP_FILE}"
281
261
  SUDO cp "${NGINX_RP_CONF}" "${BACKUP_FILE}"
282
262
 
283
- # ============================================================
284
263
  # 3. 현재 활성 포트 판별 (nginx config proxy_pass 파싱)
285
- # ============================================================
286
264
  echo "🔍 nginx config 의 현재 활성 포트 탐색"
287
265
  ACTIVE_PORT=$(
288
266
  SUDO awk -v dom="${SERVICE_DOMAIN}" '
@@ -335,17 +313,13 @@ jobs:
335
313
  echo "🐳 신규 배포 → 포트=${NEW_PORT} 컨테이너=${NEW_CONTAINER_NAME}"
336
314
  echo "🗑️ 이전 컨테이너 (제거 예정) = ${OLD_CONTAINER_NAME}"
337
315
 
338
- # ============================================================
339
316
  # 4. 동일 슬롯(idle 쪽) 잔존 컨테이너 정리
340
- # ============================================================
341
317
  if SUDO docker ps -a --format '{{.Names}}' | grep -Eq "^${NEW_CONTAINER_NAME}\$"; then
342
318
  echo "🗑️ idle 슬롯 정리: ${NEW_CONTAINER_NAME}"
343
319
  SUDO docker rm -f "${NEW_CONTAINER_NAME}"
344
320
  fi
345
321
 
346
- # ============================================================
347
322
  # 5. 볼륨 마운트 옵션 구성
348
- # ============================================================
349
323
  VOLUME_MOUNT_OPTION="-v /etc/localtime:/etc/localtime:ro"
350
324
  if [ "${ENABLE_VOLUME_MOUNT}" = "true" ]; then
351
325
  if [ ! -d "${VOLUME_HOST_PATH}" ]; then
@@ -358,9 +332,7 @@ jobs:
358
332
  echo "ℹ️ 볼륨 마운트 비활성화됨"
359
333
  fi
360
334
 
361
- # ============================================================
362
335
  # 6. 새 컨테이너 기동
363
- # ============================================================
364
336
  echo "🐳 새 컨테이너 기동: ${NEW_CONTAINER_NAME} (포트 ${NEW_PORT})"
365
337
  SUDO docker run -d \
366
338
  -p ${NEW_PORT}:${CONTAINER_INTERNAL_PORT} \
@@ -370,9 +342,7 @@ jobs:
370
342
  ${VOLUME_MOUNT_OPTION} \
371
343
  "${IMAGE}"
372
344
 
373
- # ============================================================
374
345
  # 7. 컨테이너 헬스체크 (로컬 포트 직접 호출)
375
- # ============================================================
376
346
  echo "⏳ 헬스체크 시작 (최대 ${HEALTHCHECK_MAX_RETRIES}회 × ${HEALTHCHECK_RETRY_INTERVAL}초)"
377
347
  HEALTHCHECK_SUCCESS=false
378
348
  for i in $(seq 1 ${HEALTHCHECK_MAX_RETRIES}); do
@@ -394,9 +364,7 @@ jobs:
394
364
  exit 1
395
365
  fi
396
366
 
397
- # ============================================================
398
367
  # 8. nginx config 포트 토글 (proxy_pass 포트 치환)
399
- # ============================================================
400
368
  echo "🔧 nginx config 포트 토글: ${ACTIVE_PORT} → ${NEW_PORT}"
401
369
  TMP_FILE="$(mktemp)"
402
370
  SUDO awk -v dom="${SERVICE_DOMAIN}" -v new_port="${NEW_PORT}" '
@@ -430,9 +398,7 @@ jobs:
430
398
  }
431
399
  ' "${NGINX_RP_CONF}" > "${TMP_FILE}"
432
400
 
433
- # ============================================================
434
401
  # 9. nginx 설정 검증 + reload (실패 시 백업 복구)
435
- # ============================================================
436
402
  echo "🔧 nginx 설정 적용 및 검증"
437
403
  SUDO cp "${TMP_FILE}" "${NGINX_RP_CONF}"
438
404
  if ! (SUDO nginx -t); then
@@ -461,9 +427,7 @@ jobs:
461
427
  fi
462
428
  fi
463
429
 
464
- # ============================================================
465
430
  # 10. 도메인 접근 검증
466
- # ============================================================
467
431
  echo "🌐 도메인 접근 검증 (${SERVICE_DOMAIN})"
468
432
  DOMAIN_OK=false
469
433
  for i in $(seq 1 ${DOMAIN_CHECK_RETRIES}); do
@@ -481,9 +445,7 @@ jobs:
481
445
  echo "⚠️ 도메인 접근 검증 실패: 배포 진행 (DNS 전파 지연 가능성)"
482
446
  fi
483
447
 
484
- # ============================================================
485
448
  # 11. 이전 컨테이너 제거
486
- # ============================================================
487
449
  echo "⏱️ in-flight 요청 처리 대기 (${IN_FLIGHT_WAIT}초)"
488
450
  sleep ${IN_FLIGHT_WAIT}
489
451
 
@@ -494,9 +456,7 @@ jobs:
494
456
  echo "ℹ️ old=${OLD_CONTAINER_NAME} 없음 — 정리 생략"
495
457
  fi
496
458
 
497
- # ============================================================
498
459
  # 12. dangling 이미지 정리 + 백업 보존
499
- # ============================================================
500
460
  echo "🧹 dangling(<none>) 이미지 정리..."
501
461
  SUDO docker image prune -af
502
462
 
@@ -509,9 +469,7 @@ jobs:
509
469
  echo "🌐 도메인: https://${SERVICE_DOMAIN}"
510
470
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
511
471
 
512
- # ===================================================================
513
- # 📝 사용 방법
514
- # ===================================================================
472
+ # 사용 방법
515
473
  #
516
474
  # 1) GitHub Secrets 등록:
517
475
  # APPLICATION_PROD_YML, DOCKERHUB_USERNAME, DOCKERHUB_TOKEN,
@@ -534,5 +492,3 @@ jobs:
534
492
  # 4) 본 워크플로우로 전환:
535
493
  # - 본 파일의 push.branches 주석 해제
536
494
  # - PROJECT-SPRING-SIMPLE-CICD.yaml 의 push 트리거 주석 처리
537
- #
538
- # ===================================================================
@@ -1,7 +1,5 @@
1
1
  # project-auto-wizard:managed-workflow
2
- # ===================================================================
3
2
  # Spring Boot 무중단 배포 (Traefik Blue-Green, SSH + Docker)
4
- # ===================================================================
5
3
  #
6
4
  # deploy 브랜치 푸시 시 Docker 이미지를 빌드하고
7
5
  # Traefik 라벨 기반 Blue-Green 토글로 서버(SSH 접속 가능한 호스트)에 무중단 배포합니다.
@@ -10,9 +8,7 @@
10
8
  # 기본 배포는 PROJECT-SPRING-SIMPLE-CICD.yaml 입니다.
11
9
  # 전환하려면 아래 push.branches 주석 해제 + SIMPLE-CICD 의 push 트리거 주석 처리.
12
10
  #
13
- # ===================================================================
14
- # 🔑 필수 GitHub Secrets
15
- # ===================================================================
11
+ # 필수 GitHub Secrets
16
12
  # APPLICATION_PROD_YML (선택): application-prod.yml 내용
17
13
  # DOCKERHUB_USERNAME: DockerHub 사용자명
18
14
  # DOCKERHUB_TOKEN: DockerHub 액세스 토큰
@@ -20,50 +16,45 @@
20
16
  # SERVER_USER: SSH 사용자명
21
17
  # SERVER_PASSWORD: SSH 비밀번호 (SSH_AUTH_METHOD=password일 때)
22
18
  # SSH_KEY: SSH 개인키 .pem 내용 (SSH_AUTH_METHOD=key일 때, AWS EC2 등)
23
- # ===================================================================
24
19
  #
25
- # 🔧 환경변수 설정 (env 섹션에서 설정)
26
- # ===================================================================
20
+ # 환경변수 설정 (env 섹션에서 설정)
27
21
  #
28
- # 🌐 포트 및 컨테이너:
22
+ # 포트 및 컨테이너:
29
23
  # PROJECT_NAME: 프로젝트명 (컨테이너/이미지/Traefik router 이름)
30
24
  # SERVICE_DOMAIN: 외부 진입 도메인
31
25
  # CONTAINER_INTERNAL_PORT: Spring Boot 내부 포트 (기본: 8080)
32
26
  #
33
- # 🚦 Traefik:
27
+ # Traefik:
34
28
  # TRAEFIK_NETWORK: Traefik docker 네트워크 (기본: traefik-network)
35
29
  # TRAEFIK_ENTRYPOINT: Traefik entrypoint 이름 (기본: web)
36
30
  # TRAEFIK_INTERNAL_PORT: NAS 호스트의 Traefik 진입 포트 (기본: 8079)
37
31
  # EXTRA_NETWORKS: 추가 docker 네트워크 (공백 구분, 예: selenium-chrome-network)
38
32
  #
39
- # 📦 볼륨/스토리지:
33
+ # 볼륨/스토리지:
40
34
  # ENABLE_VOLUME_MOUNT: 볼륨 마운트 여부 (true/false)
41
35
  # VOLUME_HOST_PATH: 호스트 볼륨 경로
42
36
  # VOLUME_CONTAINER_PATH: 컨테이너 내부 마운트 경로
43
37
  #
44
- # 🔌 SSH 연결:
38
+ # SSH 연결:
45
39
  # SSH_PORT: SSH 포트 (기본: 2022)
46
40
  # SSH_COMMAND_TIMEOUT: 명령 타임아웃 (기본: 600s)
47
41
  # SSH_CONNECTION_TIMEOUT: 연결 타임아웃 (기본: 60s)
48
42
  #
49
- # ⏱️ 헬스체크:
43
+ # 헬스체크:
50
44
  # HEALTHCHECK_PATH: Traefik 통한 GET 호출 path (기본: /)
51
45
  # HEALTHCHECK_ACCEPT_CODES: 통과 인정 HTTP 코드 (| 구분, 기본: 200|301|302|308)
52
46
  # HEALTHCHECK_MAX_RETRIES: 최대 시도 횟수 (기본: 36)
53
47
  # HEALTHCHECK_RETRY_INTERVAL: 재시도 간격 초 (기본: 5)
54
48
  # IN_FLIGHT_WAIT: old 컨테이너 제거 전 대기 초 (기본: 10)
55
49
  #
56
- # 💡 사전 조건:
50
+ # 사전 조건:
57
51
  # - 배포 서버에 Traefik 컨테이너가 traefik-network 에 띄워져 있어야 함
58
52
  # - 역방향 프록시: ${SERVICE_DOMAIN}:443 → localhost:${TRAEFIK_INTERNAL_PORT}
59
53
  # (예: Synology DSM 역방향 프록시, Nginx, Caddy 등)
60
- # ===================================================================
61
54
 
62
55
  name: PROJECT-SPRING-NONSTOP-TRAEFIK-CICD
63
56
 
64
- # ===================================================================
65
57
  # 트리거 설정
66
- # ===================================================================
67
58
  # deploy 브랜치 push 자동 트리거는 주석 처리되어 있습니다.
68
59
  # 본 워크플로우로 전환하려면 아래 push.branches 주석을 해제하세요.
69
60
  on:
@@ -72,48 +63,45 @@ on:
72
63
  # - {{MAIN_BRANCH}}
73
64
  workflow_dispatch:
74
65
 
75
- # ===================================================================
76
- # 환경 변수 설정
77
- # ===================================================================
78
66
  env:
79
- # 🔧 프로젝트 설정 - 실제 프로젝트명으로 변경하세요
67
+ # 프로젝트 설정 - 실제 프로젝트명으로 변경하세요
80
68
  PROJECT_NAME: "__PROJECT_NAME__" # @wizard ask:@repo
81
69
  SERVICE_DOMAIN: "__SERVICE_DOMAIN__" # @wizard ask:example.com
82
70
 
83
- # ☁️ Spring Boot 설정
71
+ # Spring Boot 설정
84
72
  SPRING_PROFILE: "prod"
85
73
  JAVA_VERSION: "__JAVA_VERSION__" # @wizard ask:@jdk
86
74
  GRADLE_OPTS: "-Dspring.profiles.active=prod"
87
75
 
88
- # 📁 경로 설정
76
+ # 경로 설정
89
77
  APPLICATION_YML_DIR: "__APPLICATION_YML_DIR__" # @wizard auto:spring-app-yml-dir
90
78
  DOCKERFILE_PATH: "./Dockerfile"
91
79
 
92
- # 🌐 포트 및 컨테이너 설정
80
+ # 포트 및 컨테이너 설정
93
81
  CONTAINER_INTERNAL_PORT: "8080"
94
82
 
95
- # 🚦 Traefik 설정 (서버의 Traefik 환경 구축 후 수정 금지)
83
+ # Traefik 설정 (서버의 Traefik 환경 구축 후 수정 금지)
96
84
  TRAEFIK_NETWORK: "traefik-network"
97
85
  TRAEFIK_ENTRYPOINT: "web"
98
86
  TRAEFIK_INTERNAL_PORT: "8079"
99
87
  EXTRA_NETWORKS: ""
100
88
 
101
- # 📦 볼륨 마운트 설정
89
+ # 볼륨 마운트 설정
102
90
  ENABLE_VOLUME_MOUNT: "false" # @wizard ask:false
103
91
  VOLUME_HOST_PATH: "/volume1/projects/__PROJECT_NAME__" # @wizard ask:/volume1/projects/__PROJECT_NAME__
104
92
  VOLUME_CONTAINER_PATH: "/mnt/__PROJECT_NAME__" # @wizard ask:/mnt/__PROJECT_NAME__
105
93
 
106
- # 🔐 SSH 인증 방식: "password"(Synology·일반 서버) | "key"(AWS EC2·.pem)
94
+ # SSH 인증 방식: "password"(Synology·일반 서버) | "key"(AWS EC2·.pem)
107
95
  # password → SERVER_PASSWORD secret 사용
108
96
  # key → SSH_KEY secret 사용 (.pem 파일 전체 내용을 secret 값으로)
109
97
  SSH_AUTH_METHOD: "password" # @wizard ask:password
110
98
 
111
- # 🔌 SSH 연결 설정
99
+ # SSH 연결 설정
112
100
  SSH_PORT: "__SSH_PORT__" # @wizard ask:2022
113
101
  SSH_COMMAND_TIMEOUT: "600s"
114
102
  SSH_CONNECTION_TIMEOUT: "60s"
115
103
 
116
- # ⏱️ 헬스체크 설정
104
+ # 헬스체크 설정
117
105
  HEALTHCHECK_PATH: "/"
118
106
  HEALTHCHECK_ACCEPT_CODES: "200|301|302|308"
119
107
  HEALTHCHECK_MAX_RETRIES: "36"
@@ -121,9 +109,7 @@ env:
121
109
  IN_FLIGHT_WAIT: "10"
122
110
 
123
111
  jobs:
124
- # ===================================================================
125
112
  # 빌드 작업
126
- # ===================================================================
127
113
  build:
128
114
  name: Spring Boot 애플리케이션 빌드
129
115
  runs-on: ubuntu-latest
@@ -185,9 +171,7 @@ jobs:
185
171
  rm -rf /tmp/.buildx-cache
186
172
  mv /tmp/.buildx-cache-new /tmp/.buildx-cache
187
173
 
188
- # ===================================================================
189
174
  # 배포 작업 (Blue-Green 무중단)
190
- # ===================================================================
191
175
  deploy:
192
176
  name: Blue-Green 무중단 배포
193
177
  needs: build
@@ -231,7 +215,7 @@ jobs:
231
215
  export PATH=$PATH:/usr/local/bin
232
216
  export PW="${SERVER_PASSWORD}"
233
217
 
234
- # 🔐 SSH 인증 방식에 따른 sudo 추상화
218
+ # SSH 인증 방식에 따른 sudo 추상화
235
219
  SSH_AUTH_METHOD="${SSH_AUTH_METHOD:-password}"
236
220
  if [ "${SSH_AUTH_METHOD}" = "key" ]; then
237
221
  SUDO() { sudo "$@"; }
@@ -252,15 +236,11 @@ jobs:
252
236
  echo "🔧 Traefik 진입: localhost:${TRAEFIK_INTERNAL_PORT} (entrypoint=${TRAEFIK_ENTRYPOINT})"
253
237
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
254
238
 
255
- # ============================================================
256
239
  # 1. 최신 이미지 Pull
257
- # ============================================================
258
240
  echo "📥 이미지 Pull: ${IMAGE}"
259
241
  SUDO docker pull "${IMAGE}"
260
242
 
261
- # ============================================================
262
243
  # 2. 현재 active 컨테이너 색 판별 (Traefik 라벨 부착 여부 기준)
263
- # ============================================================
264
244
  ACTIVE=$(SUDO docker ps \
265
245
  --filter "label=traefik.http.routers.${ROUTER_NAME}.rule" \
266
246
  --filter "name=${PROJECT_NAME}-" \
@@ -283,15 +263,11 @@ jobs:
283
263
 
284
264
  echo "🎨 active=${ACTIVE:-none} → new=${NEW_NAME}, old=${OLD_NAME}"
285
265
 
286
- # ============================================================
287
266
  # 3. 동일 슬롯(idle 쪽) 잔존 컨테이너 정리
288
- # ============================================================
289
267
  echo "🗑️ idle 슬롯 정리: ${NEW_NAME}"
290
268
  SUDO docker rm -f "${NEW_NAME}" 2>/dev/null || true
291
269
 
292
- # ============================================================
293
270
  # 4. 볼륨 마운트 옵션 구성
294
- # ============================================================
295
271
  VOLUME_MOUNT_OPTION="-v /etc/localtime:/etc/localtime:ro"
296
272
  if [ "${ENABLE_VOLUME_MOUNT}" = "true" ]; then
297
273
  if [ ! -d "${VOLUME_HOST_PATH}" ]; then
@@ -304,9 +280,7 @@ jobs:
304
280
  echo "ℹ️ 볼륨 마운트 비활성화됨"
305
281
  fi
306
282
 
307
- # ============================================================
308
283
  # 5. 새 컨테이너 기동 (Traefik 라벨 포함)
309
- # ============================================================
310
284
  echo "🐳 새 컨테이너 기동: ${NEW_NAME}"
311
285
  SUDO docker run -d \
312
286
  --name "${NEW_NAME}" \
@@ -320,9 +294,7 @@ jobs:
320
294
  ${VOLUME_MOUNT_OPTION} \
321
295
  "${IMAGE}"
322
296
 
323
- # ============================================================
324
297
  # 6. 추가 네트워크 연결 (EXTRA_NETWORKS, 공백 구분)
325
- # ============================================================
326
298
  if [ -n "${EXTRA_NETWORKS}" ]; then
327
299
  for net in ${EXTRA_NETWORKS}; do
328
300
  echo "🔗 추가 네트워크 연결: ${net}"
@@ -330,15 +302,11 @@ jobs:
330
302
  done
331
303
  fi
332
304
 
333
- # ============================================================
334
305
  # 7. Traefik 라벨 디버그 출력 (escape 검증용)
335
- # ============================================================
336
306
  echo "🔍 Traefik 라벨 확인:"
337
307
  SUDO docker inspect "${NEW_NAME}" --format '{{range $k, $v := .Config.Labels}} {{$k}} = {{$v}}{{"\n"}}{{end}}' | grep traefik || true
338
308
 
339
- # ============================================================
340
309
  # 8. 헬스체크 — Traefik 통한 라우팅 확인
341
- # ============================================================
342
310
  MAX_WAIT=$((HEALTHCHECK_MAX_RETRIES * HEALTHCHECK_RETRY_INTERVAL))
343
311
  echo "⏳ 헬스체크 시작 (최대 ${MAX_WAIT}초, ${HEALTHCHECK_MAX_RETRIES}회 × ${HEALTHCHECK_RETRY_INTERVAL}초)"
344
312
 
@@ -388,9 +356,7 @@ jobs:
388
356
  exit 1
389
357
  fi
390
358
 
391
- # ============================================================
392
359
  # 9. in-flight 처리 + old 컨테이너 자동 제거
393
- # ============================================================
394
360
  if SUDO docker ps -a --format '{{.Names}}' | grep -Eq "^${OLD_NAME}$"; then
395
361
  echo "⏱️ in-flight 요청 처리 대기 (${IN_FLIGHT_WAIT}초)"
396
362
  sleep ${IN_FLIGHT_WAIT}
@@ -400,9 +366,7 @@ jobs:
400
366
  echo "ℹ️ old=${OLD_NAME} 없음 — 정리 생략"
401
367
  fi
402
368
 
403
- # ============================================================
404
369
  # 10. dangling 이미지 정리
405
- # ============================================================
406
370
  echo "🧹 dangling(<none>) 이미지 정리..."
407
371
  SUDO docker image prune -af
408
372
 
@@ -411,9 +375,7 @@ jobs:
411
375
  echo "🌐 도메인: https://${SERVICE_DOMAIN}"
412
376
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
413
377
 
414
- # ===================================================================
415
- # 📝 사용 방법
416
- # ===================================================================
378
+ # 사용 방법
417
379
  #
418
380
  # 1) GitHub Secrets 등록:
419
381
  # APPLICATION_PROD_YML, DOCKERHUB_USERNAME, DOCKERHUB_TOKEN,
@@ -434,5 +396,3 @@ jobs:
434
396
  # 4) 본 워크플로우로 전환:
435
397
  # - 본 파일의 push.branches 주석 해제
436
398
  # - PROJECT-SPRING-SIMPLE-CICD.yaml 의 push 트리거 주석 처리
437
- #
438
- # ===================================================================