project-auto-wizard 0.1.20 → 0.1.23
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 +11 -6
- package/package.json +2 -2
- package/payload/scripts/__pycache__/changelog_manager.cpython-314.pyc +0 -0
- package/payload/scripts/__pycache__/version_manager.cpython-314.pyc +0 -0
- package/payload/workflows/common/PROJECT-COMMON-RELEASE-PUBLISH.yaml +4 -1
- package/src/commands/doctor.js +14 -9
- package/src/ui/banner.js +2 -2
- package/src/ui/status-cards.js +3 -3
package/README.md
CHANGED
|
@@ -11,12 +11,13 @@ npx project-auto-wizard
|
|
|
11
11
|
<!-- TODO: 30초 데모 GIF (docs/assets/demo.gif) -->
|
|
12
12
|
<!-- TODO: 3분 데모 YouTube 링크 -->
|
|
13
13
|
|
|
14
|
+
[](https://github.com/Twin-Fang/project-auto-wizard/actions/workflows/CI.yaml)
|
|
14
15
|
[](https://www.npmjs.com/package/project-auto-wizard)
|
|
15
16
|
[](LICENSE)
|
|
16
17
|
[](package.json)
|
|
17
18
|
|
|
18
19
|
<!-- AUTO-VERSION-SECTION: DO NOT EDIT MANUALLY -->
|
|
19
|
-
## 최신 버전 : v0.1.
|
|
20
|
+
## 최신 버전 : v0.1.23 (2026-08-06)
|
|
20
21
|
|
|
21
22
|
[전체 버전 기록 보기](CHANGELOG.md)
|
|
22
23
|
|
|
@@ -163,13 +164,17 @@ npx project-auto-wizard --mode doctor # 환경 진단 (읽기 전용, 규칙
|
|
|
163
164
|
[✓] GitHub 로그인 — 레포 설정 조회 권한 인증됨
|
|
164
165
|
[✓] merge commit 허용 — 릴리스 PR 자동 머지 조건 허용됨
|
|
165
166
|
|
|
166
|
-
[!]
|
|
167
|
-
✗
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
→
|
|
167
|
+
[!] WORKFLOW_PAT — 자동 태그·Release 발행
|
|
168
|
+
✗ secret이 등록되어 있지 않습니다.
|
|
169
|
+
PR 자동 머지 뒤 태그·Release 워크플로가 이어지지 않습니다.
|
|
170
|
+
(GitHub 정책상 기본 토큰으로 만든 커밋은 다음 워크플로를 깨우지 못합니다)
|
|
171
|
+
→ 개인 액세스 토큰 발급 (scopes: repo, workflow)
|
|
172
|
+
→ 레포 Settings → Secrets and variables → Actions
|
|
173
|
+
→ New repository secret · 이름은 WORKFLOW_PAT
|
|
171
174
|
→ 자세히: https://github.com/Twin-Fang/project-auto-wizard#post-install
|
|
172
175
|
|
|
176
|
+
[i] Workflow permissions — 직접 추가한 워크플로우의 기본 권한
|
|
177
|
+
현재 read 입니다 — 마법사가 설치한 워크플로우는 각자 권한을 선언하므로 그대로 동작합니다.
|
|
173
178
|
[i] GitHub Models — AI 릴리스 노트 생성
|
|
174
179
|
조직 정책으로 차단됐는지는 자동으로 확인할 수 없습니다 (Settings → Models).
|
|
175
180
|
차단돼 있어도 규칙 기반 요약으로 자동 전환되므로 그대로 두셔도 됩니다.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "project-auto-wizard",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.23",
|
|
4
4
|
"description": "One command DevOps: npx wizard that installs GitHub-native AI Release Automation into any project",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
19
|
"test": "npm run test:node && npm run test:py",
|
|
20
|
-
"test:node": "node --test
|
|
20
|
+
"test:node": "node --test --test-concurrency=1",
|
|
21
21
|
"test:py": "node scripts/run-py-tests.mjs"
|
|
22
22
|
},
|
|
23
23
|
"repository": {
|
|
Binary file
|
|
Binary file
|
|
@@ -322,7 +322,10 @@ jobs:
|
|
|
322
322
|
- name: Create GitHub Release
|
|
323
323
|
if: steps.gate.outputs.proceed == 'true' && steps.version.outputs.release_exists != 'true'
|
|
324
324
|
env:
|
|
325
|
-
|
|
325
|
+
# WORKFLOW_PAT으로 발행해야 release 이벤트가 후속 워크플로우(npm 배포 등)를 트리거한다.
|
|
326
|
+
# GITHUB_TOKEN이 만든 이벤트는 GitHub 정책상 다른 워크플로우를 깨우지 못한다.
|
|
327
|
+
# PAT이 없는 레포에서도 릴리스 자체는 계속 동작해야 하므로 기본 토큰으로 폴백한다.
|
|
328
|
+
GH_TOKEN: ${{ secrets.WORKFLOW_PAT || github.token }}
|
|
326
329
|
run: |
|
|
327
330
|
VERSION="${{ steps.version.outputs.version }}"
|
|
328
331
|
gh release create "v$VERSION" --title "v$VERSION" --notes-file notes.md
|
package/src/commands/doctor.js
CHANGED
|
@@ -83,26 +83,31 @@ export function runDoctor(cwd = process.cwd(), { exec = defaultExec } = {}) {
|
|
|
83
83
|
|
|
84
84
|
const perm = exec("gh", ["api", `repos/${owner}/${repo}/actions/permissions/workflow`, "--jq", ".default_workflow_permissions"]);
|
|
85
85
|
const permValue = (perm.stdout || "").trim();
|
|
86
|
+
// 이 값은 "워크플로우가 permissions를 생략했을 때 적용되는 기본값"이지 상한이 아니다(#34).
|
|
87
|
+
// 마법사가 설치하는 워크플로우는 전부 자체 permissions를 선언하므로(회귀 가드:
|
|
88
|
+
// tests/node/payload-workflow-permissions.test.js) read여도 정상 동작한다 — 이 레포 자체가
|
|
89
|
+
// read인데 VERSION-CONTROL이 버전 커밋 push에 성공하는 것이 그 증거다.
|
|
90
|
+
const PERM_PURPOSE = "직접 추가한 워크플로우의 기본 권한";
|
|
86
91
|
if (perm.status !== 0) {
|
|
92
|
+
// 조회 실패는 오진이 아니라 실제로 정보를 얻지 못한 상태다 — 관리자 확인이라는 조치가 있다.
|
|
87
93
|
add({
|
|
88
|
-
name: "Workflow permissions", purpose:
|
|
94
|
+
name: "Workflow permissions", purpose: PERM_PURPOSE, status: "WARN",
|
|
89
95
|
value: "설정을 조회하지 못했습니다.",
|
|
90
96
|
impact: ["레포 관리자 권한이 없으면 이 설정은 조회되지 않습니다 — 값 자체는 정상일 수 있습니다."],
|
|
91
97
|
actions: ["레포 관리자에게 Settings → Actions → General → Workflow permissions 값을 확인하세요"],
|
|
92
98
|
doc: DOC.postInstall,
|
|
93
99
|
});
|
|
94
100
|
} else if (permValue === "write") {
|
|
95
|
-
add({ name: "Workflow permissions", purpose:
|
|
101
|
+
add({ name: "Workflow permissions", purpose: PERM_PURPOSE, status: "OK", value: "Read and write" });
|
|
96
102
|
} else {
|
|
103
|
+
// 조치가 필요 없으므로 WARN이 아니라 INFO다. 경고로 띄우면 없는 장애를 알리고
|
|
104
|
+
// 불필요한 권한 상향을 유도해 최소 권한 원칙에 역행한다.
|
|
97
105
|
add({
|
|
98
|
-
name: "Workflow permissions", purpose:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
"레포 Settings → Actions → General → Workflow permissions",
|
|
103
|
-
'"Read and write permissions" 선택 후 Save',
|
|
106
|
+
name: "Workflow permissions", purpose: PERM_PURPOSE, status: "INFO",
|
|
107
|
+
note: [
|
|
108
|
+
`현재 ${permValue || "확인불가"} 입니다 — 마법사가 설치한 워크플로우는 각자 권한을 선언하므로 그대로 동작합니다.`,
|
|
109
|
+
"직접 추가한 워크플로우에서 permissions를 생략했다면 이 기본값을 따르므로, 그때만 Read and write로 올리세요.",
|
|
104
110
|
],
|
|
105
|
-
doc: DOC.postInstall,
|
|
106
111
|
});
|
|
107
112
|
}
|
|
108
113
|
|
package/src/ui/banner.js
CHANGED
|
@@ -10,7 +10,7 @@ function boxLine(out, content = "") {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
// 대화형 첫 화면 배너 — 박스 타이틀 + 메타 4줄 (.ps1 Print-Banner 등가, #446 확정 시안 A)
|
|
13
|
-
export function printBanner({ version, modeLabel }, out = (s) => process.
|
|
13
|
+
export function printBanner({ version, modeLabel }, out = (s) => process.stderr.write(s)) {
|
|
14
14
|
out("\n");
|
|
15
15
|
out(paint(`╔${"═".repeat(INNER)}╗`, A.cyan) + "\n");
|
|
16
16
|
boxLine(out);
|
|
@@ -24,6 +24,6 @@ export function printBanner({ version, modeLabel }, out = (s) => process.stdout.
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
// 비대화형(--force/CI) 축약 배너 — 1줄 (사용자 확정: 로그 오염 최소 + 버전 추적)
|
|
27
|
-
export function printBannerCompact({ version, mode }, out = (s) => process.
|
|
27
|
+
export function printBannerCompact({ version, mode }, out = (s) => process.stderr.write(s)) {
|
|
28
28
|
out(`${paint("✦", A.yellow)} ${paint("project-auto-wizard", A.bold)} v${version} — ${mode} 모드 (--force)\n`);
|
|
29
29
|
}
|
package/src/ui/status-cards.js
CHANGED
|
@@ -9,7 +9,7 @@ const HEAD = paint("◆", A.cyan);
|
|
|
9
9
|
const OK = paint("✓", A.green);
|
|
10
10
|
|
|
11
11
|
// 층2 — 감지 로그 (.ps1 감지 진행 표시 등가)
|
|
12
|
-
export function printDetectionLog({ types = [], version = "", branch = "" }, out = (s) => process.
|
|
12
|
+
export function printDetectionLog({ types = [], version = "", branch = "" }, out = (s) => process.stderr.write(s)) {
|
|
13
13
|
out(`${paint("┌", A.gray)} 🔍 프로젝트를 살펴보는 중...\n`);
|
|
14
14
|
if (types.length && !(types.length === 1 && types[0] === "basic")) {
|
|
15
15
|
for (const t of types) {
|
|
@@ -26,7 +26,7 @@ export function printDetectionLog({ types = [], version = "", branch = "" }, out
|
|
|
26
26
|
// 층3 — 프로젝트 분석 개요 카드 (.ps1 Print-ProjectAnalysis 등가+)
|
|
27
27
|
export function printAnalysisCard({ mode = "", modeLabel = "", types = [], version = "", branch = "",
|
|
28
28
|
includeNexus = null, includeSecretBackup = null, paths = new Map(), showOptional = false },
|
|
29
|
-
out = (s) => process.
|
|
29
|
+
out = (s) => process.stderr.write(s)) {
|
|
30
30
|
out(`${HEAD} ${paint("프로젝트 분석 결과", A.bold)}\n`);
|
|
31
31
|
const row = (icon, label, value) => out(`${GUT} ${icon} ${label.padEnd(10)} ${value}\n`);
|
|
32
32
|
row("📂", types.length > 1 ? "타입(멀티)" : "타입", paint(types.join(", ") || "basic", A.bold));
|
|
@@ -46,7 +46,7 @@ export function printAnalysisCard({ mode = "", modeLabel = "", types = [], versi
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
// 층5 — 신규 통합 vs 업데이트 판별 라인 (Breaking 박스는 breaking-check.js)
|
|
49
|
-
export function printInstallKind({ currentTemplateVersion = "", templateVersion = "" }, out = (s) => process.
|
|
49
|
+
export function printInstallKind({ currentTemplateVersion = "", templateVersion = "" }, out = (s) => process.stderr.write(s)) {
|
|
50
50
|
if (currentTemplateVersion) {
|
|
51
51
|
out(`${GUT} ♻️ ${paint("업데이트", A.bold)} — 템플릿 ${paint(`v${currentTemplateVersion}`, A.dim)} → ${paint(`v${templateVersion}`, A.green)}\n`);
|
|
52
52
|
} else {
|