@sleighmaster/bmad 1.5.6 → 1.5.8

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 (30) hide show
  1. package/data/_bmad/bmm/agents/dev.md +1 -1
  2. package/data/_bmad/bmm/data/public-release-templates/release-to-public.yml +99 -0
  3. package/data/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-01-init.md +2 -1
  4. package/data/_bmad/bmm/workflows/2-plan-workflows/create-prd/workflow.md +2 -0
  5. package/data/_bmad/bmm/workflows/4-implementation/dev-story/instructions.xml +3 -2
  6. package/data/_bmad/bmm/workflows/github-setup/instructions.xml +6 -0
  7. package/data/_bmad/bmm/workflows/public-release-setup/instructions.xml +439 -0
  8. package/data/_bmad/bmm/workflows/public-release-setup/workflow.yaml +13 -0
  9. package/data/_bmad/hooks/commit-msg +9 -0
  10. package/data/claude-commands/bmad-bmm-public-release-setup.md +12 -0
  11. package/data/claude-hooks/restrict-to-cwd.sh +63 -0
  12. package/dist/cli.js +2 -0
  13. package/dist/cli.js.map +1 -1
  14. package/dist/commands/install.d.ts +1 -0
  15. package/dist/commands/install.d.ts.map +1 -1
  16. package/dist/commands/install.js +10 -1
  17. package/dist/commands/install.js.map +1 -1
  18. package/dist/commands/update.d.ts +1 -0
  19. package/dist/commands/update.d.ts.map +1 -1
  20. package/dist/commands/update.js +14 -1
  21. package/dist/commands/update.js.map +1 -1
  22. package/dist/services/config-manager.d.ts +1 -0
  23. package/dist/services/config-manager.d.ts.map +1 -1
  24. package/dist/services/config-manager.js +1 -0
  25. package/dist/services/config-manager.js.map +1 -1
  26. package/dist/services/installer.d.ts +10 -0
  27. package/dist/services/installer.d.ts.map +1 -1
  28. package/dist/services/installer.js +149 -11
  29. package/dist/services/installer.js.map +1 -1
  30. package/package.json +1 -1
@@ -25,7 +25,7 @@ You must fully embody this agent's persona and follow all activation instruction
25
25
  <step n="5">Execute tasks/subtasks IN ORDER as written in story file - no skipping, no reordering, no doing what you want</step>
26
26
  <step n="6">Mark task/subtask [x] ONLY when both implementation AND tests are complete and passing</step>
27
27
  <step n="7">Run full test suite after each task - NEVER proceed with failing tests</step>
28
- <step n="8">Execute continuously without pausing until all tasks/subtasks are complete</step>
28
+ <step n="8">Execute the task loop autonomously without asking for user confirmation but ALWAYS complete git commit for each task before proceeding to the next</step>
29
29
  <step n="9">Document in story file Dev Agent Record what was implemented, tests created, and any decisions made</step>
30
30
  <step n="10">Update story file File List with ALL changed files after each task completion</step>
31
31
  <step n="11">NEVER lie about tests being written or passing - tests must actually exist and pass 100%</step>
@@ -0,0 +1,99 @@
1
+ # Release to Public Repository
2
+ # Private 저장소에서 v* 태그 push 시 Public 저장소에 릴리스 생성
3
+ #
4
+ # 필요 Secrets:
5
+ # PUBLIC_REPO_TOKEN - Public 저장소에 대한 Fine-grained PAT
6
+ # (Contents: Read and write)
7
+ #
8
+ # Generated by BMAD Method - Public Release Setup
9
+
10
+ name: Release to Public
11
+
12
+ on:
13
+ push:
14
+ tags:
15
+ - 'v*'
16
+
17
+ permissions:
18
+ contents: read
19
+
20
+ jobs:
21
+ release-to-public:
22
+ runs-on: ubuntu-latest
23
+ steps:
24
+ - name: Checkout source
25
+ uses: actions/checkout@v4
26
+ with:
27
+ fetch-depth: 0
28
+
29
+ - name: Setup runtime
30
+ uses: __SETUP_ACTION__
31
+ with:
32
+ __SETUP_WITH__
33
+
34
+ - name: Install dependencies
35
+ run: __INSTALL_CMD__
36
+
37
+ - name: Build
38
+ run: __BUILD_CMD__
39
+
40
+ - name: Extract version from tag
41
+ id: version
42
+ run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
43
+
44
+ - name: Extract changelog for current version
45
+ id: changelog
46
+ run: |
47
+ # CHANGELOG.md에서 현재 버전 섹션 추출
48
+ VERSION="${{ steps.version.outputs.version }}"
49
+ NOTES=$(awk -v ver="$VERSION" '
50
+ /^## \[/ {
51
+ if (found) exit
52
+ if (index($0, ver)) found=1
53
+ next
54
+ }
55
+ found { print }
56
+ ' CHANGELOG.md)
57
+
58
+ if [ -z "$NOTES" ]; then
59
+ NOTES="Release ${GITHUB_REF_NAME}"
60
+ fi
61
+
62
+ # multiline output
63
+ {
64
+ echo "notes<<EOF"
65
+ echo "$NOTES"
66
+ echo "EOF"
67
+ } >> "$GITHUB_OUTPUT"
68
+
69
+ - name: Create release on public repo
70
+ uses: softprops/action-gh-release@v2
71
+ with:
72
+ repository: __PUBLIC_REPO__
73
+ token: ${{ secrets.PUBLIC_REPO_TOKEN }}
74
+ tag_name: ${{ github.ref_name }}
75
+ name: ${{ github.ref_name }}
76
+ body: ${{ steps.changelog.outputs.notes }}
77
+ files: |
78
+ __ARTIFACT_PATTERNS__
79
+
80
+ - name: Sync CHANGELOG to public repo
81
+ env:
82
+ GH_TOKEN: ${{ secrets.PUBLIC_REPO_TOKEN }}
83
+ run: |
84
+ git clone "https://x-access-token:${GH_TOKEN}@github.com/__PUBLIC_REPO__.git" _public_repo
85
+ cp CHANGELOG.md _public_repo/CHANGELOG.md
86
+ cd _public_repo
87
+
88
+ git config user.name "github-actions[bot]"
89
+ git config user.email "github-actions[bot]@users.noreply.github.com"
90
+
91
+ # 변경사항이 있을 때만 커밋
92
+ if git diff --quiet CHANGELOG.md; then
93
+ echo "CHANGELOG.md is already up to date"
94
+ else
95
+ git add CHANGELOG.md
96
+ git commit -m "docs: CHANGELOG.md 동기화 (${{ github.ref_name }})"
97
+ git push origin main
98
+ echo "CHANGELOG.md synced successfully"
99
+ fi
@@ -114,7 +114,8 @@ Try to discover the following:
114
114
 
115
115
  **Document Setup:**
116
116
 
117
- - Copy the template from `{prdTemplate}` to `{outputFile}`
117
+ - Copy the template from `{prdTemplate}` to `{outputFile}` (this is `{planning_artifacts}/prd.md`)
118
+ - ⚠️ Do NOT save to `{prd_artifacts}` — that path is for sharded PRD sections, not the main PRD document
118
119
  - Initialize frontmatter with proper structure including inputDocuments array.
119
120
 
120
121
  #### C. Present Initialization Results
@@ -133,6 +133,8 @@ Load and read full config from {main_config} and resolve:
133
133
 
134
134
  ✅ YOU MUST ALWAYS SPEAK OUTPUT In your Agent communication style with the configured `{communication_language}`.
135
135
 
136
+ ⚠️ **CRITICAL: PRD Output Path** — The PRD document MUST be saved to `{planning_artifacts}/prd.md` as defined in each step file's `outputFile`. Do NOT use `prd_artifacts` — that config value is only for sharded PRD sections used by other workflows.
137
+
136
138
  ### 3. Route to Appropriate Workflow
137
139
 
138
140
  **IF mode == create:**
@@ -298,7 +298,7 @@
298
298
 
299
299
  <critical>NEVER implement anything not mapped to a specific task/subtask in the story file</critical>
300
300
  <critical>NEVER proceed to next task until current task/subtask is complete AND tests pass</critical>
301
- <critical>Execute continuously without pausing until all tasks/subtasks are complete or explicit HALT condition</critical>
301
+ <critical>Execute the Step 5→6→7→8 loop autonomously for each task without asking for user confirmation but ALWAYS complete Step 8 (including git commit) before proceeding to the next task</critical>
302
302
  <critical>Do NOT propose to pause for review until Step 9 completion gates are satisfied</critical>
303
303
  </step>
304
304
 
@@ -349,7 +349,8 @@
349
349
  <action>Update File List section with ALL new, modified, or deleted files (paths relative to repo root)</action>
350
350
  <action>Add completion notes to Dev Agent Record summarizing what was ACTUALLY implemented and tested</action>
351
351
 
352
- <!-- GIT COMMIT FOR COMPLETED TASK -->
352
+ <!-- GIT COMMIT FOR COMPLETED TASK - MANDATORY -->
353
+ <critical>Git commit is NOT a pause — it is a MANDATORY part of each task completion cycle. Do NOT batch commits across multiple tasks.</critical>
353
354
  <check if="git repository detected">
354
355
  <action>변경된 파일 스테이징: git add {{modified_files_for_this_task}}</action>
355
356
  <action>태스크 커밋 생성:
@@ -167,6 +167,8 @@
167
167
 
168
168
  <check if="user chooses 1 (squash-and-merge)">
169
169
  <action>gh repo edit --enable-squash-merge --enable-merge-commit --enable-rebase-merge=false --delete-branch-on-merge</action>
170
+ <action>config.yaml에 merge_strategy 저장: _bmad/bmm/config.yaml의 merge_strategy 필드를 squash-and-merge로 업데이트</action>
171
+ <action>CLAUDE.md 머지 명령 업데이트: CLAUDE.md에서 `gh pr merge` 명령을 찾아 `--squash` 플래그로 교체, 단계명 "Squash Merge"</action>
170
172
  <output>✅ 저장소 머지 규칙 설정 완료:
171
173
  - Squash Merge: 허용
172
174
  - Merge Commit: 허용
@@ -176,6 +178,8 @@
176
178
 
177
179
  <check if="user chooses 2 (merge-only)">
178
180
  <action>gh repo edit --enable-merge-commit --enable-squash-merge=false --enable-rebase-merge=false --delete-branch-on-merge</action>
181
+ <action>config.yaml에 merge_strategy 저장: _bmad/bmm/config.yaml의 merge_strategy 필드를 merge-only로 업데이트</action>
182
+ <action>CLAUDE.md 머지 명령 업데이트: CLAUDE.md에서 `gh pr merge` 명령을 찾아 `--merge` 플래그로 교체, 단계명 "Merge"</action>
179
183
  <output>✅ 저장소 머지 규칙 설정 완료:
180
184
  - Merge Commit: 허용
181
185
  - Squash Merge: 비활성화
@@ -185,6 +189,8 @@
185
189
 
186
190
  <check if="user chooses 3 (squash-only)">
187
191
  <action>gh repo edit --enable-squash-merge --enable-merge-commit=false --enable-rebase-merge=false --delete-branch-on-merge</action>
192
+ <action>config.yaml에 merge_strategy 저장: _bmad/bmm/config.yaml의 merge_strategy 필드를 squash-only로 업데이트</action>
193
+ <action>CLAUDE.md 머지 명령 업데이트: CLAUDE.md에서 `gh pr merge` 명령을 찾아 `--squash` 플래그로 교체, 단계명 "Squash Merge"</action>
188
194
  <output>✅ 저장소 머지 규칙 설정 완료:
189
195
  - Squash Merge: 허용
190
196
  - Merge Commit: 비활성화
@@ -0,0 +1,439 @@
1
+ <workflow>
2
+ <critical>The workflow execution engine is governed by: {project-root}/_bmad/core/tasks/workflow.xml</critical>
3
+ <critical>You MUST have already loaded and processed: {installed_path}/workflow.yaml</critical>
4
+ <critical>Communicate all responses in {communication_language}</critical>
5
+
6
+ <step n="1" goal="환경 확인">
7
+ <critical>🔧 PUBLIC RELEASE SETUP - Private → Public 릴리스 자동화 설정</critical>
8
+
9
+ <output>📋 **Public 릴리스 자동화 설정**
10
+
11
+ 이 워크플로우는 Private 저장소에서 태그 push 시 Public 저장소에
12
+ 자동으로 릴리스(바이너리 + 문서)를 배포하는 파이프라인을 설정합니다:
13
+
14
+ - Public 릴리스 저장소 생성
15
+ - GitHub Actions 워크플로우 생성 (release-to-public.yml)
16
+ - Secrets (PAT) 설정 가이드
17
+
18
+ </output>
19
+
20
+ <action>git repository 확인: git rev-parse --git-dir</action>
21
+ <check if="git repository NOT detected">
22
+ <output>⚠️ Git 저장소가 감지되지 않습니다. Git 저장소에서 실행해주세요.</output>
23
+ <action>HALT</action>
24
+ </check>
25
+
26
+ <action>gh CLI 확인: gh --version</action>
27
+ <check if="gh CLI not installed">
28
+ <output>⚠️ GitHub CLI(gh)가 설치되지 않았습니다.
29
+
30
+ 설치 방법:
31
+ - Windows: winget install GitHub.cli
32
+ - macOS: brew install gh
33
+ - Linux: https://github.com/cli/cli#installation
34
+
35
+ 설치 후 `gh auth login`으로 인증해주세요.
36
+ </output>
37
+ <action>HALT</action>
38
+ </check>
39
+
40
+ <action>gh CLI 인증 확인: gh auth status</action>
41
+ <check if="gh auth 실패">
42
+ <output>⚠️ GitHub CLI 인증이 필요합니다.</output>
43
+ <ask>`gh auth login`을 실행하시겠습니까? [y/n]</ask>
44
+ <check if="user confirms">
45
+ <action>gh auth login 안내 제공</action>
46
+ </check>
47
+ <check if="user cancels">
48
+ <action>HALT</action>
49
+ </check>
50
+ </check>
51
+
52
+ <action>.github/workflows 디렉토리 확인 (없으면 생성)</action>
53
+
54
+ <action>현재 저장소 정보 추출: gh repo view --json owner,name -q '.owner.login + "/" + .name'</action>
55
+ <action>{{private_owner}} = owner, {{private_repo}} = name</action>
56
+ <output>✅ 환경 확인 완료
57
+ - Private 저장소: {{private_owner}}/{{private_repo}}
58
+ </output>
59
+ </step>
60
+
61
+ <step n="2" goal="프로젝트 정보 수집">
62
+ <critical>📝 PROJECT INFO - 빌드 및 릴리스 정보 수집</critical>
63
+
64
+ <ask>Public 릴리스 저장소 이름을 입력해주세요 (예: {{private_repo}}-releases):</ask>
65
+ <action>{{public_repo_name}} = 사용자 입력값</action>
66
+
67
+ <ask>프로젝트 설명을 입력해주세요 (Public 저장소 description):</ask>
68
+ <action>{{project_description}} = 사용자 입력값</action>
69
+
70
+ <output>📋 **빌드 런타임 선택**
71
+
72
+ 프로젝트의 빌드 런타임을 선택해주세요:
73
+ 1. Node.js — npm ci / npm run build
74
+ 2. Go — go build
75
+ 3. Rust — cargo build --release
76
+ 4. .NET — dotnet publish
77
+ 5. Python — python -m build
78
+ 6. Java — ./gradlew build
79
+ 7. 커스텀 — 직접 설정
80
+ </output>
81
+
82
+ <ask>빌드 런타임을 선택해주세요: [1-7]</ask>
83
+
84
+ <check if="user chooses 1 (Node.js)">
85
+ <action>{{setup_action}} = "actions/setup-node@v4"</action>
86
+ <action>{{setup_with}} = "node-version: '20'"</action>
87
+ <action>{{install_cmd}} = "npm ci"</action>
88
+ <action>{{build_cmd}} = "npm run build"</action>
89
+ <action>{{artifact_path}} = "dist/"</action>
90
+ <action>{{runtime_label}} = "Node.js"</action>
91
+ </check>
92
+
93
+ <check if="user chooses 2 (Go)">
94
+ <action>{{setup_action}} = "actions/setup-go@v5"</action>
95
+ <action>{{setup_with}} = "go-version: 'stable'"</action>
96
+ <action>{{install_cmd}} = ""</action>
97
+ <action>{{build_cmd}} = "go build -o ./build/ ./..."</action>
98
+ <action>{{artifact_path}} = "build/"</action>
99
+ <action>{{runtime_label}} = "Go"</action>
100
+ </check>
101
+
102
+ <check if="user chooses 3 (Rust)">
103
+ <action>{{setup_action}} = "dtolnay/rust-toolchain@stable"</action>
104
+ <action>{{setup_with}} = ""</action>
105
+ <action>{{install_cmd}} = ""</action>
106
+ <action>{{build_cmd}} = "cargo build --release"</action>
107
+ <action>{{artifact_path}} = "target/release/"</action>
108
+ <action>{{runtime_label}} = "Rust"</action>
109
+ </check>
110
+
111
+ <check if="user chooses 4 (.NET)">
112
+ <action>{{setup_action}} = "actions/setup-dotnet@v4"</action>
113
+ <action>{{setup_with}} = "dotnet-version: '8.0.x'"</action>
114
+ <action>{{install_cmd}} = "dotnet restore"</action>
115
+ <action>{{build_cmd}} = "dotnet publish -c Release -o ./publish"</action>
116
+ <action>{{artifact_path}} = "publish/"</action>
117
+ <action>{{runtime_label}} = ".NET"</action>
118
+ </check>
119
+
120
+ <check if="user chooses 5 (Python)">
121
+ <action>{{setup_action}} = "actions/setup-python@v5"</action>
122
+ <action>{{setup_with}} = "python-version: '3.x'"</action>
123
+ <action>{{install_cmd}} = "pip install -r requirements.txt"</action>
124
+ <action>{{build_cmd}} = "python -m build"</action>
125
+ <action>{{artifact_path}} = "dist/"</action>
126
+ <action>{{runtime_label}} = "Python"</action>
127
+ </check>
128
+
129
+ <check if="user chooses 6 (Java)">
130
+ <action>{{setup_action}} = "actions/setup-java@v4"</action>
131
+ <action>{{setup_with}} = "distribution: 'temurin'\n java-version: '21'"</action>
132
+ <action>{{install_cmd}} = ""</action>
133
+ <action>{{build_cmd}} = "./gradlew build"</action>
134
+ <action>{{artifact_path}} = "build/libs/"</action>
135
+ <action>{{runtime_label}} = "Java"</action>
136
+ </check>
137
+
138
+ <check if="user chooses 7 (커스텀)">
139
+ <ask>런타임 setup action을 입력해주세요 (없으면 빈 값):</ask>
140
+ <action>{{setup_action}} = 사용자 입력값</action>
141
+ <check if="{{setup_action}} is not empty">
142
+ <ask>setup action의 with 매개변수를 입력해주세요 (없으면 빈 값):</ask>
143
+ <action>{{setup_with}} = 사용자 입력값</action>
144
+ </check>
145
+ <ask>의존성 설치 명령어를 입력해주세요 (없으면 빈 값):</ask>
146
+ <action>{{install_cmd}} = 사용자 입력값</action>
147
+ <ask>빌드 명령어를 입력해주세요:</ask>
148
+ <action>{{build_cmd}} = 사용자 입력값</action>
149
+ <ask>빌드 결과물 경로를 입력해주세요:</ask>
150
+ <action>{{artifact_path}} = 사용자 입력값</action>
151
+ <action>{{runtime_label}} = "커스텀"</action>
152
+ </check>
153
+
154
+ <output>ℹ️ 기본값이 설정되었습니다. 다음에서 세부 사항을 조정할 수 있습니다.</output>
155
+
156
+ <ask>빌드 명령어를 수정하시겠습니까? (현재: {{build_cmd}}) [y/n]</ask>
157
+ <check if="user confirms">
158
+ <ask>새 빌드 명령어를 입력해주세요:</ask>
159
+ <action>{{build_cmd}} = 사용자 입력값</action>
160
+ </check>
161
+
162
+ <ask>설치 명령어를 수정하시겠습니까? (현재: {{install_cmd}}) [y/n]</ask>
163
+ <check if="user confirms">
164
+ <ask>새 설치 명령어를 입력해주세요:</ask>
165
+ <action>{{install_cmd}} = 사용자 입력값</action>
166
+ </check>
167
+
168
+ <ask>빌드 결과물 경로를 수정하시겠습니까? (현재: {{artifact_path}}) [y/n]</ask>
169
+ <check if="user confirms">
170
+ <ask>새 결과물 경로를 입력해주세요:</ask>
171
+ <action>{{artifact_path}} = 사용자 입력값</action>
172
+ </check>
173
+
174
+ <ask>릴리스에 첨부할 파일 패턴을 입력해주세요 (예: dist/*.zip, dist/*.tar.gz 등, 여러 줄 가능):</ask>
175
+ <action>{{artifact_patterns}} = 사용자 입력값</action>
176
+
177
+ <ask>라이선스를 선택해주세요:
178
+ 1. MIT
179
+ 2. Apache-2.0
180
+ 3. GPL-3.0
181
+ 4. BSD-3-Clause
182
+ 5. 없음 (건너뛰기)
183
+ </ask>
184
+ <action>{{license_type}} = 사용자 선택값</action>
185
+
186
+ <output>📋 **수집된 정보 요약**
187
+
188
+ - Public 저장소: {{private_owner}}/{{public_repo_name}}
189
+ - 설명: {{project_description}}
190
+ - 런타임: {{runtime_label}}
191
+ - 빌드: {{build_cmd}}
192
+ - 설치: {{install_cmd}}
193
+ - 결과물 경로: {{artifact_path}}
194
+ - 릴리스 패턴: {{artifact_patterns}}
195
+ - 라이선스: {{license_type}}
196
+ </output>
197
+
198
+ <ask>위 정보가 맞습니까? [y/n]</ask>
199
+ <check if="user cancels">
200
+ <output>❌ 설정을 취소합니다. 다시 실행해주세요.</output>
201
+ <action>HALT</action>
202
+ </check>
203
+ </step>
204
+
205
+ <step n="3" goal="Public 저장소 생성">
206
+ <critical>🏗️ CREATE PUBLIC REPO - Public 릴리스 저장소 생성</critical>
207
+
208
+ <action>저장소 존재 확인: gh repo view {{private_owner}}/{{public_repo_name}} 2>/dev/null</action>
209
+
210
+ <check if="저장소 이미 존재">
211
+ <output>⚠️ {{private_owner}}/{{public_repo_name}} 저장소가 이미 존재합니다.</output>
212
+ <ask>기존 저장소를 사용하시겠습니까? [y/n]</ask>
213
+ <check if="user cancels">
214
+ <output>❌ 설정을 취소합니다.</output>
215
+ <action>HALT</action>
216
+ </check>
217
+ <output>ℹ️ 기존 저장소를 사용합니다.</output>
218
+ </check>
219
+
220
+ <check if="저장소 없음">
221
+ <action>gh repo create {{private_owner}}/{{public_repo_name}} --public --description "{{project_description}}"</action>
222
+ <output>✅ Public 저장소 생성됨: {{private_owner}}/{{public_repo_name}}</output>
223
+
224
+ <!-- 초기 파일 생성 및 Push -->
225
+ <action>임시 디렉토리 생성 및 이동</action>
226
+ <action>git clone https://github.com/{{private_owner}}/{{public_repo_name}}.git temp-public-repo</action>
227
+ <action>cd temp-public-repo</action>
228
+
229
+ <!-- README.md -->
230
+ <action>README.md 생성:
231
+ # {{public_repo_name}}
232
+
233
+ {{project_description}}
234
+
235
+ ## 설치
236
+
237
+ [릴리스 페이지](https://github.com/{{private_owner}}/{{public_repo_name}}/releases)에서
238
+ 최신 버전을 다운로드하세요.
239
+
240
+ ## 라이선스
241
+
242
+ {{license_type}} 라이선스에 따라 배포됩니다.
243
+ </action>
244
+
245
+ <!-- CHANGELOG.md -->
246
+ <action>CHANGELOG.md 생성:
247
+ # Changelog
248
+
249
+ 이 프로젝트의 주요 변경사항을 기록합니다.
250
+
251
+ 형식은 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/)를 따르며,
252
+ [Semantic Versioning](https://semver.org/lang/ko/)을 준수합니다.
253
+ </action>
254
+
255
+ <!-- LICENSE (선택된 경우) -->
256
+ <check if="{{license_type}} != 없음">
257
+ <action>LICENSE 파일 생성 (선택된 라이선스 유형에 맞는 전문)</action>
258
+ </check>
259
+
260
+ <action>git add -A</action>
261
+ <action>git commit -m "chore: 저장소 초기화
262
+
263
+ Generated by BMAD Method - Public Release Setup"</action>
264
+ <action>git push origin main</action>
265
+ <action>임시 디렉토리 정리 (cd .. && rm -rf temp-public-repo)</action>
266
+
267
+ <output>✅ 초기 파일 Push 완료:
268
+ - README.md
269
+ - CHANGELOG.md
270
+ {{license_file_note}}
271
+ </output>
272
+ </check>
273
+ </step>
274
+
275
+ <step n="4" goal="Actions 워크플로우 생성">
276
+ <critical>⚙️ ACTIONS WORKFLOW - release-to-public.yml 생성</critical>
277
+
278
+ <action>{{release_templates}}/release-to-public.yml 기본 템플릿 로드</action>
279
+
280
+ <action>플레이스홀더 교체:
281
+ - __PUBLIC_REPO__ → {{private_owner}}/{{public_repo_name}}
282
+ - __SETUP_ACTION__ → {{setup_action}} (비어있으면 해당 step 제거)
283
+ - __SETUP_WITH__ → {{setup_with}} (비어있으면 with 블록 제거)
284
+ - __INSTALL_CMD__ → {{install_cmd}} (비어있으면 해당 step 제거)
285
+ - __BUILD_CMD__ → {{build_cmd}}
286
+ - __ARTIFACT_PATH__ → {{artifact_path}}
287
+ - __ARTIFACT_PATTERNS__ → {{artifact_patterns}}
288
+ </action>
289
+
290
+ <check if="{{target_workflows_dir}}/release-to-public.yml 이미 존재">
291
+ <output>⚠️ release-to-public.yml이 이미 존재합니다.</output>
292
+ <ask>덮어쓰시겠습니까? [y/n]</ask>
293
+ <check if="user cancels">
294
+ <output>ℹ️ 기존 파일을 유지합니다.</output>
295
+ </check>
296
+ <check if="user confirms">
297
+ <action>기존 파일 백업: release-to-public.yml.backup</action>
298
+ <action>생성된 워크플로우를 {{target_workflows_dir}}/release-to-public.yml에 저장</action>
299
+ <output>✅ release-to-public.yml 덮어쓰기 완료 (백업 생성됨)</output>
300
+ </check>
301
+ </check>
302
+
303
+ <check if="{{target_workflows_dir}}/release-to-public.yml 없음">
304
+ <action>생성된 워크플로우를 {{target_workflows_dir}}/release-to-public.yml에 저장</action>
305
+ <output>✅ release-to-public.yml 생성 완료</output>
306
+ </check>
307
+
308
+ <output>📄 **생성된 워크플로우 요약**
309
+
310
+ 파일: .github/workflows/release-to-public.yml
311
+ 트리거: v* 태그 push
312
+ 동작:
313
+ 1. 소스 체크아웃
314
+ 2. {{runtime_label}} 런타임 설정
315
+ 3. 의존성 설치 및 빌드
316
+ 4. CHANGELOG에서 릴리스 노트 추출
317
+ 5. Public 저장소에 릴리스 생성 + 아티팩트 첨부
318
+ 6. Public 저장소에 CHANGELOG.md 동기화
319
+ </output>
320
+ </step>
321
+
322
+ <step n="5" goal="Secrets 설정">
323
+ <critical>🔑 SECRETS - GitHub Actions Secrets 설정</critical>
324
+
325
+ <output>📋 **Fine-grained Personal Access Token (PAT) 생성 가이드**
326
+
327
+ Public 저장소에 릴리스를 배포하려면 PAT가 필요합니다.
328
+
329
+ **생성 방법:**
330
+ 1. GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens
331
+ 2. "Generate new token" 클릭
332
+ 3. 설정:
333
+ - Token name: `public-release-{{public_repo_name}}`
334
+ - Expiration: 원하는 기간 (권장: 90일, 이후 갱신)
335
+ - Resource owner: {{private_owner}}
336
+ - Repository access: "Only select repositories" → **{{public_repo_name}}** 선택
337
+ - Permissions:
338
+ - Contents: Read and write
339
+ - Metadata: Read-only (자동 선택됨)
340
+ 4. "Generate token" 클릭 후 토큰 복사
341
+
342
+ ⚠️ 토큰은 한 번만 표시됩니다. 반드시 복사해두세요!
343
+ </output>
344
+
345
+ <ask>PAT를 생성하셨습니까? Secret을 설정할 준비가 되셨습니까? [y/n]</ask>
346
+
347
+ <check if="user confirms">
348
+ <output>ℹ️ 다음 명령어로 Secret을 설정합니다:
349
+ `gh secret set PUBLIC_REPO_TOKEN -R {{private_owner}}/{{private_repo}}`
350
+
351
+ 프롬프트에 복사한 PAT 토큰을 붙여넣어주세요.
352
+ </output>
353
+
354
+ <action>gh secret set PUBLIC_REPO_TOKEN -R {{private_owner}}/{{private_repo}}</action>
355
+
356
+ <check if="secret 설정 성공">
357
+ <output>✅ PUBLIC_REPO_TOKEN Secret 설정 완료</output>
358
+ </check>
359
+
360
+ <check if="secret 설정 실패">
361
+ <output>⚠️ Secret 설정에 실패했습니다.
362
+
363
+ 수동으로 설정하려면:
364
+ 1. GitHub → {{private_owner}}/{{private_repo}} → Settings → Secrets and variables → Actions
365
+ 2. "New repository secret" 클릭
366
+ 3. Name: PUBLIC_REPO_TOKEN
367
+ 4. Secret: 생성한 PAT 토큰
368
+ 5. "Add secret" 클릭
369
+ </output>
370
+ </check>
371
+ </check>
372
+
373
+ <check if="user cancels">
374
+ <output>ℹ️ Secret 설정을 건너뜁니다.
375
+
376
+ 나중에 설정하려면:
377
+ `gh secret set PUBLIC_REPO_TOKEN -R {{private_owner}}/{{private_repo}}`
378
+
379
+ 또는 GitHub 웹에서:
380
+ {{private_owner}}/{{private_repo}} → Settings → Secrets and variables → Actions
381
+ </output>
382
+ </check>
383
+ </step>
384
+
385
+ <step n="6" goal="완료 및 안내">
386
+ <output>🎉 **Public 릴리스 자동화 설정 완료!**
387
+
388
+ **설정된 항목:**
389
+ ✅ Public 저장소: {{private_owner}}/{{public_repo_name}}
390
+ ✅ Actions 워크플로우: .github/workflows/release-to-public.yml
391
+ ✅ Secret: PUBLIC_REPO_TOKEN
392
+
393
+ **릴리스 방법:**
394
+ 1. CHANGELOG.md에 새 버전 섹션 추가
395
+ 2. 태그 생성 및 Push:
396
+ ```
397
+ git tag v1.0.0
398
+ git push origin v1.0.0
399
+ ```
400
+ 3. GitHub Actions가 자동으로:
401
+ - 프로젝트 빌드
402
+ - CHANGELOG에서 릴리스 노트 추출
403
+ - Public 저장소에 릴리스 생성 + 아티팩트 첨부
404
+ - Public 저장소에 CHANGELOG.md 동기화
405
+
406
+ **확인:**
407
+ - Private Actions: https://github.com/{{private_owner}}/{{private_repo}}/actions
408
+ - Public Releases: https://github.com/{{private_owner}}/{{public_repo_name}}/releases
409
+
410
+ **주의사항:**
411
+ - PAT 토큰은 만료 기간이 있으므로 갱신이 필요합니다
412
+ - Private 저장소의 소스 코드는 Public에 노출되지 않습니다
413
+ - 릴리스에 첨부되는 아티팩트만 공개됩니다
414
+ </output>
415
+
416
+ <ask>변경사항(.github/workflows/release-to-public.yml)을 지금 커밋하시겠습니까? [y/n]</ask>
417
+
418
+ <check if="user confirms">
419
+ <action>git add .github/workflows/release-to-public.yml</action>
420
+ <action>git commit -m "ci: Public 릴리스 자동 배포 워크플로우 추가
421
+
422
+ - release-to-public.yml: v* 태그 push 시 Public 저장소에 릴리스 배포
423
+ - 빌드 → 아티팩트 첨부 → CHANGELOG 동기화
424
+
425
+ Generated by BMAD Method"</action>
426
+ <output>✅ 커밋 완료!
427
+
428
+ Push하려면: `git push origin {{current_branch}}`
429
+ </output>
430
+
431
+ <ask>지금 Push하시겠습니까? [y/n]</ask>
432
+ <check if="user confirms">
433
+ <action>git push origin {{current_branch}}</action>
434
+ <output>✅ Push 완료!</output>
435
+ </check>
436
+ </check>
437
+ </step>
438
+
439
+ </workflow>
@@ -0,0 +1,13 @@
1
+ name: public-release-setup
2
+ description: "Private 저장소에서 Public 릴리스 저장소로 자동 배포 설정"
3
+ author: "BMAD"
4
+
5
+ config_source: "{project-root}/_bmad/bmm/config.yaml"
6
+ installed_path: "{project-root}/_bmad/bmm/workflows/public-release-setup"
7
+ instructions: "{installed_path}/instructions.xml"
8
+ template: false
9
+ standalone: true
10
+
11
+ variables:
12
+ release_templates: "{project-root}/_bmad/bmm/data/public-release-templates"
13
+ target_workflows_dir: "{project-root}/.github/workflows"
@@ -58,4 +58,13 @@ if ! echo "$FIRST_LINE" | grep -qE "$PATTERN"; then
58
58
  exit 1
59
59
  fi
60
60
 
61
+ # 한글 권장 (description 부분) - 차단하지 않고 경고만 표시
62
+ DESC=$(echo "$FIRST_LINE" | sed 's/^[a-z]*([^)]*): //' | sed 's/^[a-z]*: //')
63
+ if ! echo "$DESC" | grep -P '[\xEA-\xED][\x80-\xBF][\x80-\xBF]' > /dev/null 2>&1; then
64
+ echo ""
65
+ echo "NOTE: 커밋 메시지 제목을 한글로 작성하는 것을 권장합니다."
66
+ echo " 예: feat(cli): Claude Code 보안 훅 추가"
67
+ echo ""
68
+ fi
69
+
61
70
  exit 0
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: 'public-release-setup'
3
+ description: 'Private 저장소에서 Public 릴리스 저장소로 자동 배포 설정'
4
+ ---
5
+
6
+ <steps CRITICAL="TRUE">
7
+ 1. Always LOAD the FULL @{project-root}/_bmad/core/tasks/workflow.xml
8
+ 2. READ its entire contents
9
+ 3. Pass the yaml path as 'workflow-config' parameter to workflow.xml: {project-root}/_bmad/bmm/workflows/public-release-setup/workflow.yaml
10
+ 4. Follow workflow.xml instructions EXACTLY as written
11
+ 5. Save outputs after EACH section
12
+ </steps>