project-auto-wizard 0.12.2 → 0.13.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.ja.md +165 -0
- package/README.ko.md +165 -0
- package/README.md +107 -286
- package/README.zh-CN.md +165 -0
- package/bin/project-auto-wizard.js +1 -2
- package/package.json +7 -3
- package/payload/config/breaking-changes.json +24 -0
- package/payload/config/wizard-prompts.yml +45 -0
- package/payload/scripts/changelog_manager.py +141 -46
- package/payload/scripts/issue_helper.py +34 -5
- package/payload/scripts/version_manager.py +397 -97
- package/payload/version.yml.template +4 -2
- package/payload/workflows/common/PROJECT-COMMON-AI-PR-SUMMARY.yaml +39 -9
- package/payload/workflows/common/PROJECT-COMMON-AUTO-CHANGELOG-CONTROL.yaml +165 -38
- package/payload/workflows/common/PROJECT-COMMON-README-VERSION-UPDATE.yaml +14 -5
- package/payload/workflows/common/PROJECT-COMMON-RELEASE-PUBLISH.yaml +220 -6
- package/payload/workflows/common/PROJECT-COMMON-VERSION-CONTROL.yaml +89 -3
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-FIREBASE-CICD.yaml +78 -16
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-PLAYSTORE-CICD.yaml +72 -16
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-SELFHOSTED-CICD.yaml +62 -20
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-TEST-APK.yaml +51 -13
- package/payload/workflows/flutter/PROJECT-FLUTTER-CI.yaml +75 -11
- package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TEST-TESTFLIGHT.yaml +52 -3
- package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TESTFLIGHT.yaml +60 -11
- package/payload/workflows/go/PROJECT-GO-CI.yaml +10 -1
- package/payload/workflows/go/PROJECT-GO-PR-PREVIEW.yaml +148 -28
- package/payload/workflows/go/PROJECT-GO-SIMPLE-CICD.yaml +45 -4
- package/payload/workflows/next/PROJECT-NEXT-CI.yaml +25 -3
- package/payload/workflows/next/PROJECT-NEXT-CICD.yaml +83 -9
- package/payload/workflows/python/PROJECT-PYTHON-CI.yaml +70 -6
- package/payload/workflows/python/PROJECT-PYTHON-PR-PREVIEW.yaml +148 -28
- package/payload/workflows/python/PROJECT-PYTHON-SIMPLE-CICD.yaml +45 -4
- package/payload/workflows/react/PROJECT-REACT-CI.yaml +25 -3
- package/payload/workflows/react/PROJECT-REACT-CICD.yaml +84 -10
- package/payload/workflows/spring/PROJECT-SPRING-CI.yml +13 -3
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-NGINX-CICD.yaml +47 -5
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-TRAEFIK-CICD.yaml +47 -5
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-PR-PREVIEW.yaml +153 -30
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-SIMPLE-CICD.yaml +47 -5
- package/src/cli/args.js +33 -24
- package/src/cli/help.js +16 -4
- package/src/commands/doctor.js +17 -10
- package/src/commands/dry-run.js +54 -1
- package/src/commands/full.js +127 -50
- package/src/commands/interactive-flutter.js +1 -1
- package/src/commands/interactive.js +124 -56
- package/src/commands/purge.js +59 -17
- package/src/commands/status.js +16 -1
- package/src/commands/uninstall.js +58 -13
- package/src/context.js +5 -5
- package/src/core/baseline.js +20 -5
- package/src/core/branches.js +19 -1
- package/src/core/branding.js +1 -1
- package/src/core/breaking-check.js +14 -19
- package/src/core/breaking.js +7 -3
- package/src/core/copy/gitignore.js +20 -12
- package/src/core/copy/readme.js +24 -5
- package/src/core/copy/simple.js +52 -13
- package/src/core/copy/workflows.js +90 -47
- package/src/core/deploy-style.js +83 -11
- package/src/core/detect-fs.js +127 -24
- package/src/core/detect.js +131 -47
- package/src/core/errors.js +3 -0
- package/src/core/flutter-options.js +4 -3
- package/src/core/fsutil.js +23 -6
- package/src/core/logger.js +55 -19
- package/src/core/paths-resolve.js +50 -47
- package/src/core/paths.js +26 -1
- package/src/core/release-options.js +23 -0
- package/src/core/removal-plan.js +75 -19
- package/src/core/types.js +113 -0
- package/src/core/verify.js +85 -19
- package/src/core/version-yml.js +42 -8
- package/src/core/wizard-env.js +21 -14
- package/src/core/wizard-labels.js +34 -25
- package/src/index.js +122 -49
- package/src/ui/ansi.js +3 -1
- package/src/ui/banner.js +12 -8
- package/src/ui/env-plan.js +68 -44
- package/src/ui/prompts.js +22 -12
- package/src/ui/readline-engine.js +109 -22
- package/src/ui/status-cards.js +10 -5
- package/src/ui/summary.js +71 -33
- 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/README.md
CHANGED
|
@@ -1,348 +1,169 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**English** · [한국어](README.ko.md) · [简体中文](README.zh-CN.md) · [日本語](README.ja.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# project-auto-wizard
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
npx project-auto-wizard
|
|
9
|
-
```
|
|
7
|
+
**One command sets up versioning, CHANGELOG, GitHub Releases and CI/CD in your repo.**
|
|
10
8
|
|
|
9
|
+
Everything it installs is plain GitHub Actions in your own repository. No API keys, no hosted service.
|
|
10
|
+
|
|
11
|
+
[Docs](https://twin-fang.github.io/project-auto-wizard/) · [Quickstart](#quickstart) · [Changelog](CHANGELOG.md)
|
|
11
12
|
|
|
12
13
|
[](https://github.com/Twin-Fang/project-auto-wizard/actions/workflows/CI.yaml)
|
|
13
|
-
[](https://www.npmjs.com/package/project-auto-wizard)
|
|
14
|
+
[](https://www.npmjs.com/package/project-auto-wizard)
|
|
15
|
+
[](https://www.npmjs.com/package/project-auto-wizard)
|
|
14
16
|
[](LICENSE)
|
|
15
17
|
[](package.json)
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
## 최신 버전 : v0.12.1 (2026-09-26)
|
|
19
|
-
|
|
20
|
-
[전체 버전 기록 보기](CHANGELOG.md)
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## 왜 만들었나
|
|
19
|
+
<img src="https://raw.githubusercontent.com/Twin-Fang/project-auto-wizard/main/assets/demo/install.gif" alt="Installing release automation into a Spring project with the wizard" width="800">
|
|
25
20
|
|
|
26
|
-
|
|
27
|
-
project-auto-wizard는 이걸 **한 줄, 3분**으로 줄입니다.
|
|
21
|
+
</div>
|
|
28
22
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
npx project-auto-wizard --mode full --force --type spring,react # CI에서 비대화형
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## 무엇을 설치하나 — 3축
|
|
23
|
+
<!-- AUTO-VERSION-SECTION: DO NOT EDIT MANUALLY -->
|
|
24
|
+
## Latest Version : v0.13.0 (2026-09-30)
|
|
35
25
|
|
|
36
|
-
|
|
37
|
-
|---|---|
|
|
38
|
-
| ① **npx 마법사** | 마커 파일로 프로젝트 타입 자동 감지 — **10타입 + 멀티타입 + 모노레포 경로**까지. 질문은 최소한만 |
|
|
39
|
-
| ② **GitHub-native Release Automation** | 릴리스 PR을 열면: 버전 확정 → **릴리스 노트 작성**(기본은 규칙 기반, GitHub Copilot AI는 선택) → CHANGELOG 갱신 → automerge → tag + GitHub Release. **API 키 0개** |
|
|
40
|
-
| ③ **타입별 CI/CD 워크플로우** | Spring(무중단 배포 포함)·Flutter(스토어 배포)·React·Next·Python·Go 등 타입에 맞는 GitHub Actions 자동 배치 |
|
|
26
|
+
[Full release history](CHANGELOG.md)
|
|
41
27
|
|
|
42
|
-
|
|
28
|
+
## Why
|
|
43
29
|
|
|
44
|
-
|
|
30
|
+
Every new project starts with the same chores before the first feature: decide how versions are bumped, keep a CHANGELOG, write release notes, tag releases, and copy CI/CD workflows over from the last project and fix them up. It takes hours, and each repo ends up slightly different.
|
|
45
31
|
|
|
46
|
-
-
|
|
47
|
-
- **모노레포**: `--paths "flutter=app,react=client"` — 타입별 서브폴더 지정 (마커 파일 자동 감지)
|
|
48
|
-
- `spring`/`flutter`/`react`/`next`/`python`/`go` 6개 타입은 아래 "타입별 워크플로우 구성"처럼 전용 CI/CD가 설치됩니다. `node`/`react-native`/`react-native-expo`/`basic`은 타입 전용 CI 없이 릴리스 자동화(버전 관리·체인지로그·AI 요약)를 담당하는 공통 워크플로우만 설치됩니다 — 빌드/배포 CI는 직접 추가해서 확장할 수 있습니다.
|
|
32
|
+
project-auto-wizard does that setup once, with a few prompts. After that, merging a release PR is all it takes to cut a release.
|
|
49
33
|
|
|
50
|
-
|
|
34
|
+
<a id="quickstart"></a>
|
|
51
35
|
|
|
52
|
-
|
|
36
|
+
## Quickstart
|
|
53
37
|
|
|
54
|
-
|
|
55
|
-
PROJECT_NAME:
|
|
56
|
-
label: "프로젝트 이름이 뭔가요?"
|
|
57
|
-
help: "GitHub 레포 이름과 다르게 표시하고 싶을 때만 입력하세요."
|
|
38
|
+
Run it in the root of your repository (Node.js 20.12 or later):
|
|
58
39
|
|
|
59
|
-
|
|
60
|
-
|
|
40
|
+
```bash
|
|
41
|
+
npx project-auto-wizard
|
|
61
42
|
```
|
|
62
43
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
`spring`/`flutter`는 아래처럼 단일 CI 이상으로 깊게 구성되어 있습니다:
|
|
66
|
-
|
|
67
|
-
- **flutter**: Android(Firebase/Playstore/Selfhosted/TestAPK 배포), iOS(TestFlight/Test-TestFlight), CI, Lab 트리거까지 8종 — 스토어 배포(Play Store·TestFlight)는 고른 플랫폼만 설치되고 fastlane 파일도 함께 생성됩니다. 환경변수 방식·배포 모드 등 자세한 내용은 아래 "Flutter 워크플로우 상세"를 참고하세요.
|
|
68
|
-
- **spring**: 서버 배포 1종(단일 서버 / 무중단 Nginx / 무중단 Traefik / 배포 안 함 중 택1) + PR 프리뷰 + CI
|
|
69
|
-
- 서버 배포 워크플로우는 **서로 대체재**라 하나만 설치합니다. 대화형에서 고르면 그것만 깔리고 **`push` 트리거까지 켜진 채로** 설치됩니다. 비대화형은 `--deploy-style simple|nginx|traefik|none` (기본: `simple`).
|
|
70
|
-
- 고른 방식은 `version.yml`에 기록되므로 다시 실행해도 묻지 않습니다. 방식을 바꾸면 **이전 워크플로우를 마법사가 정리합니다** — 손대지 않은 파일은 삭제하고, 수정한 파일은 `.bak`으로 옮겨 내용을 보존합니다. 남겨두면 배포가 두 번 돕니다.
|
|
71
|
-
- PR 프리뷰는 배포 방식과 무관한 별개 축이라 선택과 관계없이 함께 설치됩니다 (단, `none`을 고르면 PR 프리뷰도 함께 제외됩니다 — 서버 배포 자체를 하지 않는 프로젝트를 위한 선택지입니다).
|
|
72
|
-
- **react/next**: CI와 CI+CD 분리 구성
|
|
73
|
-
- **python**: CI / PR 프리뷰 / SimpleCICD
|
|
74
|
-
- **go**: CI(Dockerfile 불필요, go test/vet/build/lint) / PR 프리뷰 / SimpleCICD(Dockerfile 있는 프로젝트만 해당)
|
|
44
|
+
It detects your project type, asks a few questions (branch strategy, deploy style, whether to use Copilot for summaries) and writes the files. For CI or scripts, run it non-interactively:
|
|
75
45
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
프로젝트 타입에 `flutter`가 포함되면 마법사가 아래 선택지 3개를 묻습니다. 고른 값은 `version.yml`의 `metadata.template.options`(`env_mode`, `flutter_store`, `android_deploy_mode`, `ios_deploy_mode`)에 기록되므로 다시 실행해도 묻지 않고, 나중에 바꾸려면 확인 화면의 **수정하기 > 환경변수 방식 / 스토어 배포 대상 / 배포 모드**를 쓰세요. Flutter가 없는 프로젝트에는 이 질문·저장값이 전혀 나타나지 않습니다.
|
|
81
|
-
|
|
82
|
-
| 선택지 | 값 | 기본값 | CLI 플래그 |
|
|
83
|
-
|---|---|---|---|
|
|
84
|
-
| 환경변수 방식 | `dart-define` / `dotenv` | 신규 설치는 `dart-define`. `version.yml`이 이미 있고 저장값이 없는 설치는 기존 동작을 보존하려고 `dotenv` 유지 | `--flutter-env-mode` |
|
|
85
|
-
| 스토어 배포 대상 | Android(Play Store) / iOS(TestFlight) 다중 선택 | 대화형 신규 설치는 아무것도 선택하지 않은 상태, 비대화형·플래그 미지정은 현행 동작(둘 다 설치). 저장값이 없는 기존 설치는 이미 설치된 스토어 워크플로우에서 초기 선택을 추론 | `--flutter-store android,ios,none` |
|
|
86
|
-
| 배포 모드 | 고른 플랫폼별 `store_only` / `store_prepare` / `store_submit` | `store_only` | `--android-deploy-mode`, `--ios-deploy-mode` |
|
|
87
|
-
|
|
88
|
-
**설치되는 구성**
|
|
89
|
-
|
|
90
|
-
- 항상 설치: `CI`, `ANDROID-FIREBASE-CICD`, `ANDROID-SELFHOSTED-CICD`, `ANDROID-TEST-APK`, `APP-BUILD-TRIGGER`
|
|
91
|
-
- Android를 고르면: `ANDROID-PLAYSTORE-CICD` + `android/fastlane/Fastfile.playstore`
|
|
92
|
-
- iOS를 고르면: `IOS-TESTFLIGHT` + `IOS-TEST-TESTFLIGHT` + `ios/fastlane/Fastfile` + `ios/ExportOptions.plist`
|
|
93
|
-
- fastlane은 위 스토어 배포 워크플로우에서만 씁니다. `SELFHOSTED`와 `TEST-APK`는 `flutter build apk --release`를 직접 실행하며 Ruby·fastlane을 설치하지 않습니다.
|
|
94
|
-
- `Fastfile`과 `ExportOptions.plist`는 **Flutter 루트 기준**으로(모노레포는 `--paths flutter=app`이면 `app/` 아래) **없을 때만 생성**합니다. 이미 있으면 덮어쓰지 않고 설치 요약과 `--dry-run`에 "기존 파일 유지"로 표시하며, `--mode uninstall`도 이 파일들은 건드리지 않습니다(사용자 소유 파일).
|
|
95
|
-
- 스토어 대상을 해제하고 다시 실행하면 배포 방식을 바꿀 때와 같은 규칙으로 정리합니다 — 손대지 않은 워크플로우는 삭제하고, 수정한 것은 `.bak`으로 옮겨 보존합니다. `Fastfile`·`ExportOptions.plist`는 삭제하지 않습니다.
|
|
96
|
-
|
|
97
|
-
**환경변수 방식**
|
|
98
|
-
|
|
99
|
-
두 방식 모두 시크릿 `ENV_FILE`(없으면 `ENV`)에 `.env` 형식으로 값을 넣어 두면 됩니다. 두 방식을 동시에 쓰는 모드는 없습니다.
|
|
100
|
-
|
|
101
|
-
- `dart-define`: `ENV_FILE`을 프로젝트 밖 임시 경로(러너 임시 폴더)에 쓰고 모든 `flutter build`에 `--dart-define-from-file`로 넘깁니다. 프로젝트 루트에는 `.env`를 만들지 않으며, 코드에서는 `String.fromEnvironment('KEY')`로 읽습니다. 값이 아닌 파일 경로를 넘기므로 `--verbose` 로그에도 값이 명령줄에 노출되지 않습니다.
|
|
102
|
-
- `dotenv`: Flutter 루트에 `.env`를 만든 뒤 빌드합니다(`build_runner`가 그 뒤에 실행되는 순서 유지). `flutter_dotenv`·`envied`를 쓰는 프로젝트가 여기에 해당합니다. 이 `.env`에는 아래 파서 제약이 적용되지 않습니다.
|
|
103
|
-
|
|
104
|
-
`dart-define` 방식에서 `ENV_FILE`은 Flutter의 `--dart-define-from-file` 파서가 읽으므로 다음 범위만 지원됩니다 (근거: Flutter 3.47.5 `flutter_tools/lib/src/runner/flutter_command.dart`의 `DotEnvRegex`).
|
|
105
|
-
|
|
106
|
-
- 내용이 `{`로 시작하면 JSON 파일로 해석하고, 그렇지 않으면 `KEY=값` 줄로 해석합니다. 키는 `[a-zA-Z_][a-zA-Z0-9_]*` 형태여야 합니다.
|
|
107
|
-
- `#`로 시작하는 주석 줄과 빈 줄은 무시합니다.
|
|
108
|
-
- 값은 `"…"`, `'…'`, `` `…` `` 따옴표가 벗겨지고 그 뒤의 `# 주석`은 제거됩니다. 따옴표 없는 값은 공백 또는 `#` 앞까지 읽으며, 값 안의 `=`는 허용됩니다.
|
|
109
|
-
- `export KEY=값` 형태와 멀티라인(`"""`) 값은 지원하지 않아 빌드가 오류로 종료됩니다.
|
|
110
|
-
|
|
111
|
-
**배포 모드** — 플랫폼별로 아래처럼 동작합니다(모르는 값은 `store_only`로 취급). 기본값은 워크플로우 표현식의 폴백 자리에 반영되며, 저장소 변수 `ANDROID_DEPLOY_MODE`·`IOS_DEPLOY_MODE`와 `workflow_dispatch` 입력이 항상 우선합니다.
|
|
112
|
-
|
|
113
|
-
| 모드 | Play Store (Android) | TestFlight / App Store (iOS) |
|
|
114
|
-
|---|---|---|
|
|
115
|
-
| `store_only` | internal 트랙에 업로드 | TestFlight 업로드 |
|
|
116
|
-
| `store_prepare` | production 트랙에 draft 상태로 업로드 (Play Console에서 직접 출시) | 앱 버전·메타데이터 준비까지 (심사 제출 안 함) |
|
|
117
|
-
| `store_submit` | production 트랙에 심사 제출 | 심사 제출까지 |
|
|
118
|
-
|
|
119
|
-
> `store_submit`을 고르면 **main push마다 심사가 자동 제출**됩니다.
|
|
120
|
-
|
|
121
|
-
**필요한 Secrets · Variables** — 설치 완료 화면과 실행 로그에도 설치된 워크플로우가 실제로 요구하는 Secret 목록이 출력됩니다.
|
|
122
|
-
|
|
123
|
-
| 대상 | Secrets | Variables |
|
|
124
|
-
|---|---|---|
|
|
125
|
-
| 모든 Flutter 빌드 | `ENV_FILE` (없으면 `ENV`) | — |
|
|
126
|
-
| Android 서명 (`PLAYSTORE`·`FIREBASE`·`TEST-APK`) | `RELEASE_KEYSTORE_BASE64`, `RELEASE_KEYSTORE_PASSWORD`, `RELEASE_KEY_ALIAS`, `RELEASE_KEY_PASSWORD`, `GOOGLE_SERVICES_JSON` | — |
|
|
127
|
-
| Play Store (`PLAYSTORE`) | `GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_BASE64`, `ANDROID_PACKAGE_NAME` | `ANDROID_PACKAGE_NAME`(Secret이 없을 때 대신 사용), `ANDROID_DEPLOY_MODE`(선택) |
|
|
128
|
-
| iOS (`IOS-TESTFLIGHT`·`IOS-TEST-TESTFLIGHT`) | `APP_STORE_CONNECT_API_KEY_BASE64`, `APP_STORE_CONNECT_API_KEY_ID`, `APP_STORE_CONNECT_ISSUER_ID`, `APPLE_CERTIFICATE_BASE64`, `APPLE_CERTIFICATE_PASSWORD`, `APPLE_PROVISIONING_PROFILE_BASE64`, `IOS_PROVISIONING_PROFILE_NAME`, `IOS_BUNDLE_ID`, `SECRETS_XCCONFIG`(선택) | `IOS_BUNDLE_ID`(Secret이 없을 때 대신 사용), `IOS_DEPLOY_MODE`(선택) |
|
|
129
|
-
| Firebase 배포 (`FIREBASE`·`TEST-APK`) | `FIREBASE_SERVICE_ACCOUNT_JSON_BASE64` | — |
|
|
130
|
-
| Selfhosted 배포 (`SELFHOSTED`) | `SERVER_HOST`, `SERVER_USER`, `SERVER_PASSWORD`, `DEBUG_KEYSTORE` | — |
|
|
46
|
+
```bash
|
|
47
|
+
npx project-auto-wizard --mode full --force --type spring,react
|
|
48
|
+
npx project-auto-wizard --mode full --force --type node --dry-run # preview only, writes nothing
|
|
49
|
+
```
|
|
131
50
|
|
|
132
|
-
|
|
51
|
+
Commit the generated files and push. `npx project-auto-wizard --mode doctor` checks the repository settings the workflows depend on.
|
|
133
52
|
|
|
134
|
-
|
|
53
|
+
## What you get
|
|
135
54
|
|
|
136
|
-
|
|
|
55
|
+
| Installed | Purpose |
|
|
137
56
|
|---|---|
|
|
138
|
-
| `
|
|
139
|
-
|
|
|
140
|
-
| `
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
- `--paths flutter=app`처럼 Flutter 하위 폴더를 지정하면 모든 Flutter 워크플로우가 그 폴더(`FLUTTER_PROJECT_DIR`)를 기준으로 동작하고, main push로 도는 배포 워크플로우(`PLAYSTORE`·`IOS-TESTFLIGHT`·`SELFHOSTED`·`FIREBASE`)는 `app/**`가 바뀔 때만 실행됩니다(Spring 등 다른 타입과 같은 `paths` 필터).
|
|
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가 하나라도 있으면 실패합니다.
|
|
146
|
-
- 브랜치 보호 규칙의 required status check에는 개별 job이 아니라 **`CI Gate`(`ci-gate`) 하나만** 등록하세요. 경로 필터로 워크플로우 자체를 건너뛰면 required check가 Pending에 머물러 머지가 막히지만, job을 건너뛰는 방식은 그렇지 않기 때문입니다.
|
|
147
|
-
- 워크플로우 `paths` 필터는 태그 push에 적용되지 않습니다(GitHub 문서).
|
|
57
|
+
| `.github/workflows/PROJECT-COMMON-*.yaml` | Release automation: version bump, release PR notes, CHANGELOG, tag and GitHub Release, README version line, PR summary comments, branch-name suggestions on new issues |
|
|
58
|
+
| `.github/workflows/PROJECT-<TYPE>-*` | CI/CD for your stack (Spring, Flutter, React, Next.js, Python, Go) |
|
|
59
|
+
| `.github/scripts/*.py` | The logic behind the workflows, standard-library Python only |
|
|
60
|
+
| `version.yml` | Single source of the version, project types, paths, branches and options |
|
|
61
|
+
| `README.md` version section | Kept up to date after every release |
|
|
148
62
|
|
|
149
|
-
|
|
63
|
+
The files are yours to read and edit. Running the wizard again updates them: files you changed are kept when the upstream version did not change, and when both changed it asks whether to keep yours, replace with a backup, or add the new version alongside.
|
|
150
64
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
설치·업데이트·삭제를 실행할 때마다 `.github/.wizard/logs/<시각>-<동작>.log`에 실행 추적이 남습니다. 감지 근거, **파일별 처리 결정과 그 사유**, 치환된 값, 미치환 항목, 등록해야 하는 GitHub Secret이 시간순으로 기록되고, 파일 끝에 결과 요약이 붙습니다.
|
|
65
|
+
How a release flows with the default `pr-flow` strategy:
|
|
154
66
|
|
|
155
67
|
```
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
68
|
+
feature PRs ──▶ develop ──▶ release PR (develop → main)
|
|
69
|
+
│ next version from commit types: feat → minor, ! → major, else patch
|
|
70
|
+
│ release notes written, CHANGELOG.md / CHANGELOG.json updated
|
|
71
|
+
▼
|
|
72
|
+
automerge ──▶ tag vX.Y.Z + GitHub Release ──▶ README version updated
|
|
160
73
|
```
|
|
161
74
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
이 폴더에는 자체 `.gitignore`(`*`, `!.gitignore`)가 함께 생성되어 **로그가 git에 올라가지 않습니다**. 최근 20개만 보관하고 오래된 것부터 정리합니다. `--dry-run`은 파일을 만들지 않는 것이 계약이므로 로그도 남기지 않습니다.
|
|
75
|
+
With `trunk-based` (release branch = development branch), every push to the release branch runs the same steps in one workflow.
|
|
165
76
|
|
|
166
|
-
|
|
77
|
+
Release notes are rule-based by default. You can turn on GitHub Copilot (uses your Copilot AI Credits) or point it at any OpenAI-compatible API. If a model is unavailable or fails, it falls back to the rules, so a release is never blocked by the summary step.
|
|
167
78
|
|
|
168
|
-
|
|
79
|
+
## Without / with
|
|
169
80
|
|
|
170
|
-
|
|
81
|
+
| | Without | With project-auto-wizard |
|
|
82
|
+
|---|---|---|
|
|
83
|
+
| Initial setup | Copy workflows from an older repo and adapt them | `npx project-auto-wizard`, answer a few prompts |
|
|
84
|
+
| Next version | Decided and typed by hand | Derived from commit types in the release PR |
|
|
85
|
+
| CHANGELOG | Written by hand, often skipped | Updated when the release PR merges |
|
|
86
|
+
| Tags and Releases | Created manually | Created after merge |
|
|
87
|
+
| CI/CD per stack | Written per project | Installed for the detected types |
|
|
88
|
+
| AI summaries | Need an API key and custom scripting | Optional; rule-based works with no keys |
|
|
171
89
|
|
|
172
|
-
|
|
90
|
+
## Compared to other tools
|
|
173
91
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
92
|
+
| | project-auto-wizard | release-please | semantic-release | changesets |
|
|
93
|
+
|---|---|---|---|---|
|
|
94
|
+
| How it's added | Installs editable workflow files | GitHub Action + config | npm package run in CI + plugins | CLI + GitHub Action |
|
|
95
|
+
| Version decided by | Commit types (non-conventional commits → patch) | Conventional Commits | Conventional Commits (configurable) | Changeset files written by developers |
|
|
96
|
+
| Release PR | Yes (or trunk-based) | Yes | No, releases on push | Yes ("Version Packages") |
|
|
97
|
+
| Publishes to npm / PyPI | No | No | Yes, via plugins | Yes (npm) |
|
|
98
|
+
| Stack CI/CD included | Yes, per project type | No | No | No |
|
|
99
|
+
| Monorepo | Per-type paths, one shared version | Per-package versions | Community plugins | Per-package versions |
|
|
177
100
|
|
|
178
|
-
|
|
179
|
-
npx project-auto-wizard --mode uninstall # 대화형 체크리스트
|
|
180
|
-
npx project-auto-wizard --mode uninstall --force # 워크플로우·스크립트만 안전 삭제
|
|
181
|
-
npx project-auto-wizard --mode uninstall --force --purge-readme --purge-gitignore --purge-version # 완전 삭제
|
|
182
|
-
```
|
|
101
|
+
What the others do better:
|
|
183
102
|
|
|
184
|
-
|
|
103
|
+
- **release-please** is mature and widely used, updates version files for many ecosystems, and handles independently versioned packages in a monorepo.
|
|
104
|
+
- **semantic-release** publishes to npm and other registries with no manual step and has a large plugin ecosystem.
|
|
105
|
+
- **changesets** is the best fit for JavaScript monorepos publishing many packages, with changelog entries written by people rather than derived from commits.
|
|
185
106
|
|
|
186
|
-
|
|
107
|
+
## When to use it, and when not to
|
|
187
108
|
|
|
188
|
-
|
|
109
|
+
Use it if:
|
|
189
110
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
```
|
|
111
|
+
- you are starting a repo and want releases working from day one
|
|
112
|
+
- your team merges `develop` into `main` and wants a release PR with notes and a CHANGELOG
|
|
113
|
+
- you have a Spring, Flutter, React, Next.js, Python or Go project and want CI/CD and release automation from one setup
|
|
114
|
+
- one repo holds several stacks (for example a Spring backend and a React frontend) that share a version
|
|
195
115
|
|
|
196
|
-
|
|
197
|
-
- **Copilot은 GitHub Copilot AI Credits를 소비합니다.** 개인 저장소는 저장소 소유자의 Copilot 좌석에, 조직 저장소는 조직에 과금되며 조직은 "Allow use of Copilot CLI billed to the organization" 정책을 켜야 합니다. 사용할 수 없으면 자동으로 규칙 기반 요약으로 전환됩니다. PR에 푸시할 때마다 요약이 새로 생성되므로 그만큼 크레딧이 소비됩니다.
|
|
198
|
-
- Copilot은 항상 `auto` 모델 선택으로 호출됩니다. Copilot Free·Student 계정은 모델명을 직접 지정하는 호출이 거부되고 `auto`만 허용되기 때문에, 모델을 바꾸는 옵션은 제공하지 않습니다.
|
|
199
|
-
- GitHub은 Copilot CLI를 `run` 스텝에서 직접 호출하기보다 Agentic Workflows를 쓰라고 권고하지만, 이 프로젝트는 직접 호출을 택했습니다. 프롬프트 입력이 PR 제목·커밋 메시지·`git diff --stat`뿐이고, 빈 임시 디렉터리에서 shell/write/url 도구와 내장 MCP를 모두 막은 텍스트 생성 전용으로 호출하며, 포크 PR은 기존 가드로 건너뛰어 프롬프트 인젝션 위험을 낮췄기 때문입니다.
|
|
200
|
-
- `AI_API_KEY`(**Secret**)와 `AI_API_BASE_URL`·`AI_MODEL`(**Variables**)을 **모두** 설정하면 OpenAI-호환 엔드포인트(Groq, Gemini 호환 모드, Ollama 등)를 최우선으로 사용합니다. 셋 중 하나라도 없으면 이 단계는 건너뜁니다.
|
|
201
|
-
- 규칙 fallback 3단: 프로젝트 컨벤션 → Conventional Commits → 무형식 bullet. 커밋 컨벤션이 없어도 동작.
|
|
202
|
-
|
|
203
|
-
## 릴리스 흐름
|
|
204
|
-
|
|
205
|
-
```mermaid
|
|
206
|
-
flowchart LR
|
|
207
|
-
subgraph pr-flow ["pr-flow (기본)"]
|
|
208
|
-
D1[develop push] --> PR[develop→main 릴리스 PR]
|
|
209
|
-
PR --> V["버전 확정 (patch+1)"]
|
|
210
|
-
V --> AI[릴리스 노트]
|
|
211
|
-
AI --> CL[CHANGELOG.json/md 갱신]
|
|
212
|
-
CL --> AM[automerge]
|
|
213
|
-
AM --> TAG["tag vX.Y.Z + GitHub Release"]
|
|
214
|
-
end
|
|
215
|
-
```
|
|
116
|
+
Skip it if:
|
|
216
117
|
|
|
217
|
-
|
|
118
|
+
- a single package already releases fine with release-please or semantic-release
|
|
119
|
+
- the release itself must publish to a package registry (add your own workflow on the Release event, as this repo does for npm; this needs `WORKFLOW_PAT`, because releases created with `GITHUB_TOKEN` don't trigger other workflows)
|
|
120
|
+
- your packages need independent versions
|
|
121
|
+
- the repository is not on GitHub
|
|
218
122
|
|
|
219
|
-
|
|
220
|
-
- **trunk-based** (릴리스 브랜치 = 개발 브랜치): `RELEASE-PUBLISH` 하나가 main push마다 버전확정 → 체인지로그 → tag → Release를 순차 처리
|
|
221
|
-
- 마법사가 브랜치 전략(pr-flow/trunk-based)을 먼저 묻고, trunk-based를 고르면 개발 브랜치 질문 없이 릴리스 브랜치 하나만 사용합니다. 비대화형은 `--main-branch`/`--develop-branch` 플래그로 지정하며, 없으면 **생성 + push**까지. 선택은 `version.yml`에 저장되어 업데이트 시 재질문 없음
|
|
123
|
+
## Supported project types
|
|
222
124
|
|
|
223
|
-
|
|
125
|
+
| Type | Detected from | Installed on top of release automation |
|
|
126
|
+
|---|---|---|
|
|
127
|
+
| `spring` | `build.gradle`, `build.gradle.kts`, `pom.xml` | CI, server deploy (single server / zero-downtime Nginx or Traefik), PR preview |
|
|
128
|
+
| `flutter` | `pubspec.yaml` | CI, Android (Firebase, Play Store, self-hosted, test APK), iOS TestFlight |
|
|
129
|
+
| `react`, `next` | `package.json` dependencies | CI, CI + CD |
|
|
130
|
+
| `python` | `pyproject.toml`, `setup.py`, `requirements.txt` | CI, PR preview, server deploy |
|
|
131
|
+
| `go` | `go.mod` | CI, PR preview, server deploy |
|
|
132
|
+
| `node`, `react-native`, `react-native-expo`, `basic` | `package.json` / fallback | Release automation only |
|
|
224
133
|
|
|
225
|
-
|
|
226
|
-
npx project-auto-wizard [옵션]
|
|
227
|
-
|
|
228
|
-
-m, --mode MODE full | uninstall | status | doctor (기본: 대화형)
|
|
229
|
-
-t, --type CSV spring,react,... (미지정 시 자동 감지)
|
|
230
|
-
--project-version V 초기 버전 (미지정 시 자동 감지)
|
|
231
|
-
--paths "t=p,..." 모노레포 타입별 경로
|
|
232
|
-
--main-branch B 릴리스 브랜치 (기본: 감지된 default branch)
|
|
233
|
-
--develop-branch B 개발 브랜치 (기본: develop)
|
|
234
|
-
--deploy-style S 서버 배포 방식: simple | nginx | traefik | none (기본: simple)
|
|
235
|
-
--flutter-env-mode M Flutter 환경변수 방식: dart-define | dotenv (신규 기본: dart-define, 저장값 없는 기존 설치는 dotenv 유지)
|
|
236
|
-
--flutter-store CSV Flutter 스토어 배포 대상: android,ios,none (미지정 시 둘 다 설치)
|
|
237
|
-
--android-deploy-mode M Play Store 배포 모드: store_only | store_prepare | store_submit (기본: store_only)
|
|
238
|
-
--ios-deploy-mode M iOS 배포 모드: store_only | store_prepare | store_submit (기본: store_only)
|
|
239
|
-
--semver-auto 커밋 타입 기반 자동 major/minor/patch 승격 (기본: 사용함, --no-semver-auto로 끔)
|
|
240
|
-
--copilot Copilot으로 AI 요약 생성 (기본: 사용 안 함, GitHub Copilot AI Credits 소비, --no-copilot으로 끔)
|
|
241
|
-
--dry-run 실제 파일 변경 없이 무엇이 바뀔지만 미리 보여줌
|
|
242
|
-
--purge-readme --mode uninstall --force 시 README.md 버전 섹션도 제거
|
|
243
|
-
--purge-gitignore --mode uninstall --force 시 .gitignore 자동 추가 항목도 제거
|
|
244
|
-
--purge-version --mode uninstall --force 시 version.yml도 제거
|
|
245
|
-
--force full/version/workflows/revert 실행에 필수 (전 질문 생략, CI용)
|
|
246
|
-
```
|
|
134
|
+
Several types can live in one repo (`--type spring,react`), and monorepo subfolders are set with `--paths "flutter=app,react=client"`.
|
|
247
135
|
|
|
248
|
-
|
|
136
|
+
<a id="post-install"></a>
|
|
249
137
|
|
|
250
|
-
|
|
251
|
-
npx project-auto-wizard --mode status # 설치 상태·드리프트 확인 (읽기 전용)
|
|
252
|
-
npx project-auto-wizard --mode doctor # 환경 진단 (읽기 전용, 규칙 기반)
|
|
253
|
-
```
|
|
138
|
+
## After installing
|
|
254
139
|
|
|
255
|
-
|
|
|
140
|
+
| Item | What to do |
|
|
256
141
|
|---|---|
|
|
257
|
-
|
|
|
258
|
-
|
|
|
259
|
-
|
|
260
|
-
|
|
142
|
+
| Workflow permissions | The installed workflows declare their own permissions. Set Settings → Actions → General → Workflow permissions to **Read and write permissions** only if your own workflows rely on the default |
|
|
143
|
+
| Merge commits | Allow merge commits so the release PR can automerge |
|
|
144
|
+
| `WORKFLOW_PAT` (optional) | Without it, a `GITHUB_TOKEN` fallback finishes the release, including the deploy workflows on the release branch, about 20 seconds later. Required only if you add your own workflows triggered by the Release event. Issue it from a bot or machine account (scopes: `repo`, `workflow`) |
|
|
145
|
+
| Copilot summaries (optional) | Off by default. Uses Copilot AI Credits; organizations must allow Copilot CLI billed to the organization |
|
|
261
146
|
|
|
262
|
-
|
|
263
|
-
◆ 환경 진단 — project-auto-wizard doctor
|
|
264
|
-
|
|
265
|
-
[✓] gh CLI — 레포 설정 조회용 gh version 2.96.0
|
|
266
|
-
[✓] GitHub 로그인 — 레포 설정 조회 권한 인증됨
|
|
267
|
-
[✓] merge commit 허용 — 릴리스 PR 자동 머지 조건 허용됨
|
|
268
|
-
|
|
269
|
-
[i] Workflow permissions — 직접 추가한 워크플로우의 기본 권한
|
|
270
|
-
현재 read 입니다 — 마법사가 설치한 워크플로우는 각자 권한을 선언하므로 그대로 동작합니다.
|
|
271
|
-
[i] WORKFLOW_PAT — 자동 태그·Release 발행
|
|
272
|
-
secret이 없어도 폴백이 자동으로 이어받아 태그·Release까지 진행됩니다 — 실제 병합 후 최대 ~20초 정도 더 걸릴 뿐입니다.
|
|
273
|
-
속도를 더 원한다면 PAT을 등록할 수 있습니다 — 반드시 개인 계정이 아닌 조직 bot/machine 계정으로 발급하세요 (scopes: repo, workflow).
|
|
274
|
-
등록: 레포 Settings → Secrets and variables → Actions → New repository secret · 이름은 WORKFLOW_PAT
|
|
275
|
-
[i] Copilot AI 요약 — AI 릴리스 노트 생성(선택)
|
|
276
|
-
기본은 꺼져 있습니다 (version.yml의 copilot_ai: false).
|
|
277
|
-
켜면 GitHub Copilot AI Credits가 소비됩니다 — 조직은 'Allow use of Copilot CLI billed to the organization' 정책이 필요합니다.
|
|
278
|
-
꺼져 있거나 사용할 수 없으면 규칙 기반 요약으로 자동 전환되므로 그대로 두셔도 됩니다.
|
|
279
|
-
|
|
280
|
-
✓ 문제를 찾지 못했습니다.
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
> **드리프트 판정 기준**: `--mode status`는 설치된 워크플로우 파일이 "설치 시점 기본값 템플릿"과 바이트 단위로 일치하는지만 비교합니다 — 파일을 직접 편집했는지는 추적하지 않습니다. 대화형 설치에서 `@wizard ask` 질문(예: 배포 포트)에 기본값이 아닌 값으로 응답했다면, 파일을 전혀 수정하지 않았더라도 설치 직후부터 항상 "사용자가 수정한 워크플로우 파일"로 표시됩니다. 정상 동작이며, 파일을 직접 편집했는지 구분하려면 해당 값이 예상한 응답과 일치하는지 직접 확인하세요.
|
|
284
|
-
|
|
285
|
-
`--dry-run`을 어떤 모드와도 함께 쓰면 실제로 파일을 바꾸지 않고 무엇이 바뀔지만 미리 보여줍니다(`full`/`version`/`workflows`/`revert` 전체 지원):
|
|
286
|
-
|
|
287
|
-
```bash
|
|
288
|
-
npx project-auto-wizard --mode full --force --type node --dry-run
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
### 자동 semver 승격 (`--semver-auto`)
|
|
292
|
-
|
|
293
|
-
기본적으로 켜져 있습니다. 커밋 메시지 컨벤션(`feat:` → minor, `!` 브레이킹 마커 → major, 그 외 → patch)을 기반으로 다음 버전을 자동으로 계산합니다. 분류가 애매한 커밋은 AI 엔진 체인이 patch→minor 승격 여부를 판단합니다. 끄면 기존과 동일하게 항상 patch+1입니다.
|
|
294
|
-
|
|
295
|
-
```bash
|
|
296
|
-
npx project-auto-wizard --semver-auto # 기본값, 명시 지정도 가능
|
|
297
|
-
npx project-auto-wizard --no-semver-auto # 항상 patch+1 (레거시 동작)
|
|
298
|
-
```
|
|
147
|
+
<a id="flutter-store"></a>
|
|
299
148
|
|
|
300
|
-
|
|
149
|
+
Flutter store deployment (Play Store, Firebase, TestFlight) setup is described in the [Flutter page of the docs site](https://twin-fang.github.io/project-auto-wizard/project-types/flutter/).
|
|
301
150
|
|
|
302
|
-
|
|
151
|
+
## Documentation
|
|
303
152
|
|
|
304
|
-
|
|
153
|
+
The full documentation is at [twin-fang.github.io/project-auto-wizard](https://twin-fang.github.io/project-auto-wizard/), in English and Korean. Simplified Chinese and Japanese cover the landing page and quickstart; other pages fall back to English. It covers:
|
|
305
154
|
|
|
306
|
-
|
|
155
|
+
- every CLI option, `--mode status`, `--mode doctor`, `--dry-run` and `--mode uninstall`
|
|
156
|
+
- Flutter store deployment, deploy modes, required secrets and `ExportOptions.plist`
|
|
157
|
+
- the release notes engine chain and Copilot billing
|
|
158
|
+
- per-type workflow details, run logs, design principles and architecture
|
|
307
159
|
|
|
308
|
-
##
|
|
160
|
+
## Contributing
|
|
309
161
|
|
|
310
|
-
|
|
311
|
-
|---|---|
|
|
312
|
-
| **`WORKFLOW_PAT` secret** (선택 — 속도 최적화용) | 없어도 `GITHUB_TOKEN` 폴백이 automerge부터 Release 발행까지 자동으로 이어갑니다(실제 병합 후 최대 ~20초 추가). 더 빠르게 하고 싶다면 Settings → Secrets → Actions에 `WORKFLOW_PAT` (scopes: `repo`, `workflow`) 등록 — 반드시 개인 계정이 아닌 조직 bot/machine 계정으로 발급하세요 |
|
|
313
|
-
| **Workflow permissions** | Settings → Actions → Workflow permissions: **Read and write** |
|
|
314
|
-
| **Copilot AI 요약** (선택) | 기본 꺼짐. 켜려면 마법사에서 선택하거나 `version.yml`의 `copilot_ai`를 `true`로 — AI Credits가 소비되며 조직은 "Allow use of Copilot CLI billed to the organization" 정책이 필요합니다. 사용할 수 없으면 자동으로 규칙 fallback |
|
|
315
|
-
|
|
316
|
-
## 설계 원칙
|
|
317
|
-
|
|
318
|
-
- **payload 단일 진실**: 마법사가 설치하는 모든 자산은 npm 패키지 동봉 `payload/` 하나에서 나옵니다. 템플릿 레포 clone 없음, 네트워크 접근 0, 설치 재현성 100%
|
|
319
|
-
- **크로스플랫폼 무결점**: 마법사는 Node, 설치되는 스크립트는 전부 Python. bash/PowerShell 이중 유지·macOS bash 3.2 함정을 **설계로 제거**
|
|
320
|
-
- **graceful degradation**: AI 실패 → 다음 엔진 → 규칙 fallback. 릴리스가 도구 때문에 막히는 일은 없습니다
|
|
321
|
-
- **표준 존중**: GitHub 기본 라벨·Releases·Conventional Commits — 커스텀 발명 대신 생태계 표준 위에 구축
|
|
322
|
-
- **멱등성**: 같은 명령을 다시 실행해도 안전 — unchanged 파일은 건너뛰고, 충돌은 3지선(유지/백업 후 교체/참고본 추가)으로 처리
|
|
323
|
-
|
|
324
|
-
## 아키텍처
|
|
325
|
-
|
|
326
|
-
```mermaid
|
|
327
|
-
flowchart TB
|
|
328
|
-
CLI["npx project-auto-wizard<br/>(Node CLI — 감지·질문·치환)"] --> P["payload/ (단일 진실)"]
|
|
329
|
-
P --> W[".github/workflows/*<br/>(브랜치 placeholder 치환 설치)"]
|
|
330
|
-
P --> S[".github/scripts/*.py<br/>(version_manager · changelog_manager)"]
|
|
331
|
-
P --> V["version.yml<br/>(버전·타입·경로·브랜치·옵션 기록)"]
|
|
332
|
-
W --> R["릴리스 자동화<br/>(AI 요약 엔진 체인)"]
|
|
333
|
-
S --> R
|
|
334
|
-
V --> R
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
## 개발
|
|
338
|
-
|
|
339
|
-
```bash
|
|
340
|
-
npm test # node --test + python unittest (node 222 + py 87)
|
|
341
|
-
npm run test:node
|
|
342
|
-
npm run test:py
|
|
343
|
-
```
|
|
162
|
+
Issues and pull requests are welcome. Branch from `develop` and open PRs against `develop`; see [CONTRIBUTING.md](CONTRIBUTING.md) for setup and tests (`npm test`). This repository releases itself with the workflows it installs.
|
|
344
163
|
|
|
345
|
-
|
|
164
|
+
- [ARCHITECTURE.md](ARCHITECTURE.md) — module map, install pipeline, `@wizard` marker grammar, how updates compare files
|
|
165
|
+
- [ADDING-A-PROJECT-TYPE.md](ADDING-A-PROJECT-TYPE.md) — step-by-step guide to adding a project type
|
|
166
|
+
- [CONTRIBUTING.md](CONTRIBUTING.md) — dev setup and pull request rules
|
|
346
167
|
|
|
347
168
|
## License
|
|
348
169
|
|