project-auto-wizard 0.9.0 → 0.10.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.
- package/README.md +5 -5
- package/package.json +1 -1
- package/payload/scripts/__pycache__/changelog_manager.cpython-314.pyc +0 -0
- package/payload/scripts/__pycache__/issue_helper.cpython-314.pyc +0 -0
- package/payload/scripts/__pycache__/version_manager.cpython-314.pyc +0 -0
- package/payload/scripts/changelog_manager.py +2 -2
- package/payload/scripts/version_manager.py +2 -2
- package/payload/version.yml.template +1 -1
- package/payload/workflows/common/secret-backup/PROJECT-COMMON-SECRET-FILE-UPLOAD.yaml +12 -12
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-TEST-APK.yaml +1 -1
- package/payload/workflows/flutter/{PROJECT-FLUTTER-SUH-LAB-APP-BUILD-TRIGGER.yaml → PROJECT-FLUTTER-APP-BUILD-TRIGGER.yaml} +38 -38
- package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TEST-TESTFLIGHT.yaml +1 -1
- package/payload/workflows/go/PROJECT-GO-PR-PREVIEW.yaml +40 -40
- package/payload/workflows/python/PROJECT-PYTHON-PR-PREVIEW.yaml +40 -40
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-PR-PREVIEW.yaml +39 -39
- package/src/cli/args.js +2 -2
- package/src/cli/help.js +1 -1
- package/src/core/copy/workflows.js +21 -9
- package/src/core/deploy-style.js +9 -1
- package/src/core/verify.js +2 -2
- package/src/ui/env-plan.js +14 -4
- package/src/ui/prompts.js +10 -4
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ npx project-auto-wizard
|
|
|
17
17
|
[](package.json)
|
|
18
18
|
|
|
19
19
|
<!-- AUTO-VERSION-SECTION: DO NOT EDIT MANUALLY -->
|
|
20
|
-
## 최신 버전 : v0.9.0 (2026-
|
|
20
|
+
## 최신 버전 : v0.9.0 (2026-09-18)
|
|
21
21
|
|
|
22
22
|
[전체 버전 기록 보기](CHANGELOG.md)
|
|
23
23
|
|
|
@@ -67,10 +67,10 @@ flutter.APP_ARTIFACT_NAME:
|
|
|
67
67
|
`spring`/`flutter`는 아래처럼 단일 CI 이상으로 깊게 구성되어 있습니다:
|
|
68
68
|
|
|
69
69
|
- **flutter**: Android(Firebase/Playstore/Selfhosted/TestAPK 배포), iOS(TestFlight/Test-TestFlight), CI, Lab 트리거까지 8종
|
|
70
|
-
- **spring**: 서버 배포 1종(단일 서버 / 무중단 Nginx / 무중단 Traefik 중 택1) + PR 프리뷰 + 라이브러리 publish 2종(Nexus·GitHub Packages, `--nexus` opt-in)
|
|
71
|
-
- 서버 배포 워크플로우는 **서로 대체재**라 하나만 설치합니다. 대화형에서 고르면 그것만 깔리고 **`push` 트리거까지 켜진 채로** 설치됩니다. 비대화형은 `--deploy-style simple|nginx|traefik` (기본: `simple`).
|
|
70
|
+
- **spring**: 서버 배포 1종(단일 서버 / 무중단 Nginx / 무중단 Traefik / 배포 안 함 중 택1) + PR 프리뷰 + 라이브러리 publish 2종(Nexus·GitHub Packages, `--nexus` opt-in)
|
|
71
|
+
- 서버 배포 워크플로우는 **서로 대체재**라 하나만 설치합니다. 대화형에서 고르면 그것만 깔리고 **`push` 트리거까지 켜진 채로** 설치됩니다. 비대화형은 `--deploy-style simple|nginx|traefik|none` (기본: `simple`).
|
|
72
72
|
- 고른 방식은 `version.yml`에 기록되므로 다시 실행해도 묻지 않습니다. 방식을 바꾸면 **이전 워크플로우를 마법사가 정리합니다** — 손대지 않은 파일은 삭제하고, 수정한 파일은 `.bak`으로 옮겨 내용을 보존합니다. 남겨두면 배포가 두 번 돕니다.
|
|
73
|
-
- PR 프리뷰는 배포 방식과 무관한 별개 축이라 선택과 관계없이 함께
|
|
73
|
+
- PR 프리뷰는 배포 방식과 무관한 별개 축이라 선택과 관계없이 함께 설치됩니다 (단, `none`을 고르면 PR 프리뷰도 함께 제외됩니다 — 서버 배포 자체를 하지 않는 프로젝트를 위한 선택지입니다).
|
|
74
74
|
- **react/next**: CI와 CI+CD 분리 구성
|
|
75
75
|
- **python**: CI / PR 프리뷰 / SimpleCICD
|
|
76
76
|
- **go**: CI(Dockerfile 불필요, go test/vet/build/lint) / PR 프리뷰 / SimpleCICD(Dockerfile 있는 프로젝트만 해당)
|
|
@@ -153,7 +153,7 @@ npx project-auto-wizard [옵션]
|
|
|
153
153
|
--paths "t=p,..." 모노레포 타입별 경로
|
|
154
154
|
--main-branch B 릴리스 브랜치 (기본: 감지된 default branch)
|
|
155
155
|
--develop-branch B 개발 브랜치 (기본: develop)
|
|
156
|
-
--deploy-style S 서버 배포 방식: simple | nginx | traefik (기본: simple)
|
|
156
|
+
--deploy-style S 서버 배포 방식: simple | nginx | traefik | none (기본: simple)
|
|
157
157
|
--nexus 라이브러리 publish 워크플로우 포함 (Nexus + GitHub Packages)
|
|
158
158
|
--secret-backup Secret 서버 백업 워크플로우 포함
|
|
159
159
|
--semver-auto 커밋 타입 기반 자동 major/minor/patch 승격 (기본: 사용함, --no-semver-auto로 끔)
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -277,7 +277,7 @@ def classify_commits(lines: list[str]) -> dict:
|
|
|
277
277
|
"""
|
|
278
278
|
커밋 제목 목록을 3단계 규칙으로 분류.
|
|
279
279
|
|
|
280
|
-
1단계:
|
|
280
|
+
1단계: 제목 컨벤션 — "제목 : type : 내용 [URL]"
|
|
281
281
|
2단계: Conventional Commits — "type(scope)!: 내용"
|
|
282
282
|
(perf/style/build/ci → chore 버킷으로 매핑)
|
|
283
283
|
3단계: 위 두 형식에 매칭되지 않으면 "changes" 버킷 (자유 형식)
|
|
@@ -298,7 +298,7 @@ def classify_commits(lines: list[str]) -> dict:
|
|
|
298
298
|
# 1단계가 2단계보다 먼저다 — 트레이드오프: "제목 : feat : 내용" 형식은
|
|
299
299
|
# "feat: ..." Conventional Commits와 겹칠 수 없지만(타입 앞에 제목 필수),
|
|
300
300
|
# 제목이 있는 줄에 " : type : "가 우연히 들어가면 tier-2 해석 기회 없이
|
|
301
|
-
# tier-1로 확정된다.
|
|
301
|
+
# tier-1로 확정된다. 이 컨벤션을 쓰는 레포에서는 이것이 의도된 우선순위다.
|
|
302
302
|
tier1 = _TIER1_RE.match(line)
|
|
303
303
|
if tier1:
|
|
304
304
|
title = tier1.group(1).strip()
|
|
@@ -5,8 +5,8 @@ version_manager.py — general-purpose version management script (stdlib only).
|
|
|
5
5
|
This script is copied into user repos (.github/scripts/) by project-auto-wizard
|
|
6
6
|
and runs standalone on GitHub Actions ubuntu runners (python3, no third-party deps).
|
|
7
7
|
|
|
8
|
-
It is a Python rewrite of the battle-tested bash
|
|
9
|
-
|
|
8
|
+
It is a Python rewrite of the battle-tested bash reference implementation
|
|
9
|
+
(version_manager.sh). Behavioral equivalence with that script is the design goal:
|
|
10
10
|
- version.yml is the single source of truth for `version` and `version_code`.
|
|
11
11
|
- version.yml is edited via line-based regex replacements that preserve all
|
|
12
12
|
comments and formatting (never rewritten wholesale, never parsed with a YAML lib).
|
|
@@ -47,5 +47,5 @@ metadata:
|
|
|
47
47
|
nexus: {{OPT_NEXUS}}
|
|
48
48
|
secret_backup: {{OPT_SECRET_BACKUP}}
|
|
49
49
|
semver_auto: {{OPT_SEMVER_AUTO}}
|
|
50
|
-
deploy_style: "{{OPT_DEPLOY_STYLE}}" # simple | nginx | traefik (서버 배포 워크플로우)
|
|
50
|
+
deploy_style: "{{OPT_DEPLOY_STYLE}}" # simple | nginx | traefik | none (서버 배포 워크플로우)
|
|
51
51
|
{{DEPLOY}}
|
|
@@ -135,17 +135,17 @@ jobs:
|
|
|
135
135
|
# ============================================
|
|
136
136
|
|
|
137
137
|
# --- ENV_FILE → .env ---
|
|
138
|
-
cat << '
|
|
138
|
+
cat << '__WIZARD_SECRET_CHECK_EOF__' > /tmp/_secret_check
|
|
139
139
|
${{ secrets.ENV_FILE }}
|
|
140
|
-
|
|
140
|
+
__WIZARD_SECRET_CHECK_EOF__
|
|
141
141
|
if [ -s /tmp/_secret_check ] && [ -n "$(tr -d '[:space:]' < /tmp/_secret_check)" ]; then
|
|
142
142
|
echo "ENV_FILE → .env 업로드 중..."
|
|
143
|
-
cat << '
|
|
143
|
+
cat << '__WIZARD_FILE_CONTENT_EOF__' | sudo tee "${BASE_DIR}/.env" > /dev/null
|
|
144
144
|
${{ secrets.ENV_FILE }}
|
|
145
|
-
|
|
146
|
-
cat << '
|
|
145
|
+
__WIZARD_FILE_CONTENT_EOF__
|
|
146
|
+
cat << '__WIZARD_FILE_CONTENT_EOF__' | sudo tee "${BASE_DIR}/${TIMESTAMP}/.env" > /dev/null
|
|
147
147
|
${{ secrets.ENV_FILE }}
|
|
148
|
-
|
|
148
|
+
__WIZARD_FILE_CONTENT_EOF__
|
|
149
149
|
echo ".env 업로드 완료"
|
|
150
150
|
else
|
|
151
151
|
echo "ENV_FILE 스킵 (Secret 미설정)"
|
|
@@ -153,17 +153,17 @@ jobs:
|
|
|
153
153
|
rm -f /tmp/_secret_check
|
|
154
154
|
|
|
155
155
|
# --- APPLICATION_PROD_YML → application-prod.yml ---
|
|
156
|
-
cat << '
|
|
156
|
+
cat << '__WIZARD_SECRET_CHECK_EOF__' > /tmp/_secret_check
|
|
157
157
|
${{ secrets.APPLICATION_PROD_YML }}
|
|
158
|
-
|
|
158
|
+
__WIZARD_SECRET_CHECK_EOF__
|
|
159
159
|
if [ -s /tmp/_secret_check ] && [ -n "$(tr -d '[:space:]' < /tmp/_secret_check)" ]; then
|
|
160
160
|
echo "APPLICATION_PROD_YML → application-prod.yml 업로드 중..."
|
|
161
|
-
cat << '
|
|
161
|
+
cat << '__WIZARD_FILE_CONTENT_EOF__' | sudo tee "${BASE_DIR}/application-prod.yml" > /dev/null
|
|
162
162
|
${{ secrets.APPLICATION_PROD_YML }}
|
|
163
|
-
|
|
164
|
-
cat << '
|
|
163
|
+
__WIZARD_FILE_CONTENT_EOF__
|
|
164
|
+
cat << '__WIZARD_FILE_CONTENT_EOF__' | sudo tee "${BASE_DIR}/${TIMESTAMP}/application-prod.yml" > /dev/null
|
|
165
165
|
${{ secrets.APPLICATION_PROD_YML }}
|
|
166
|
-
|
|
166
|
+
__WIZARD_FILE_CONTENT_EOF__
|
|
167
167
|
echo "application-prod.yml 업로드 완료"
|
|
168
168
|
else
|
|
169
169
|
echo "APPLICATION_PROD_YML 스킵 (Secret 미설정)"
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
# project-auto-wizard:managed-workflow
|
|
2
2
|
# ===================================================================
|
|
3
|
-
# Flutter 테스트 앱 빌드 트리거 워크플로우
|
|
3
|
+
# Flutter 테스트 앱 빌드 트리거 워크플로우
|
|
4
4
|
# ===================================================================
|
|
5
5
|
#
|
|
6
6
|
# 이 워크플로우는 PR 또는 이슈에 댓글로 빌드 명령어를 작성하면
|
|
7
7
|
# Android와 iOS 테스트 앱 빌드를 자동으로 트리거합니다.
|
|
8
8
|
#
|
|
9
9
|
# 주요 특징:
|
|
10
|
-
# - PR/이슈 댓글 감지: "
|
|
10
|
+
# - PR/이슈 댓글 감지: "/wizard app build / apk build / ios build" 키워드 감지 (어순 무관: build app 도 동작)
|
|
11
11
|
# - repository_dispatch 이벤트로 빌드 워크플로우 트리거
|
|
12
12
|
# - PR/이슈 번호 + 빌드 횟수로 고유한 빌드 번호 생성 (예: 38700, 38701...)
|
|
13
13
|
# - 브랜치명에서 이슈 번호 자동 추출 (YYYYMMDD_#이슈번호_내용 형식)
|
|
14
14
|
# - 테스트 버전은 version.yml에서 동적으로 읽어 사용 (빌드 번호로 운영/테스트 구분)
|
|
15
15
|
#
|
|
16
16
|
# 사용 방법:
|
|
17
|
-
# - PR에 댓글 작성: "
|
|
18
|
-
# - PR에 댓글 작성: "
|
|
19
|
-
# - PR에 댓글 작성: "
|
|
20
|
-
# - 이슈에 댓글 작성: 위 명령어 동일 (
|
|
17
|
+
# - PR에 댓글 작성: "/wizard app build" (Android + iOS 모두 빌드)
|
|
18
|
+
# - PR에 댓글 작성: "/wizard apk build" (Android만 빌드)
|
|
19
|
+
# - PR에 댓글 작성: "/wizard ios build" (iOS만 빌드)
|
|
20
|
+
# - 이슈에 댓글 작성: 위 명령어 동일 (Issue Helper 댓글 필요)
|
|
21
21
|
# - 어순은 무관: "build app" / "build apk" / "build ios"로 적어도 동일하게 동작
|
|
22
|
-
# - 특정 브랜치 지정: "
|
|
23
|
-
# 예: "
|
|
24
|
-
# 브랜치명을 생략하면 PR head 또는 이슈의
|
|
22
|
+
# - 특정 브랜치 지정: "/wizard app build <브랜치명>" (명령어 뒤에 브랜치명을 적으면 해당 브랜치를 빌드)
|
|
23
|
+
# 예: "/wizard apk build 20260609_#349_feature" → 해당 브랜치로 Android 빌드
|
|
24
|
+
# 브랜치명을 생략하면 PR head 또는 이슈의 Issue Helper 댓글 브랜치를 사용
|
|
25
25
|
#
|
|
26
26
|
# 트리거되는 워크플로우:
|
|
27
27
|
# - PROJECT-FLUTTER-ANDROID-TEST-APK.yaml (event_type: build-android-app)
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
#
|
|
30
30
|
# ===================================================================
|
|
31
31
|
|
|
32
|
-
name: PROJECT-Flutter-
|
|
32
|
+
name: PROJECT-Flutter-App-Build-Trigger
|
|
33
33
|
|
|
34
34
|
on:
|
|
35
35
|
issue_comment:
|
|
@@ -43,9 +43,9 @@ permissions:
|
|
|
43
43
|
jobs:
|
|
44
44
|
trigger-builds:
|
|
45
45
|
name: 빌드 워크플로우 트리거
|
|
46
|
-
#
|
|
46
|
+
# /wizard app build / /wizard apk build / /wizard ios build 키워드 감지 (어순 무관)
|
|
47
47
|
if: |
|
|
48
|
-
contains(github.event.comment.body, '
|
|
48
|
+
contains(github.event.comment.body, '/wizard') &&
|
|
49
49
|
(
|
|
50
50
|
(contains(github.event.comment.body, 'build') && contains(github.event.comment.body, 'app')) ||
|
|
51
51
|
(contains(github.event.comment.body, 'apk') && contains(github.event.comment.body, 'build')) ||
|
|
@@ -93,27 +93,27 @@ jobs:
|
|
|
93
93
|
// 어순은 양방향 지원: "{타입} build"(app/apk/ios build)와 "build {타입}"(build app 등) 모두 허용.
|
|
94
94
|
// apk가 app으로 오인되지 않도록 app 토큰은 \b 단어경계로 정확히 끊는다(apk·application 제외).
|
|
95
95
|
// apk/ios를 app보다 먼저 검사해, "apk build"가 app 분기로 새지 않게 한다.
|
|
96
|
-
if (comment.match(
|
|
97
|
-
//
|
|
96
|
+
if (comment.match(/\/wizard[^\S\r\n]+apk[^\S\r\n]+build/) || comment.match(/\/wizard[^\S\r\n]+build[^\S\r\n]+apk/)) {
|
|
97
|
+
// /wizard apk build [브랜치] (또는 build apk) → Android만
|
|
98
98
|
buildAndroid = true;
|
|
99
99
|
buildType = 'apk';
|
|
100
|
-
m = rawComment.match(
|
|
101
|
-
|| rawComment.match(
|
|
100
|
+
m = rawComment.match(/\/wizard[^\S\r\n]+apk[^\S\r\n]+build(?:[^\S\r\n]+(\S+))?/i)
|
|
101
|
+
|| rawComment.match(/\/wizard[^\S\r\n]+build[^\S\r\n]+apk(?:[^\S\r\n]+(\S+))?/i);
|
|
102
102
|
customBranch = (m && m[1]) || '';
|
|
103
|
-
} else if (comment.match(
|
|
104
|
-
//
|
|
103
|
+
} else if (comment.match(/\/wizard[^\S\r\n]+ios[^\S\r\n]+build/) || comment.match(/\/wizard[^\S\r\n]+build[^\S\r\n]+ios/)) {
|
|
104
|
+
// /wizard ios build [브랜치] (또는 build ios) → iOS만
|
|
105
105
|
buildIos = true;
|
|
106
106
|
buildType = 'ios';
|
|
107
|
-
m = rawComment.match(
|
|
108
|
-
|| rawComment.match(
|
|
107
|
+
m = rawComment.match(/\/wizard[^\S\r\n]+ios[^\S\r\n]+build(?:[^\S\r\n]+(\S+))?/i)
|
|
108
|
+
|| rawComment.match(/\/wizard[^\S\r\n]+build[^\S\r\n]+ios(?:[^\S\r\n]+(\S+))?/i);
|
|
109
109
|
customBranch = (m && m[1]) || '';
|
|
110
|
-
} else if (comment.match(
|
|
111
|
-
//
|
|
110
|
+
} else if (comment.match(/\/wizard[^\S\r\n]+app\b[^\S\r\n]+build/) || comment.match(/\/wizard[^\S\r\n]+build[^\S\r\n]+app\b/)) {
|
|
111
|
+
// /wizard app build [브랜치] (또는 build app) → Android + iOS 모두
|
|
112
112
|
buildAndroid = true;
|
|
113
113
|
buildIos = true;
|
|
114
114
|
buildType = 'app';
|
|
115
|
-
m = rawComment.match(
|
|
116
|
-
|| rawComment.match(
|
|
115
|
+
m = rawComment.match(/\/wizard[^\S\r\n]+app\b[^\S\r\n]+build(?:[^\S\r\n]+(\S+))?/i)
|
|
116
|
+
|| rawComment.match(/\/wizard[^\S\r\n]+build[^\S\r\n]+app\b(?:[^\S\r\n]+(\S+))?/i);
|
|
117
117
|
customBranch = (m && m[1]) || '';
|
|
118
118
|
}
|
|
119
119
|
|
|
@@ -175,7 +175,7 @@ jobs:
|
|
|
175
175
|
} catch (error) {
|
|
176
176
|
console.log('ℹ️ PR이 아닙니다. 이슈에서 브랜치 정보를 찾습니다...');
|
|
177
177
|
|
|
178
|
-
// 2. PR이 아니면 이슈에서 "
|
|
178
|
+
// 2. PR이 아니면 이슈에서 "Issue Helper" 댓글 찾기
|
|
179
179
|
sourceType = 'ISSUE';
|
|
180
180
|
sourceNumber = issueNumber.toString();
|
|
181
181
|
relatedIssueNumber = issueNumber.toString();
|
|
@@ -203,27 +203,27 @@ jobs:
|
|
|
203
203
|
per_page: 100
|
|
204
204
|
});
|
|
205
205
|
|
|
206
|
-
// "
|
|
206
|
+
// "Issue Helper" 댓글 찾기
|
|
207
207
|
const guideComment = comments.data.find(c =>
|
|
208
|
-
c.body.includes('
|
|
208
|
+
c.body.includes('<!-- project-auto-wizard issue helper -->')
|
|
209
209
|
);
|
|
210
210
|
|
|
211
211
|
if (!guideComment) {
|
|
212
|
-
console.log('❌ "
|
|
212
|
+
console.log('❌ "Issue Helper" 댓글을 찾을 수 없습니다.');
|
|
213
213
|
core.setOutput('found', 'false');
|
|
214
|
-
core.setOutput('errorMessage', '이슈에서 "
|
|
214
|
+
core.setOutput('errorMessage', '이슈에서 "Issue Helper" 댓글을 찾을 수 없습니다. 브랜치 정보가 포함된 댓글이 필요합니다.');
|
|
215
215
|
return;
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
console.log('✅ "
|
|
218
|
+
console.log('✅ "Issue Helper" 댓글 발견');
|
|
219
219
|
|
|
220
220
|
// 브랜치명 추출 (### 브랜치 다음 ``` 블록 내용)
|
|
221
|
-
const branchMatch = guideComment.body.match(/###
|
|
221
|
+
const branchMatch = guideComment.body.match(/### 브랜치(?:명)?\s*```\s*([\s\S]*?)\s*```/);
|
|
222
222
|
|
|
223
223
|
if (!branchMatch) {
|
|
224
224
|
console.log('❌ 브랜치 정보를 파싱할 수 없습니다.');
|
|
225
225
|
core.setOutput('found', 'false');
|
|
226
|
-
core.setOutput('errorMessage', '"
|
|
226
|
+
core.setOutput('errorMessage', '"Issue Helper" 댓글에서 브랜치 정보를 파싱할 수 없습니다. 댓글 형식을 확인해주세요.');
|
|
227
227
|
return;
|
|
228
228
|
}
|
|
229
229
|
|
|
@@ -262,9 +262,9 @@ jobs:
|
|
|
262
262
|
|
|
263
263
|
**해결 방법:**
|
|
264
264
|
- PR에서 빌드하는 경우: PR 페이지에서 댓글을 작성해주세요.
|
|
265
|
-
- 이슈에서 빌드하는 경우: "
|
|
265
|
+
- 이슈에서 빌드하는 경우: "Issue Helper" 댓글이 있어야 합니다.
|
|
266
266
|
- 댓글에 \`### 브랜치\` 섹션과 브랜치명이 포함되어 있어야 합니다.
|
|
267
|
-
- 또는 댓글에 브랜치명을 직접 지정할 수 있습니다:
|
|
267
|
+
- 또는 댓글에 브랜치명을 직접 지정할 수 있습니다: \`/wizard app build <브랜치명>\``;
|
|
268
268
|
|
|
269
269
|
await github.rest.issues.createComment({
|
|
270
270
|
owner: context.repo.owner,
|
|
@@ -329,7 +329,7 @@ jobs:
|
|
|
329
329
|
'',
|
|
330
330
|
'### 💡 확인 사항',
|
|
331
331
|
'1. 브랜치가 원격 저장소에 push되었는지 확인하세요',
|
|
332
|
-
'2. "
|
|
332
|
+
'2. "Issue Helper" 댓글의 브랜치명이 올바른지 확인하세요',
|
|
333
333
|
'3. 브랜치명에 오타가 없는지 확인하세요',
|
|
334
334
|
'',
|
|
335
335
|
`🔗 [워크플로우 로그](${runUrl})`
|
|
@@ -377,7 +377,7 @@ jobs:
|
|
|
377
377
|
// iOS 빌드: ios 빌드 + app 공용 빌드 둘 다 카운트 (어순 무관)
|
|
378
378
|
buildCount = comments.data.filter(c => {
|
|
379
379
|
const body = c.body.toLowerCase();
|
|
380
|
-
return body.includes('
|
|
380
|
+
return body.includes('/wizard') && body.includes('build') && (
|
|
381
381
|
body.includes('ios') || body.includes('app')
|
|
382
382
|
);
|
|
383
383
|
}).length;
|
|
@@ -387,7 +387,7 @@ jobs:
|
|
|
387
387
|
// Android 빌드: apk 빌드 + app 공용 빌드 둘 다 카운트 (어순 무관)
|
|
388
388
|
buildCount = comments.data.filter(c => {
|
|
389
389
|
const body = c.body.toLowerCase();
|
|
390
|
-
return body.includes('
|
|
390
|
+
return body.includes('/wizard') && body.includes('build') && (
|
|
391
391
|
body.includes('apk') || body.includes('app')
|
|
392
392
|
);
|
|
393
393
|
}).length;
|
|
@@ -397,7 +397,7 @@ jobs:
|
|
|
397
397
|
// 전체 앱 빌드: 모든 빌드 명령어 카운트 (어순 무관)
|
|
398
398
|
buildCount = comments.data.filter(c => {
|
|
399
399
|
const body = c.body.toLowerCase();
|
|
400
|
-
return body.includes('
|
|
400
|
+
return body.includes('/wizard') && body.includes('build') && (
|
|
401
401
|
body.includes('ios') ||
|
|
402
402
|
body.includes('apk') ||
|
|
403
403
|
body.includes('app')
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
# ===================================================================
|
|
20
20
|
#
|
|
21
21
|
# 🚀 사용법:
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
22
|
+
# /wizard server build - Preview 빌드 및 배포
|
|
23
|
+
# /wizard server destroy - Preview 환경 삭제
|
|
24
|
+
# /wizard server status - 현재 상태 확인
|
|
25
25
|
#
|
|
26
26
|
# 📊 리소스 네이밍:
|
|
27
27
|
# - 컨테이너: {PROJECT_NAME}-pr-{번호}
|
|
@@ -64,7 +64,7 @@ env:
|
|
|
64
64
|
|
|
65
65
|
# Issue Helper 댓글 마커 (프로젝트별 수정 필요)
|
|
66
66
|
# Issue 댓글에서 브랜치명을 추출할 때 사용
|
|
67
|
-
ISSUE_HELPER_MARKER: '
|
|
67
|
+
ISSUE_HELPER_MARKER: '<!-- project-auto-wizard issue helper -->'
|
|
68
68
|
|
|
69
69
|
# Health Check 설정 (프로젝트별 수정 필요)
|
|
70
70
|
# - HEALTH_CHECK_PATH: HTTP Health Check 경로 (빈값이면 HTTP 체크 건너뜀)
|
|
@@ -115,7 +115,7 @@ jobs:
|
|
|
115
115
|
is_custom_branch: ${{ steps.parse.outputs.is_custom_branch }}
|
|
116
116
|
steps:
|
|
117
117
|
- name: 댓글에 👀 리액션 추가
|
|
118
|
-
if: contains(github.event.comment.body, '
|
|
118
|
+
if: contains(github.event.comment.body, '/wizard') && contains(github.event.comment.body, 'server')
|
|
119
119
|
uses: actions/github-script@v9
|
|
120
120
|
with:
|
|
121
121
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -143,8 +143,8 @@ jobs:
|
|
|
143
143
|
fi
|
|
144
144
|
|
|
145
145
|
# 명령어 파싱 (브랜치 파라미터 지원)
|
|
146
|
-
# 형식:
|
|
147
|
-
if [[ "$COMMENT" =~
|
|
146
|
+
# 형식: /wizard server <command> [브랜치명]
|
|
147
|
+
if [[ "$COMMENT" =~ /wizard[[:space:]]+server[[:space:]]+build([[:space:]]+([^[:space:]]+))? ]]; then
|
|
148
148
|
echo "command=build" >> $GITHUB_OUTPUT
|
|
149
149
|
echo "is_valid=true" >> $GITHUB_OUTPUT
|
|
150
150
|
if [[ -n "${BASH_REMATCH[2]}" ]]; then
|
|
@@ -155,7 +155,7 @@ jobs:
|
|
|
155
155
|
echo "is_custom_branch=false" >> $GITHUB_OUTPUT
|
|
156
156
|
echo "✅ 명령어 감지: build"
|
|
157
157
|
fi
|
|
158
|
-
elif [[ "$COMMENT" =~
|
|
158
|
+
elif [[ "$COMMENT" =~ /wizard[[:space:]]+server[[:space:]]+destroy([[:space:]]+([^[:space:]]+))? ]]; then
|
|
159
159
|
echo "command=destroy" >> $GITHUB_OUTPUT
|
|
160
160
|
echo "is_valid=true" >> $GITHUB_OUTPUT
|
|
161
161
|
if [[ -n "${BASH_REMATCH[2]}" ]]; then
|
|
@@ -166,7 +166,7 @@ jobs:
|
|
|
166
166
|
echo "is_custom_branch=false" >> $GITHUB_OUTPUT
|
|
167
167
|
echo "✅ 명령어 감지: destroy"
|
|
168
168
|
fi
|
|
169
|
-
elif [[ "$COMMENT" =~
|
|
169
|
+
elif [[ "$COMMENT" =~ /wizard[[:space:]]+server[[:space:]]+status([[:space:]]+([^[:space:]]+))? ]]; then
|
|
170
170
|
echo "command=status" >> $GITHUB_OUTPUT
|
|
171
171
|
echo "is_valid=true" >> $GITHUB_OUTPUT
|
|
172
172
|
if [[ -n "${BASH_REMATCH[2]}" ]]; then
|
|
@@ -179,7 +179,7 @@ jobs:
|
|
|
179
179
|
fi
|
|
180
180
|
else
|
|
181
181
|
echo "is_valid=false" >> $GITHUB_OUTPUT
|
|
182
|
-
echo "ℹ️
|
|
182
|
+
echo "ℹ️ /wizard server 명령어가 아님"
|
|
183
183
|
fi
|
|
184
184
|
|
|
185
185
|
# -----------------------------------------------------------------
|
|
@@ -519,17 +519,17 @@ jobs:
|
|
|
519
519
|
'### 📋 명령어',
|
|
520
520
|
'| 명령어 | 설명 |',
|
|
521
521
|
'|--------|------|',
|
|
522
|
-
'|
|
|
523
|
-
'|
|
|
524
|
-
'|
|
|
522
|
+
'| `/wizard server build` | 최신 커밋으로 재배포 |',
|
|
523
|
+
'| `/wizard server destroy` | Preview 환경 삭제 |',
|
|
524
|
+
'| `/wizard server status` | 현재 상태 확인 |',
|
|
525
525
|
'',
|
|
526
526
|
'<details>',
|
|
527
527
|
'<summary>🔧 고급 명령어 (다른 Issue/PR에서 제어)</summary>',
|
|
528
528
|
'',
|
|
529
529
|
'```',
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
530
|
+
`/wizard server build ${branchName}`,
|
|
531
|
+
`/wizard server destroy ${branchName}`,
|
|
532
|
+
`/wizard server status ${branchName}`,
|
|
533
533
|
'```',
|
|
534
534
|
'</details>',
|
|
535
535
|
'',
|
|
@@ -594,7 +594,7 @@ jobs:
|
|
|
594
594
|
'',
|
|
595
595
|
'### 💡 다음 단계',
|
|
596
596
|
'1. 위 링크에서 빌드/배포 로그를 확인하세요',
|
|
597
|
-
'2. 문제를 수정한 후 다시 시도하세요:
|
|
597
|
+
'2. 문제를 수정한 후 다시 시도하세요: `/wizard server build`',
|
|
598
598
|
'',
|
|
599
599
|
'---',
|
|
600
600
|
'*🤖 이 댓글은 PR Preview 시스템에 의해 자동 생성되었습니다.*'
|
|
@@ -1115,17 +1115,17 @@ jobs:
|
|
|
1115
1115
|
'### 📋 명령어',
|
|
1116
1116
|
'| 명령어 | 설명 |',
|
|
1117
1117
|
'|--------|------|',
|
|
1118
|
-
'|
|
|
1119
|
-
'|
|
|
1120
|
-
'|
|
|
1118
|
+
'| `/wizard server build` | 최신 커밋으로 재배포 |',
|
|
1119
|
+
'| `/wizard server destroy` | Preview 환경 삭제 |',
|
|
1120
|
+
'| `/wizard server status` | 현재 상태 확인 |',
|
|
1121
1121
|
'',
|
|
1122
1122
|
'<details>',
|
|
1123
1123
|
'<summary>🔧 고급 명령어 (다른 Issue/PR에서 제어)</summary>',
|
|
1124
1124
|
'',
|
|
1125
1125
|
'```',
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1126
|
+
`/wizard server build ${branchName}`,
|
|
1127
|
+
`/wizard server destroy ${branchName}`,
|
|
1128
|
+
`/wizard server status ${branchName}`,
|
|
1129
1129
|
'```',
|
|
1130
1130
|
'</details>',
|
|
1131
1131
|
'',
|
|
@@ -1188,7 +1188,7 @@ jobs:
|
|
|
1188
1188
|
'',
|
|
1189
1189
|
'### 💡 다음 단계',
|
|
1190
1190
|
'1. 위 링크에서 빌드/배포 로그를 확인하세요',
|
|
1191
|
-
'2. 문제를 수정한 후 다시 시도하세요:
|
|
1191
|
+
'2. 문제를 수정한 후 다시 시도하세요: `/wizard server build`',
|
|
1192
1192
|
'',
|
|
1193
1193
|
'---',
|
|
1194
1194
|
'*🤖 이 댓글은 Issue Preview 시스템에 의해 자동 생성되었습니다.*'
|
|
@@ -1219,7 +1219,7 @@ jobs:
|
|
|
1219
1219
|
if: |
|
|
1220
1220
|
(github.event_name == 'pull_request' && github.event.action == 'closed') ||
|
|
1221
1221
|
(github.event_name == 'issues' && github.event.action == 'closed') ||
|
|
1222
|
-
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '
|
|
1222
|
+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '/wizard') && contains(github.event.comment.body, 'server destroy'))
|
|
1223
1223
|
runs-on: ubuntu-latest
|
|
1224
1224
|
steps:
|
|
1225
1225
|
- name: PR/Issue 번호 가져오기
|
|
@@ -1302,7 +1302,7 @@ jobs:
|
|
|
1302
1302
|
`| **컨테이너** | \`${projectName}-pr-${number}\` |`,
|
|
1303
1303
|
'| **상태** | 삭제됨 |',
|
|
1304
1304
|
'',
|
|
1305
|
-
'다시 배포하려면:
|
|
1305
|
+
'다시 배포하려면: `/wizard server build`',
|
|
1306
1306
|
'',
|
|
1307
1307
|
'---',
|
|
1308
1308
|
'*🤖 이 댓글은 PR/Issue Preview 시스템에 의해 자동 생성되었습니다.*'
|
|
@@ -1401,8 +1401,8 @@ jobs:
|
|
|
1401
1401
|
'### 📋 명령어',
|
|
1402
1402
|
'| 명령어 | 설명 |',
|
|
1403
1403
|
'|--------|------|',
|
|
1404
|
-
'|
|
|
1405
|
-
'|
|
|
1404
|
+
'| `/wizard server build` | 최신 커밋으로 재배포 |',
|
|
1405
|
+
'| `/wizard server destroy` | Preview 환경 삭제 |',
|
|
1406
1406
|
'',
|
|
1407
1407
|
'---',
|
|
1408
1408
|
`*🤖 이 댓글은 ${contextType} Preview 시스템에 의해 자동 생성되었습니다.*`
|
|
@@ -1416,7 +1416,7 @@ jobs:
|
|
|
1416
1416
|
`| **컨테이너** | \`${projectName}-pr-${number}\` |`,
|
|
1417
1417
|
'| **상태** | 🔴 Not Found |',
|
|
1418
1418
|
'',
|
|
1419
|
-
'배포하려면:
|
|
1419
|
+
'배포하려면: `/wizard server build`',
|
|
1420
1420
|
'',
|
|
1421
1421
|
'---',
|
|
1422
1422
|
`*🤖 이 댓글은 ${contextType} Preview 시스템에 의해 자동 생성되었습니다.*`
|
|
@@ -1850,17 +1850,17 @@ jobs:
|
|
|
1850
1850
|
'### 📋 명령어',
|
|
1851
1851
|
'| 명령어 | 설명 |',
|
|
1852
1852
|
'|--------|------|',
|
|
1853
|
-
'|
|
|
1854
|
-
'|
|
|
1855
|
-
'|
|
|
1853
|
+
'| `/wizard server build` | 최신 커밋으로 재배포 |',
|
|
1854
|
+
'| `/wizard server destroy` | Preview 환경 삭제 |',
|
|
1855
|
+
'| `/wizard server status` | 현재 상태 확인 |',
|
|
1856
1856
|
'',
|
|
1857
1857
|
'<details>',
|
|
1858
1858
|
'<summary>🔧 고급 명령어 (다른 Issue/PR에서 제어)</summary>',
|
|
1859
1859
|
'',
|
|
1860
1860
|
'```',
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1861
|
+
`/wizard server build ${branchName}`,
|
|
1862
|
+
`/wizard server destroy ${branchName}`,
|
|
1863
|
+
`/wizard server status ${branchName}`,
|
|
1864
1864
|
'```',
|
|
1865
1865
|
'</details>',
|
|
1866
1866
|
'',
|
|
@@ -1921,7 +1921,7 @@ jobs:
|
|
|
1921
1921
|
'',
|
|
1922
1922
|
'### 💡 다음 단계',
|
|
1923
1923
|
'1. 위 링크에서 빌드/배포 로그를 확인하세요',
|
|
1924
|
-
`2. 문제를 수정한 후 다시 시도하세요:
|
|
1924
|
+
`2. 문제를 수정한 후 다시 시도하세요: \`/wizard server build ${branchName}\``,
|
|
1925
1925
|
'',
|
|
1926
1926
|
'---',
|
|
1927
1927
|
'*🤖 이 댓글은 Custom Branch Preview 시스템에 의해 자동 생성되었습니다.*'
|
|
@@ -2051,7 +2051,7 @@ jobs:
|
|
|
2051
2051
|
`| **컨테이너** | \`${containerName}\` |`,
|
|
2052
2052
|
'| **상태** | 삭제됨 |',
|
|
2053
2053
|
'',
|
|
2054
|
-
`다시 배포하려면:
|
|
2054
|
+
`다시 배포하려면: \`/wizard server build ${branchName}\``,
|
|
2055
2055
|
'',
|
|
2056
2056
|
'---',
|
|
2057
2057
|
'*🤖 이 댓글은 Custom Branch Preview 시스템에 의해 자동 생성되었습니다.*'
|
|
@@ -2162,8 +2162,8 @@ jobs:
|
|
|
2162
2162
|
'### 📋 명령어',
|
|
2163
2163
|
'| 명령어 | 설명 |',
|
|
2164
2164
|
'|--------|------|',
|
|
2165
|
-
`|
|
|
2166
|
-
`|
|
|
2165
|
+
`| \`/wizard server build ${branchName}\` | 최신 커밋으로 재배포 |`,
|
|
2166
|
+
`| \`/wizard server destroy ${branchName}\` | Preview 환경 삭제 |`,
|
|
2167
2167
|
'',
|
|
2168
2168
|
'---',
|
|
2169
2169
|
'*🤖 이 댓글은 Custom Branch Preview 시스템에 의해 자동 생성되었습니다.*'
|
|
@@ -2178,7 +2178,7 @@ jobs:
|
|
|
2178
2178
|
`| **컨테이너** | \`${containerName}\` |`,
|
|
2179
2179
|
'| **상태** | 🔴 Not Found |',
|
|
2180
2180
|
'',
|
|
2181
|
-
`배포하려면:
|
|
2181
|
+
`배포하려면: \`/wizard server build ${branchName}\``,
|
|
2182
2182
|
'',
|
|
2183
2183
|
'---',
|
|
2184
2184
|
'*🤖 이 댓글은 Custom Branch Preview 시스템에 의해 자동 생성되었습니다.*'
|