project-auto-wizard 0.3.0 → 0.3.3
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 +1 -1
- 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/workflows/common/PROJECT-COMMON-AI-PR-SUMMARY.yaml +12 -8
- package/payload/workflows/common/PROJECT-COMMON-AUTO-CHANGELOG-CONTROL.yaml +30 -3
- package/src/commands/interactive.js +8 -5
- package/src/core/branches.js +10 -0
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.
|
|
20
|
+
## 최신 버전 : v0.3.1 (2026-08-18)
|
|
21
21
|
|
|
22
22
|
[전체 버전 기록 보기](CHANGELOG.md)
|
|
23
23
|
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -9,13 +9,15 @@
|
|
|
9
9
|
# changelog (user API key -> GitHub Models -> rule-based fallback).
|
|
10
10
|
# The prompt includes commit subjects plus a capped `git diff --stat`.
|
|
11
11
|
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
# is
|
|
12
|
+
# On release PRs (head branch == {{DEVELOP_BRANCH}}) this job is skipped.
|
|
13
|
+
# PROJECT-COMMON-AUTO-CHANGELOG-CONTROL owns that case: it confirms
|
|
14
|
+
# the version first, then posts the AI summary itself using the
|
|
15
|
+
# confirmed version. Running this workflow too would post a comment
|
|
16
|
+
# with the pre-bump version — it always checks out the head branch
|
|
17
|
+
# before AUTO-CHANGELOG-CONTROL's version-confirm commit lands, and
|
|
18
|
+
# that commit is pushed with GITHUB_TOKEN, which GitHub does not use
|
|
19
|
+
# to retrigger pull_request events, so there would be no later run to
|
|
20
|
+
# correct it.
|
|
19
21
|
# ===================================================================
|
|
20
22
|
|
|
21
23
|
name: PROJECT-AI-PR-SUMMARY
|
|
@@ -33,7 +35,9 @@ permissions:
|
|
|
33
35
|
jobs:
|
|
34
36
|
ai-pr-summary:
|
|
35
37
|
name: Post AI summary comment
|
|
36
|
-
if:
|
|
38
|
+
if: >-
|
|
39
|
+
github.event.pull_request.head.repo.full_name == github.repository &&
|
|
40
|
+
github.event.pull_request.head.ref != '{{DEVELOP_BRANCH}}'
|
|
37
41
|
runs-on: ubuntu-latest
|
|
38
42
|
steps:
|
|
39
43
|
- name: Checkout PR head
|
|
@@ -17,9 +17,14 @@
|
|
|
17
17
|
# - The AI prompt includes commit subjects plus a capped
|
|
18
18
|
# `git diff --stat` (file-level change summary, no diff body)
|
|
19
19
|
# for richer context without token-cost blowup.
|
|
20
|
-
# 3.
|
|
20
|
+
# 3. Posts the same summary as a PR comment (this replaces
|
|
21
|
+
# PROJECT-COMMON-AI-PR-SUMMARY for release PRs, which skips them —
|
|
22
|
+
# that workflow would otherwise post the pre-bump version, since it
|
|
23
|
+
# runs before this job's version-confirm commit lands and that
|
|
24
|
+
# commit's GITHUB_TOKEN push doesn't retrigger pull_request events)
|
|
25
|
+
# 4. Updates CHANGELOG.json / CHANGELOG.md and commits to the PR head
|
|
21
26
|
# branch with [skip ci]
|
|
22
|
-
#
|
|
27
|
+
# 5. Enables automerge (gh pr merge --auto --merge)
|
|
23
28
|
#
|
|
24
29
|
# The merge-commit subject carries the release-confirm pattern
|
|
25
30
|
# "chore(release):" — keep in sync with PROJECT-COMMON-VERSION-CONTROL
|
|
@@ -152,6 +157,28 @@ jobs:
|
|
|
152
157
|
# update-from-summary reads ./pr_body.md
|
|
153
158
|
cp summary.md pr_body.md
|
|
154
159
|
|
|
160
|
+
- name: Post AI summary comment
|
|
161
|
+
continue-on-error: true
|
|
162
|
+
run: |
|
|
163
|
+
PR_NUMBER=${{ github.event.pull_request.number }}
|
|
164
|
+
|
|
165
|
+
{
|
|
166
|
+
echo "🤖 **AI Summary (project-auto-wizard)**"
|
|
167
|
+
echo ""
|
|
168
|
+
cat summary.md
|
|
169
|
+
} > comment_body.md
|
|
170
|
+
|
|
171
|
+
python3 -c 'import json; print(json.dumps({"body": open("comment_body.md", encoding="utf-8").read()}))' > comment_payload.json
|
|
172
|
+
|
|
173
|
+
curl -sf -H "Authorization: token ${{ github.token }}" \
|
|
174
|
+
-H "Content-Type: application/json" \
|
|
175
|
+
-X POST \
|
|
176
|
+
-d @comment_payload.json \
|
|
177
|
+
"https://api.github.com/repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" > /dev/null \
|
|
178
|
+
|| echo "comment post failed — continuing (this workflow never blocks the release)"
|
|
179
|
+
|
|
180
|
+
rm -f comment_body.md comment_payload.json
|
|
181
|
+
|
|
155
182
|
- name: Update CHANGELOG from summary
|
|
156
183
|
run: |
|
|
157
184
|
# note: `grep | sed || echo default` never fires the default (the
|
|
@@ -174,7 +201,7 @@ jobs:
|
|
|
174
201
|
VERSION="${{ steps.bump.outputs.new_version }}"
|
|
175
202
|
|
|
176
203
|
# Working files must not land in the repo
|
|
177
|
-
rm -f pr_body.md summary.md commits.txt diff_stat.txt
|
|
204
|
+
rm -f pr_body.md summary.md commits.txt diff_stat.txt comment_body.md comment_payload.json
|
|
178
205
|
|
|
179
206
|
git add -A
|
|
180
207
|
|
|
@@ -9,7 +9,7 @@ import { detectTypes, detectVersion, detectDefaultBranch, detectRepoName, makeRe
|
|
|
9
9
|
import { parseExisting } from "../core/version-yml.js";
|
|
10
10
|
import { runBreakingCheck } from "../core/breaking-check.js";
|
|
11
11
|
import { resolveProjectPaths } from "../core/paths-resolve.js";
|
|
12
|
-
import { resolveBranchConfig, detectRemoteBranches, ensureDevelopBranch } from "../core/branches.js";
|
|
12
|
+
import { resolveBranchConfig, detectRemoteBranches, ensureDevelopBranch, sortBranchesForSelection } from "../core/branches.js";
|
|
13
13
|
import { askAllOptionalWorkflows } from "../core/options-ask.js";
|
|
14
14
|
import { promptEnvPlan } from "../ui/env-plan.js";
|
|
15
15
|
import { surveyWorkflows } from "../core/copy/workflows.js";
|
|
@@ -305,13 +305,16 @@ export async function runInteractive(baseCtx, { cwd = process.cwd(), payloadRoot
|
|
|
305
305
|
}
|
|
306
306
|
|
|
307
307
|
// 브랜치 선택 — 원격 목록이 있으면 select(+직접 입력), 없으면 텍스트 입력. ESC/빈값 = 기본값.
|
|
308
|
-
|
|
308
|
+
// 이슈 #85: def를 최우선으로, main/develop을 그다음으로 정렬하고 커서를 def에 고정한다.
|
|
309
|
+
export async function pickBranch(io, message, def, remoteBranches, isCancel) {
|
|
309
310
|
if (io.engineIo?.select && remoteBranches.length) {
|
|
311
|
+
const sorted = sortBranchesForSelection(remoteBranches, def);
|
|
310
312
|
const options = [];
|
|
311
|
-
if (!
|
|
312
|
-
for (const b of
|
|
313
|
+
if (!sorted.includes(def)) options.push({ value: def, label: `${def} (기본값 — 없으면 새로 생성)` });
|
|
314
|
+
for (const b of sorted) options.push({ value: b, label: b === def ? `${b} (기본값)` : b });
|
|
313
315
|
options.push({ value: "__custom__", label: "직접 입력..." });
|
|
314
|
-
const
|
|
316
|
+
const initialIndex = Math.max(0, options.findIndex((o) => o.value === def));
|
|
317
|
+
const sel = await io.engineIo.select({ message, options, initialIndex });
|
|
315
318
|
if (sel === "__custom__") {
|
|
316
319
|
const v = await io.askText("브랜치 이름", def);
|
|
317
320
|
return isCancel(v) || !v ? def : v;
|
package/src/core/branches.js
CHANGED
|
@@ -34,6 +34,16 @@ export function resolveBranchConfig({ mainBranch = "", developBranch = "", defau
|
|
|
34
34
|
return { main, develop, mode: main === develop ? "trunk-based" : "pr-flow" };
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
// 브랜치 선택 프롬프트용 정렬 (이슈 #85). def를 최우선으로, 그다음 priority(main/develop)
|
|
38
|
+
// 순서로 목록 앞에 배치한다. 나머지는 remoteBranches의 원래 순서(git이 준 알파벳순)를 유지한다.
|
|
39
|
+
// 순수 함수 — remoteBranches 원본은 변경하지 않는다.
|
|
40
|
+
export function sortBranchesForSelection(remoteBranches, def, priority = ["main", "develop"]) {
|
|
41
|
+
const priorityOrder = [def, ...priority].filter((b, i, arr) => arr.indexOf(b) === i);
|
|
42
|
+
const inPriority = priorityOrder.filter((b) => remoteBranches.includes(b));
|
|
43
|
+
const rest = remoteBranches.filter((b) => !inPriority.includes(b));
|
|
44
|
+
return [...inPriority, ...rest];
|
|
45
|
+
}
|
|
46
|
+
|
|
37
47
|
// 생성: develop이 원격에 없으면 현 HEAD 기준으로 생성 + push.
|
|
38
48
|
// confirm: async(message)→bool — 대화형 확인 질문. null이면(--force) 질문 없이 자동 생성.
|
|
39
49
|
// exec 주입 가능 (테스트 mock). 반환 { created, pushed?, skipped? }.
|