project-auto-wizard 0.12.0 → 0.12.2
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 +4 -8
- package/package.json +1 -1
- package/payload/config/breaking-changes.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 +4 -4
- package/payload/scripts/version_manager.py +2 -2
- package/payload/version.yml.template +0 -2
- package/payload/workflows/common/PROJECT-COMMON-AI-PR-SUMMARY.yaml +0 -4
- package/payload/workflows/common/PROJECT-COMMON-AUTO-CHANGELOG-CONTROL.yaml +2 -7
- package/payload/workflows/common/PROJECT-COMMON-ISSUE-HELPER.yaml +3 -6
- package/payload/workflows/common/PROJECT-COMMON-README-VERSION-UPDATE.yaml +0 -12
- package/payload/workflows/common/PROJECT-COMMON-RELEASE-PUBLISH.yaml +2 -6
- package/payload/workflows/common/PROJECT-COMMON-VERSION-CONTROL.yaml +3 -7
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-FIREBASE-CICD.yaml +7 -34
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-PLAYSTORE-CICD.yaml +2 -25
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-SELFHOSTED-CICD.yaml +2 -20
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-TEST-APK.yaml +5 -30
- package/payload/workflows/flutter/PROJECT-FLUTTER-APP-BUILD-TRIGGER.yaml +0 -4
- package/payload/workflows/flutter/PROJECT-FLUTTER-CI.yaml +7 -51
- package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TEST-TESTFLIGHT.yaml +5 -29
- package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TESTFLIGHT.yaml +9 -29
- package/payload/workflows/go/PROJECT-GO-CI.yaml +5 -28
- package/payload/workflows/go/PROJECT-GO-PR-PREVIEW.yaml +19 -99
- package/payload/workflows/go/PROJECT-GO-SIMPLE-CICD.yaml +18 -89
- package/payload/workflows/next/PROJECT-NEXT-CI.yaml +11 -41
- package/payload/workflows/next/PROJECT-NEXT-CICD.yaml +9 -45
- package/payload/workflows/python/PROJECT-PYTHON-CI.yaml +1 -27
- package/payload/workflows/python/PROJECT-PYTHON-PR-PREVIEW.yaml +14 -97
- package/payload/workflows/python/PROJECT-PYTHON-SIMPLE-CICD.yaml +14 -92
- package/payload/workflows/react/PROJECT-REACT-CI.yaml +11 -40
- package/payload/workflows/react/PROJECT-REACT-CICD.yaml +9 -43
- package/payload/workflows/spring/{nexus/PROJECT-SPRING-NEXUS-CI.yml → PROJECT-SPRING-CI.yml} +2 -25
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-NGINX-CICD.yaml +19 -63
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-TRAEFIK-CICD.yaml +19 -59
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-PR-PREVIEW.yaml +23 -86
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-SIMPLE-CICD.yaml +20 -80
- package/src/cli/args.js +1 -15
- package/src/cli/help.js +0 -2
- package/src/commands/doctor.js +5 -5
- package/src/commands/dry-run.js +1 -1
- package/src/commands/full.js +9 -10
- package/src/commands/interactive-flutter.js +1 -1
- package/src/commands/interactive.js +25 -46
- package/src/commands/purge.js +2 -2
- package/src/commands/status.js +4 -6
- package/src/commands/uninstall.js +3 -4
- package/src/context.js +4 -6
- package/src/core/assets.js +2 -2
- package/src/core/baseline.js +1 -1
- package/src/core/branches.js +3 -3
- package/src/core/breaking-check.js +1 -1
- package/src/core/breaking.js +1 -1
- package/src/core/copy/flutter-app.js +2 -2
- package/src/core/copy/gitignore.js +8 -8
- package/src/core/copy/workflows.js +24 -69
- package/src/core/deploy-style.js +2 -2
- package/src/core/detect-fs.js +11 -11
- package/src/core/detect.js +7 -7
- package/src/core/flutter-options.js +1 -1
- package/src/core/installed-stores.js +1 -1
- package/src/core/logger.js +1 -1
- package/src/core/paths-resolve.js +1 -1
- package/src/core/removal-plan.js +4 -4
- package/src/core/verify.js +3 -3
- package/src/core/version-yml.js +17 -33
- package/src/core/wizard-env.js +4 -4
- package/src/index.js +12 -14
- package/src/ui/banner.js +2 -2
- package/src/ui/env-plan.js +10 -16
- package/src/ui/prompts.js +9 -14
- package/src/ui/status-cards.js +10 -12
- package/src/ui/summary.js +9 -9
- package/payload/workflows/common/secret-backup/PROJECT-COMMON-SECRET-FILE-UPLOAD.yaml +0 -210
- package/payload/workflows/spring/nexus/PROJECT-SPRING-GITHUB-PACKAGES-PUBLISH.yml +0 -92
- package/payload/workflows/spring/nexus/PROJECT-SPRING-NEXUS-PUBLISH.yml +0 -70
- package/src/core/options-ask.js +0 -102
package/README.md
CHANGED
|
@@ -8,8 +8,6 @@
|
|
|
8
8
|
npx project-auto-wizard
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
<!-- TODO: 30초 데모 GIF (docs/assets/demo.gif) -->
|
|
12
|
-
<!-- TODO: 3분 데모 YouTube 링크 -->
|
|
13
11
|
|
|
14
12
|
[](https://github.com/Twin-Fang/project-auto-wizard/actions/workflows/CI.yaml)
|
|
15
13
|
[](https://www.npmjs.com/package/project-auto-wizard)
|
|
@@ -17,7 +15,7 @@ npx project-auto-wizard
|
|
|
17
15
|
[](package.json)
|
|
18
16
|
|
|
19
17
|
<!-- AUTO-VERSION-SECTION: DO NOT EDIT MANUALLY -->
|
|
20
|
-
## 최신 버전 : v0.
|
|
18
|
+
## 최신 버전 : v0.12.1 (2026-09-26)
|
|
21
19
|
|
|
22
20
|
[전체 버전 기록 보기](CHANGELOG.md)
|
|
23
21
|
|
|
@@ -67,7 +65,7 @@ flutter.APP_ARTIFACT_NAME:
|
|
|
67
65
|
`spring`/`flutter`는 아래처럼 단일 CI 이상으로 깊게 구성되어 있습니다:
|
|
68
66
|
|
|
69
67
|
- **flutter**: Android(Firebase/Playstore/Selfhosted/TestAPK 배포), iOS(TestFlight/Test-TestFlight), CI, Lab 트리거까지 8종 — 스토어 배포(Play Store·TestFlight)는 고른 플랫폼만 설치되고 fastlane 파일도 함께 생성됩니다. 환경변수 방식·배포 모드 등 자세한 내용은 아래 "Flutter 워크플로우 상세"를 참고하세요.
|
|
70
|
-
- **spring**: 서버 배포 1종(단일 서버 / 무중단 Nginx / 무중단 Traefik / 배포 안 함 중 택1) + PR 프리뷰 +
|
|
68
|
+
- **spring**: 서버 배포 1종(단일 서버 / 무중단 Nginx / 무중단 Traefik / 배포 안 함 중 택1) + PR 프리뷰 + CI
|
|
71
69
|
- 서버 배포 워크플로우는 **서로 대체재**라 하나만 설치합니다. 대화형에서 고르면 그것만 깔리고 **`push` 트리거까지 켜진 채로** 설치됩니다. 비대화형은 `--deploy-style simple|nginx|traefik|none` (기본: `simple`).
|
|
72
70
|
- 고른 방식은 `version.yml`에 기록되므로 다시 실행해도 묻지 않습니다. 방식을 바꾸면 **이전 워크플로우를 마법사가 정리합니다** — 손대지 않은 파일은 삭제하고, 수정한 파일은 `.bak`으로 옮겨 내용을 보존합니다. 남겨두면 배포가 두 번 돕니다.
|
|
73
71
|
- PR 프리뷰는 배포 방식과 무관한 별개 축이라 선택과 관계없이 함께 설치됩니다 (단, `none`을 고르면 PR 프리뷰도 함께 제외됩니다 — 서버 배포 자체를 하지 않는 프로젝트를 위한 선택지입니다).
|
|
@@ -144,7 +142,7 @@ flutter.APP_ARTIFACT_NAME:
|
|
|
144
142
|
**모노레포와 `ci-gate`**
|
|
145
143
|
|
|
146
144
|
- `--paths flutter=app`처럼 Flutter 하위 폴더를 지정하면 모든 Flutter 워크플로우가 그 폴더(`FLUTTER_PROJECT_DIR`)를 기준으로 동작하고, main push로 도는 배포 워크플로우(`PLAYSTORE`·`IOS-TESTFLIGHT`·`SELFHOSTED`·`FIREBASE`)는 `app/**`가 바뀔 때만 실행됩니다(Spring 등 다른 타입과 같은 `paths` 필터).
|
|
147
|
-
- CI 워크플로우(Flutter·Go·Next·Python·React·Spring
|
|
145
|
+
- CI 워크플로우(Flutter·Go·Next·Python·React·Spring CI)는 `push`·`pull_request`에서 항상 실행되고, 첫 job `changes`가 변경 파일을 판별해 나머지 job을 건너뜁니다(건너뛴 job은 Success). 마지막 job `ci-gate`는 항상 실행되어 필수 job이 모두 success 또는 skipped이면 통과하고 failure·cancelled가 하나라도 있으면 실패합니다.
|
|
148
146
|
- 브랜치 보호 규칙의 required status check에는 개별 job이 아니라 **`CI Gate`(`ci-gate`) 하나만** 등록하세요. 경로 필터로 워크플로우 자체를 건너뛰면 required check가 Pending에 머물러 머지가 막히지만, job을 건너뛰는 방식은 그렇지 않기 때문입니다.
|
|
149
147
|
- 워크플로우 `paths` 필터는 태그 push에 적용되지 않습니다(GitHub 문서).
|
|
150
148
|
|
|
@@ -197,7 +195,7 @@ flowchart LR
|
|
|
197
195
|
|
|
198
196
|
- 기본값은 **규칙 기반 요약**입니다. 설치 마법사에서 Copilot을 켜면(`--copilot`, `version.yml`의 `copilot_ai: true`) Actions의 `GITHUB_TOKEN` + `permissions: copilot-requests: write`로 Copilot CLI가 요약을 생성합니다 — 별도 API 키는 필요 없습니다.
|
|
199
197
|
- **Copilot은 GitHub Copilot AI Credits를 소비합니다.** 개인 저장소는 저장소 소유자의 Copilot 좌석에, 조직 저장소는 조직에 과금되며 조직은 "Allow use of Copilot CLI billed to the organization" 정책을 켜야 합니다. 사용할 수 없으면 자동으로 규칙 기반 요약으로 전환됩니다. PR에 푸시할 때마다 요약이 새로 생성되므로 그만큼 크레딧이 소비됩니다.
|
|
200
|
-
- Copilot
|
|
198
|
+
- Copilot은 항상 `auto` 모델 선택으로 호출됩니다. Copilot Free·Student 계정은 모델명을 직접 지정하는 호출이 거부되고 `auto`만 허용되기 때문에, 모델을 바꾸는 옵션은 제공하지 않습니다.
|
|
201
199
|
- GitHub은 Copilot CLI를 `run` 스텝에서 직접 호출하기보다 Agentic Workflows를 쓰라고 권고하지만, 이 프로젝트는 직접 호출을 택했습니다. 프롬프트 입력이 PR 제목·커밋 메시지·`git diff --stat`뿐이고, 빈 임시 디렉터리에서 shell/write/url 도구와 내장 MCP를 모두 막은 텍스트 생성 전용으로 호출하며, 포크 PR은 기존 가드로 건너뛰어 프롬프트 인젝션 위험을 낮췄기 때문입니다.
|
|
202
200
|
- `AI_API_KEY`(**Secret**)와 `AI_API_BASE_URL`·`AI_MODEL`(**Variables**)을 **모두** 설정하면 OpenAI-호환 엔드포인트(Groq, Gemini 호환 모드, Ollama 등)를 최우선으로 사용합니다. 셋 중 하나라도 없으면 이 단계는 건너뜁니다.
|
|
203
201
|
- 규칙 fallback 3단: 프로젝트 컨벤션 → Conventional Commits → 무형식 bullet. 커밋 컨벤션이 없어도 동작.
|
|
@@ -238,8 +236,6 @@ npx project-auto-wizard [옵션]
|
|
|
238
236
|
--flutter-store CSV Flutter 스토어 배포 대상: android,ios,none (미지정 시 둘 다 설치)
|
|
239
237
|
--android-deploy-mode M Play Store 배포 모드: store_only | store_prepare | store_submit (기본: store_only)
|
|
240
238
|
--ios-deploy-mode M iOS 배포 모드: store_only | store_prepare | store_submit (기본: store_only)
|
|
241
|
-
--nexus 라이브러리 publish 워크플로우 포함 (Nexus + GitHub Packages)
|
|
242
|
-
--secret-backup Secret 서버 백업 워크플로우 포함
|
|
243
239
|
--semver-auto 커밋 타입 기반 자동 major/minor/patch 승격 (기본: 사용함, --no-semver-auto로 끔)
|
|
244
240
|
--copilot Copilot으로 AI 요약 생성 (기본: 사용 안 함, GitHub Copilot AI Credits 소비, --no-copilot으로 끔)
|
|
245
241
|
--dry-run 실제 파일 변경 없이 무엇이 바뀔지만 미리 보여줌
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "project-auto-wizard",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2",
|
|
4
4
|
"description": "One command DevOps: npx wizard that installs GitHub-native Release Automation (optional GitHub Copilot AI summaries) into any project",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
{
|
|
19
19
|
"severity": "warning",
|
|
20
20
|
"title": "모노레포 CI required check는 ci-gate 하나만 등록",
|
|
21
|
-
"message": "CI 워크플로우(Flutter·Go·Next·Python·React·Spring
|
|
21
|
+
"message": "CI 워크플로우(Flutter·Go·Next·Python·React·Spring CI)는 항상 실행되고 변경이 없으면 job을 건너뜁니다. required check로 쓰려면 개별 job이 아닌 CI Gate(ci-gate) 하나만 등록하세요."
|
|
22
22
|
}
|
|
23
23
|
]
|
|
24
24
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -464,7 +464,7 @@ def cmd_classify_bump(commits_file: str) -> int:
|
|
|
464
464
|
def cmd_update_from_summary() -> int:
|
|
465
465
|
"""pr_body.md에서 Markdown을 파싱하여 CHANGELOG.json 갱신."""
|
|
466
466
|
version = os.environ.get('VERSION')
|
|
467
|
-
# PROJECT_TYPES(csv)가 유일한 입력 — 단수 PROJECT_TYPE 폴백은 제거됐다
|
|
467
|
+
# PROJECT_TYPES(csv)가 유일한 입력 — 단수 PROJECT_TYPE 폴백은 제거됐다
|
|
468
468
|
project_types_csv = os.environ.get('PROJECT_TYPES', '')
|
|
469
469
|
project_types = [t.strip() for t in project_types_csv.split(',') if t.strip()]
|
|
470
470
|
today = os.environ.get('TODAY')
|
|
@@ -694,7 +694,8 @@ def cmd_export_release_notes(version: str, output_path: str | None) -> int:
|
|
|
694
694
|
|
|
695
695
|
# ------------------------ ai-summary 엔진 체인 ------------------------
|
|
696
696
|
|
|
697
|
-
|
|
697
|
+
# Copilot Free/Student 계정은 모델명 지정이 거부되고 auto 모델 선택만 허용된다 (#153).
|
|
698
|
+
_COPILOT_MODEL = "auto"
|
|
698
699
|
_COPILOT_TIMEOUT_SECONDS = 90
|
|
699
700
|
|
|
700
701
|
|
|
@@ -729,14 +730,13 @@ def call_copilot_cli(prompt: str) -> str:
|
|
|
729
730
|
빈 임시 디렉터리에서 실행하고, shell/write/url 도구를 거부하며, 내장 MCP와
|
|
730
731
|
커스텀 지침 로딩을 끈다.
|
|
731
732
|
실패(비정상 종료·타임아웃·CLI 없음)는 예외로 올려 호출부가 fallback한다."""
|
|
732
|
-
model = os.environ.get('COPILOT_MODEL') or _COPILOT_DEFAULT_MODEL
|
|
733
733
|
with tempfile.TemporaryDirectory() as workdir:
|
|
734
734
|
result = subprocess.run(
|
|
735
735
|
[
|
|
736
736
|
'copilot', '-p', prompt, '-s',
|
|
737
737
|
'--no-ask-user', '--no-color', '--no-custom-instructions', '--disable-builtin-mcps',
|
|
738
738
|
'--deny-tool=shell', '--deny-tool=write', '--deny-tool=url',
|
|
739
|
-
'--model',
|
|
739
|
+
'--model', _COPILOT_MODEL,
|
|
740
740
|
],
|
|
741
741
|
cwd=workdir, stdin=subprocess.DEVNULL,
|
|
742
742
|
capture_output=True, text=True, timeout=_COPILOT_TIMEOUT_SECONDS,
|
|
@@ -160,7 +160,7 @@ def get_project_types_csv():
|
|
|
160
160
|
# Inline array form: project_types: ["a", "b"] # trailing comment allowed
|
|
161
161
|
# The template always appends "# first entry is primary", so anchoring at
|
|
162
162
|
# end-of-line made this branch never match — every install silently fell
|
|
163
|
-
# through to the singular key instead
|
|
163
|
+
# through to the singular key instead.
|
|
164
164
|
m = re.search(r'^project_types:[ \t]*\[(.*?)\][ \t]*(?:#.*)?$', text, re.MULTILINE)
|
|
165
165
|
if m:
|
|
166
166
|
inner = m.group(1)
|
|
@@ -435,7 +435,7 @@ def sync_all_project_files(new_version):
|
|
|
435
435
|
types = get_project_types_csv()
|
|
436
436
|
if not types:
|
|
437
437
|
# No silent fallback: an unreadable project_types used to degrade to
|
|
438
|
-
# "basic" and skip every sync without a word
|
|
438
|
+
# "basic" and skip every sync without a word.
|
|
439
439
|
raise SystemExit("ERROR: version.yml has no readable project_types — cannot sync project files")
|
|
440
440
|
for t in types:
|
|
441
441
|
sync_for_type(t, new_version, get_version_code)
|
|
@@ -47,8 +47,6 @@ metadata:
|
|
|
47
47
|
develop: "{{DEVELOP_BRANCH}}"
|
|
48
48
|
mode: "{{BRANCH_MODE}}" # pr-flow | trunk-based
|
|
49
49
|
options:
|
|
50
|
-
nexus: {{OPT_NEXUS}}
|
|
51
|
-
secret_backup: {{OPT_SECRET_BACKUP}}
|
|
52
50
|
semver_auto: {{OPT_SEMVER_AUTO}}
|
|
53
51
|
copilot_ai: {{OPT_COPILOT_AI}}
|
|
54
52
|
deploy_style: "{{OPT_DEPLOY_STYLE}}" # simple | nginx | traefik | none (서버 배포 워크플로우)
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# project-auto-wizard:managed-workflow
|
|
2
|
-
# ===================================================================
|
|
3
2
|
# PROJECT-COMMON-AI-PR-SUMMARY.yaml
|
|
4
3
|
# Self-hosted AI PR summary bot — no third-party service required.
|
|
5
|
-
# ===================================================================
|
|
6
4
|
#
|
|
7
5
|
# Posts a summary comment on PRs targeting the default branch, using the
|
|
8
6
|
# same engine chain as the release changelog (user API key -> Copilot CLI,
|
|
@@ -18,7 +16,6 @@
|
|
|
18
16
|
# that commit is pushed with GITHUB_TOKEN, which GitHub does not use
|
|
19
17
|
# to retrigger pull_request events, so there would be no later run to
|
|
20
18
|
# correct it.
|
|
21
|
-
# ===================================================================
|
|
22
19
|
|
|
23
20
|
name: PROJECT-AI-PR-SUMMARY
|
|
24
21
|
|
|
@@ -72,7 +69,6 @@ jobs:
|
|
|
72
69
|
AI_MODEL: ${{ vars.AI_MODEL }}
|
|
73
70
|
GITHUB_TOKEN: ${{ github.token }}
|
|
74
71
|
COPILOT_AI: ${{ steps.copilot_options.outputs.copilot_ai }}
|
|
75
|
-
COPILOT_MODEL: ${{ vars.COPILOT_MODEL }}
|
|
76
72
|
run: |
|
|
77
73
|
PR_NUMBER=${{ github.event.pull_request.number }}
|
|
78
74
|
VERSION=$(python3 .github/scripts/version_manager.py get 2>/dev/null | tail -n 1)
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# project-auto-wizard:managed-workflow
|
|
2
|
-
# ===================================================================
|
|
3
2
|
# PROJECT-COMMON-AUTO-CHANGELOG-CONTROL.yaml
|
|
4
3
|
# Release PR pipeline: version confirm + AI changelog + automerge
|
|
5
|
-
# ===================================================================
|
|
6
4
|
#
|
|
7
5
|
# Runs on release PRs ({{DEVELOP_BRANCH}} -> {{MAIN_BRANCH}}) and:
|
|
8
6
|
# 1. Confirms the release version and syncs every version file:
|
|
@@ -36,14 +34,13 @@
|
|
|
36
34
|
# {{MAIN_BRANCH}}-push workflows (e.g. RELEASE-PUBLISH) for that merge.
|
|
37
35
|
# - secrets.AI_API_KEY (+ vars.AI_API_BASE_URL / vars.AI_MODEL, all three
|
|
38
36
|
# required together): preferred summary engine. Falls back to Copilot CLI
|
|
39
|
-
# (only when version.yml copilot_ai is true;
|
|
37
|
+
# (only when version.yml copilot_ai is true; always uses auto model selection),
|
|
40
38
|
# then to rule-based.
|
|
41
39
|
#
|
|
42
|
-
#
|
|
40
|
+
# Without WORKFLOW_PAT, a wait-for-merge-and-trigger-release job
|
|
43
41
|
# polls until the automerge actually lands, then wakes RELEASE-PUBLISH via
|
|
44
42
|
# workflow_dispatch — GITHUB_TOKEN can always trigger that event, unlike
|
|
45
43
|
# the push/release events blocked by GitHub's anti-recursion policy.
|
|
46
|
-
# ===================================================================
|
|
47
44
|
|
|
48
45
|
name: PROJECT-AUTO-CHANGELOG-CONTROL
|
|
49
46
|
|
|
@@ -166,7 +163,6 @@ jobs:
|
|
|
166
163
|
AI_MODEL: ${{ vars.AI_MODEL }}
|
|
167
164
|
GITHUB_TOKEN: ${{ github.token }}
|
|
168
165
|
COPILOT_AI: ${{ steps.copilot_options.outputs.copilot_ai }}
|
|
169
|
-
COPILOT_MODEL: ${{ vars.COPILOT_MODEL }}
|
|
170
166
|
run: |
|
|
171
167
|
# Idempotency: if the PR head is already this workflow's own
|
|
172
168
|
# version-confirm commit (re-run / synchronize retrigger), do not
|
|
@@ -203,7 +199,6 @@ jobs:
|
|
|
203
199
|
AI_MODEL: ${{ vars.AI_MODEL }}
|
|
204
200
|
GITHUB_TOKEN: ${{ github.token }}
|
|
205
201
|
COPILOT_AI: ${{ steps.copilot_options.outputs.copilot_ai }}
|
|
206
|
-
COPILOT_MODEL: ${{ vars.COPILOT_MODEL }}
|
|
207
202
|
run: |
|
|
208
203
|
VERSION=$(python3 .github/scripts/version_manager.py get | tail -n 1)
|
|
209
204
|
|
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
# project-auto-wizard:managed-workflow
|
|
2
|
-
# ===================================================================
|
|
3
2
|
# PROJECT-COMMON-ISSUE-HELPER.yaml
|
|
4
3
|
# 이슈 생성/제목 수정 시 브랜치명·커밋 메시지를 댓글로 안내
|
|
5
|
-
# ===================================================================
|
|
6
4
|
#
|
|
7
5
|
# 이슈가 열리거나(opened) 제목이 수정되면(edited + 제목 변경),
|
|
8
6
|
# 정규화된 브랜치명과 커밋 메시지를 이슈 댓글로 생성/갱신한다.
|
|
9
7
|
# ISSUE_HELPER_CREATE_BRANCH=true로 바꾸면 브랜치도 함께 생성한다
|
|
10
8
|
# (기본값은 false — 이슈를 열 때마다 브랜치가 자동 생성되는 것을
|
|
11
|
-
# 막기 위해 옵트인으로
|
|
9
|
+
# 막기 위해 옵트인으로 전환됨).
|
|
12
10
|
#
|
|
13
11
|
# 로직 본체는 .github/scripts/issue_helper.py (Chuseok22/github-issue-helper의
|
|
14
|
-
# Python 재작성, 동일 작성자
|
|
15
|
-
# ===================================================================
|
|
12
|
+
# Python 재작성, 동일 작성자).
|
|
16
13
|
|
|
17
14
|
name: PROJECT-ISSUE-HELPER
|
|
18
15
|
|
|
@@ -23,7 +20,7 @@ on:
|
|
|
23
20
|
# contents는 항상 write로 고정한다. ISSUE_HELPER_CREATE_BRANCH="true"일 때
|
|
24
21
|
# git/refs API로 브랜치를 생성하려면 write가 필요한데, 이 값은 @wizard ask로
|
|
25
22
|
# 설치 후에도 사용자가 직접 켤 수 있어(마법사 재실행 없이) 그 시점에 맞춰
|
|
26
|
-
# permissions를 조건부로 올릴 방법이
|
|
23
|
+
# permissions를 조건부로 올릴 방법이 없다.
|
|
27
24
|
permissions:
|
|
28
25
|
issues: write
|
|
29
26
|
contents: write
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
# project-auto-wizard:managed-workflow
|
|
2
|
-
# ===================================================================
|
|
3
2
|
# PROJECT-COMMON-README-VERSION-UPDATE.yaml
|
|
4
3
|
# Automatic README version update workflow
|
|
5
|
-
# ===================================================================
|
|
6
4
|
#
|
|
7
5
|
# On every push to {{MAIN_BRANCH}} this workflow reads the latest version
|
|
8
6
|
# via version_manager.py and rewrites the version section of README.md.
|
|
9
7
|
#
|
|
10
|
-
# ===================================================================
|
|
11
8
|
# How it works:
|
|
12
9
|
# 1. Triggered by a push to {{MAIN_BRANCH}}
|
|
13
10
|
# 2. Reads the latest version via version_manager.py
|
|
@@ -41,7 +38,6 @@
|
|
|
41
38
|
# afterwards with a [skip ci] commit that does not re-trigger this
|
|
42
39
|
# workflow, so the README stays one version behind until the next
|
|
43
40
|
# release/push. Run this workflow manually (workflow_dispatch) to catch up.
|
|
44
|
-
# ===================================================================
|
|
45
41
|
|
|
46
42
|
name: README VERSION UPDATE
|
|
47
43
|
|
|
@@ -112,9 +108,7 @@ jobs:
|
|
|
112
108
|
RELEASE_DATE="${{ steps.version_info.outputs.release_date }}"
|
|
113
109
|
SHOW_DATE="${{ env.SHOW_DATE }}"
|
|
114
110
|
|
|
115
|
-
# ---------------------------------------------------------
|
|
116
111
|
# Error message helper
|
|
117
|
-
# ---------------------------------------------------------
|
|
118
112
|
print_error_message() {
|
|
119
113
|
local error_type="$1"
|
|
120
114
|
local version_line="$2"
|
|
@@ -184,9 +178,7 @@ jobs:
|
|
|
184
178
|
else
|
|
185
179
|
# Update the existing version line
|
|
186
180
|
|
|
187
|
-
# ---------------------------------------------------------
|
|
188
181
|
# Validate the line format
|
|
189
|
-
# ---------------------------------------------------------
|
|
190
182
|
if [[ "$VERSION_LINE" =~ \*\* ]]; then
|
|
191
183
|
echo ""
|
|
192
184
|
echo "warning: the version line contains markdown bold (**) characters"
|
|
@@ -212,9 +204,7 @@ jobs:
|
|
|
212
204
|
LINE_NUMBER=$((LINE_NUMBER + 1))
|
|
213
205
|
fi
|
|
214
206
|
|
|
215
|
-
# ---------------------------------------------------------
|
|
216
207
|
# Extract the header part (up to the colon)
|
|
217
|
-
# ---------------------------------------------------------
|
|
218
208
|
HEADER_PART=$(printf '%s\n' "$VERSION_LINE" | sed 's/\(.*:\).*/\1 /')
|
|
219
209
|
|
|
220
210
|
if [ -z "$HEADER_PART" ] || [[ "$HEADER_PART" == "$VERSION_LINE" ]]; then
|
|
@@ -222,9 +212,7 @@ jobs:
|
|
|
222
212
|
exit 1
|
|
223
213
|
fi
|
|
224
214
|
|
|
225
|
-
# ---------------------------------------------------------
|
|
226
215
|
# Replace by line number (avoids regex special-char issues)
|
|
227
|
-
# ---------------------------------------------------------
|
|
228
216
|
NEW_LINE="${HEADER_PART}${VERSION_TEXT}"
|
|
229
217
|
|
|
230
218
|
# Escape sed replacement metacharacters (backslash, & and the
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# project-auto-wizard:managed-workflow
|
|
2
|
-
# ===================================================================
|
|
3
2
|
# PROJECT-COMMON-RELEASE-PUBLISH.yaml
|
|
4
3
|
# Tag + GitHub Release publisher (dual-mode)
|
|
5
|
-
# ===================================================================
|
|
6
4
|
#
|
|
7
5
|
# Publishes a git tag (vX.Y.Z) and a GitHub Release for every release
|
|
8
6
|
# that lands on {{MAIN_BRANCH}}. Two branch modes, read from version.yml
|
|
@@ -38,13 +36,12 @@
|
|
|
38
36
|
# previous run failed after the version was confirmed but before the
|
|
39
37
|
# release was created). The idempotency guard keeps it safe to re-run.
|
|
40
38
|
#
|
|
41
|
-
#
|
|
39
|
+
# This file and its self-copy (.github/workflows/) intentionally
|
|
42
40
|
# differ by one step — the self-copy also triggers NPM-PUBLISH via
|
|
43
41
|
# workflow_dispatch right after the release is created. NPM-PUBLISH.yaml is
|
|
44
42
|
# a repo-only workflow (not shipped in payload), so wiring that dispatch
|
|
45
43
|
# here would make every wizard-installed repo call a workflow that doesn't
|
|
46
44
|
# exist for them on every release.
|
|
47
|
-
# ===================================================================
|
|
48
45
|
|
|
49
46
|
name: PROJECT-RELEASE-PUBLISH
|
|
50
47
|
|
|
@@ -117,7 +114,7 @@ jobs:
|
|
|
117
114
|
|
|
118
115
|
echo "not a release-confirm push in pr-flow mode — skipping"
|
|
119
116
|
|
|
120
|
-
# Drift guard
|
|
117
|
+
# Drift guard: skipping is normal, but a version.yml that
|
|
121
118
|
# has run ahead of the newest tag is not — it means the version was
|
|
122
119
|
# bumped without a release, so npm silently stays behind. Six versions
|
|
123
120
|
# (0.1.26~0.1.31) went missing this way with every workflow green.
|
|
@@ -193,7 +190,6 @@ jobs:
|
|
|
193
190
|
AI_MODEL: ${{ vars.AI_MODEL }}
|
|
194
191
|
GITHUB_TOKEN: ${{ github.token }}
|
|
195
192
|
COPILOT_AI: ${{ steps.copilot_options.outputs.copilot_ai }}
|
|
196
|
-
COPILOT_MODEL: ${{ vars.COPILOT_MODEL }}
|
|
197
193
|
run: |
|
|
198
194
|
# Idempotency: on a re-run of a failed job the checked-out HEAD may
|
|
199
195
|
# already be this workflow's own docs commit — never bump twice.
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# project-auto-wizard:managed-workflow
|
|
2
|
-
# ===================================================================
|
|
3
2
|
# PROJECT-COMMON-VERSION-CONTROL.yaml
|
|
4
3
|
# Safety-net automatic version bump
|
|
5
|
-
# ===================================================================
|
|
6
4
|
#
|
|
7
5
|
# [Safety net] Only when a direct push (one that did not go through a
|
|
8
6
|
# release PR) lands on {{MAIN_BRANCH}} (production), this workflow bumps
|
|
@@ -20,11 +18,9 @@
|
|
|
20
18
|
# Release-confirm pattern: "chore(release):" — keep in sync with
|
|
21
19
|
# PROJECT-COMMON-AUTO-CHANGELOG-CONTROL and PROJECT-COMMON-RELEASE-PUBLISH.
|
|
22
20
|
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
# manual re-run.
|
|
27
|
-
# ===================================================================
|
|
21
|
+
# After pushing the safety-net bump, this workflow also triggers
|
|
22
|
+
# RELEASE-PUBLISH via workflow_dispatch so a version drift is
|
|
23
|
+
# auto-recovered instead of requiring a manual re-run.
|
|
28
24
|
|
|
29
25
|
name: PROJECT-VERSION-CONTROL
|
|
30
26
|
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# project-auto-wizard:managed-workflow
|
|
2
|
-
# ===================================================================
|
|
3
2
|
# Flutter Android Firebase App Distribution 배포
|
|
4
|
-
# ===================================================================
|
|
5
3
|
#
|
|
6
4
|
# {{MAIN_BRANCH}} 브랜치 푸시 시 Android AAB를 빌드하고
|
|
7
5
|
# Firebase App Distribution에 자동 배포합니다.
|
|
@@ -9,44 +7,36 @@
|
|
|
9
7
|
# PlayStore CICD와 동일한 빌드 과정(AAB + 버전 검증)을 거친 후
|
|
10
8
|
# Play Store 대신 Firebase App Distribution에 업로드합니다.
|
|
11
9
|
#
|
|
12
|
-
#
|
|
13
|
-
# 🔑 필수 GitHub Secrets
|
|
14
|
-
# ===================================================================
|
|
10
|
+
# 필수 GitHub Secrets
|
|
15
11
|
#
|
|
16
|
-
#
|
|
12
|
+
# Release Keystore:
|
|
17
13
|
# RELEASE_KEYSTORE_BASE64: 서명용 keystore (base64)
|
|
18
14
|
# RELEASE_KEYSTORE_PASSWORD: keystore 비밀번호
|
|
19
15
|
# RELEASE_KEY_ALIAS: key alias
|
|
20
16
|
# RELEASE_KEY_PASSWORD: key 비밀번호
|
|
21
17
|
#
|
|
22
|
-
#
|
|
18
|
+
# Firebase:
|
|
23
19
|
# FIREBASE_SERVICE_ACCOUNT_JSON_BASE64: Firebase 서비스 계정 JSON (base64)
|
|
24
20
|
#
|
|
25
|
-
#
|
|
21
|
+
# 환경 설정 (선택):
|
|
26
22
|
# ENV_FILE 또는 ENV: .env 파일 내용 (둘 중 하나, ENV_FILE 우선)
|
|
27
23
|
# GOOGLE_SERVICES_JSON: Firebase google-services.json
|
|
28
24
|
#
|
|
29
25
|
# ※ 위 Secrets는 저장소 Settings → Secrets and variables → Actions에 등록하세요.
|
|
30
26
|
# FIREBASE_APP_ID·FIREBASE_TESTER_GROUP은 아래 env 섹션 값을 직접 수정합니다.
|
|
31
27
|
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
# 🔧 프로젝트별 설정 (env 섹션에서 수정)
|
|
35
|
-
# ===================================================================
|
|
28
|
+
# 프로젝트별 설정 (env 섹션에서 수정)
|
|
36
29
|
# APP_ARTIFACT_NAME : 프로젝트 이름
|
|
37
30
|
# FLUTTER_VERSION : Flutter SDK 버전
|
|
38
31
|
# JAVA_VERSION : Java 버전
|
|
39
32
|
# FIREBASE_APP_ID : Firebase 앱 ID (Firebase Console에서 확인)
|
|
40
33
|
# FIREBASE_TESTER_GROUP : Firebase 테스터 그룹명
|
|
41
|
-
# ===================================================================
|
|
42
34
|
#
|
|
43
|
-
#
|
|
35
|
+
# 사전 설정:
|
|
44
36
|
# 1. Firebase Console → App Distribution → 테스터 그룹 생성
|
|
45
37
|
# 2. Firebase 서비스 계정 JSON 생성 (base64 인코딩)
|
|
46
38
|
# 3. GitHub Secrets에 FIREBASE_SERVICE_ACCOUNT_JSON_BASE64 등록
|
|
47
39
|
# 4. env 섹션의 FIREBASE_APP_ID, FIREBASE_TESTER_GROUP 수정
|
|
48
|
-
#
|
|
49
|
-
# ===================================================================
|
|
50
40
|
|
|
51
41
|
name: PROJECT-FLUTTER-ANDROID-FIREBASE-APPDIST-CICD
|
|
52
42
|
|
|
@@ -57,9 +47,7 @@ on:
|
|
|
57
47
|
workflow_dispatch:
|
|
58
48
|
|
|
59
49
|
env:
|
|
60
|
-
#
|
|
61
|
-
# 🔧 프로젝트별 설정 (아래 값들을 수정하세요)
|
|
62
|
-
# ============================================
|
|
50
|
+
# 프로젝트별 설정 (아래 값들을 수정하세요)
|
|
63
51
|
# 프로젝트 이름
|
|
64
52
|
APP_ARTIFACT_NAME: "__APP_ARTIFACT_NAME__" # @wizard ask:@repo
|
|
65
53
|
# Flutter/Java 버전
|
|
@@ -133,7 +121,6 @@ jobs:
|
|
|
133
121
|
dart run build_runner build --delete-conflicting-outputs
|
|
134
122
|
fi
|
|
135
123
|
|
|
136
|
-
# version_manager.py를 사용하여 현재 버전 정보 가져오기
|
|
137
124
|
- name: 현재 버전 정보 가져오기
|
|
138
125
|
id: current_version
|
|
139
126
|
working-directory: ${{ github.workspace }} # version_manager.py가 레포 루트 version.yml을 읽어야 함
|
|
@@ -161,7 +148,6 @@ jobs:
|
|
|
161
148
|
echo "TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')" >> $GITHUB_ENV
|
|
162
149
|
echo "PROJECT_TYPE=${{ env.PROJECT_TYPE }}" >> $GITHUB_ENV
|
|
163
150
|
|
|
164
|
-
# CHANGELOG.json에서 릴리즈 노트 추출 - changelog_manager.py 사용
|
|
165
151
|
- name: 릴리즈 노트 생성
|
|
166
152
|
id: release_notes
|
|
167
153
|
working-directory: ${{ github.workspace }} # CHANGELOG.json·changelog_manager.py·final_release_notes.txt(upload 짝)는 레포 루트 기준
|
|
@@ -194,7 +180,6 @@ jobs:
|
|
|
194
180
|
echo "v$VERSION 업데이트" > final_release_notes.txt
|
|
195
181
|
fi
|
|
196
182
|
|
|
197
|
-
# 릴리즈 노트를 아티팩트로 업로드
|
|
198
183
|
- name: Upload release notes
|
|
199
184
|
uses: actions/upload-artifact@v7
|
|
200
185
|
with:
|
|
@@ -232,7 +217,6 @@ jobs:
|
|
|
232
217
|
- name: Pull latest changes
|
|
233
218
|
run: git pull origin main
|
|
234
219
|
|
|
235
|
-
# 프로젝트 파일들 다운로드
|
|
236
220
|
- name: Download project files
|
|
237
221
|
uses: actions/download-artifact@v8
|
|
238
222
|
with:
|
|
@@ -254,7 +238,6 @@ jobs:
|
|
|
254
238
|
echo "dart-define file prepared"
|
|
255
239
|
fi
|
|
256
240
|
|
|
257
|
-
# Release Keystore 설정
|
|
258
241
|
- name: Setup Release Keystore
|
|
259
242
|
run: |
|
|
260
243
|
mkdir -p android/app/keystore
|
|
@@ -262,7 +245,6 @@ jobs:
|
|
|
262
245
|
echo "✅ Release Keystore 생성 완료"
|
|
263
246
|
ls -la android/app/keystore/
|
|
264
247
|
|
|
265
|
-
# key.properties 생성 (Release 서명 정보)
|
|
266
248
|
- name: Create key.properties
|
|
267
249
|
run: |
|
|
268
250
|
cat > android/key.properties << EOF
|
|
@@ -274,7 +256,6 @@ jobs:
|
|
|
274
256
|
echo "✅ key.properties 생성 완료"
|
|
275
257
|
cat android/key.properties
|
|
276
258
|
|
|
277
|
-
# Google-services.json 생성
|
|
278
259
|
- name: Create Google-services.json
|
|
279
260
|
run: |
|
|
280
261
|
cat << 'EOF' > android/app/google-services.json
|
|
@@ -318,7 +299,6 @@ jobs:
|
|
|
318
299
|
restore-keys: |
|
|
319
300
|
${{ runner.os }}-gradle-
|
|
320
301
|
|
|
321
|
-
# Android build.gradle.kts 수정 (release 서명 설정)
|
|
322
302
|
- name: Configure Android build for release
|
|
323
303
|
run: |
|
|
324
304
|
# build.gradle.kts에 release 서명 설정이 없으면 추가
|
|
@@ -331,7 +311,6 @@ jobs:
|
|
|
331
311
|
# pubspec.yaml은 x.y.z 형식 그대로 유지
|
|
332
312
|
# Flutter build 명령어의 --build-name, --build-number 플래그가 pubspec.yaml을 오버라이드함
|
|
333
313
|
|
|
334
|
-
# Flutter build appbundle (AAB 생성)
|
|
335
314
|
- name: Build Android App Bundle (AAB)
|
|
336
315
|
run: |
|
|
337
316
|
VERSION_NAME="${{ needs.prepare-build.outputs.version }}"
|
|
@@ -547,7 +526,6 @@ jobs:
|
|
|
547
526
|
echo "📱 파일 크기: $(du -h "$AAB_FILE" | cut -f1)"
|
|
548
527
|
echo "=========================================="
|
|
549
528
|
|
|
550
|
-
# AAB 파일을 아티팩트로 업로드
|
|
551
529
|
- name: Upload AAB artifact
|
|
552
530
|
uses: actions/upload-artifact@v7
|
|
553
531
|
with:
|
|
@@ -567,21 +545,18 @@ jobs:
|
|
|
567
545
|
ref: main
|
|
568
546
|
fetch-depth: 0
|
|
569
547
|
|
|
570
|
-
# AAB 파일 다운로드
|
|
571
548
|
- name: Download AAB artifact
|
|
572
549
|
uses: actions/download-artifact@v8
|
|
573
550
|
with:
|
|
574
551
|
name: android-aab
|
|
575
552
|
path: ${{ env.FLUTTER_PROJECT_DIR }}/build/app/outputs/bundle/release/
|
|
576
553
|
|
|
577
|
-
# 릴리즈 노트 다운로드
|
|
578
554
|
- name: Download release notes
|
|
579
555
|
uses: actions/download-artifact@v8
|
|
580
556
|
with:
|
|
581
557
|
name: release-notes
|
|
582
558
|
path: .
|
|
583
559
|
|
|
584
|
-
# Firebase 서비스 계정 설정
|
|
585
560
|
- name: Setup Firebase credentials file
|
|
586
561
|
run: |
|
|
587
562
|
echo "${{ secrets.FIREBASE_SERVICE_ACCOUNT_JSON_BASE64 }}" | base64 --decode > firebase-service-account.json
|
|
@@ -595,7 +570,6 @@ jobs:
|
|
|
595
570
|
python3 ./.github/scripts/truncate_release_notes.py final_release_notes.txt 4000 char
|
|
596
571
|
fi
|
|
597
572
|
|
|
598
|
-
# Firebase App Distribution에 AAB 업로드
|
|
599
573
|
- name: Upload to Firebase App Distribution
|
|
600
574
|
id: firebase_upload
|
|
601
575
|
uses: wzieba/Firebase-Distribution-Github-Action@v1
|
|
@@ -611,7 +585,6 @@ jobs:
|
|
|
611
585
|
if: always()
|
|
612
586
|
run: rm -f firebase-service-account.json
|
|
613
587
|
|
|
614
|
-
# 성공 알림
|
|
615
588
|
- name: Notify Firebase Upload Success
|
|
616
589
|
if: success()
|
|
617
590
|
run: |
|