project-auto-wizard 0.13.3 → 0.15.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 +2 -0
- package/README.ko.md +2 -0
- package/README.md +3 -1
- package/README.zh-CN.md +2 -0
- package/bin/project-auto-wizard.js +18 -4
- package/package.json +2 -2
- package/payload/config/breaking-changes.json +28 -14
- package/payload/config/wizard-prompts.yml +102 -46
- package/payload/flutter-app/android/fastlane/Fastfile.playstore +44 -32
- package/payload/flutter-app/ios/ExportOptions.plist +8 -8
- package/payload/flutter-app/ios/fastlane/Fastfile +57 -43
- package/payload/scripts/changelog_manager.py +304 -265
- package/payload/scripts/issue_helper.py +54 -50
- package/payload/scripts/messages.py +2585 -0
- package/payload/scripts/truncate_release_notes.py +7 -6
- package/payload/scripts/version_manager.py +110 -107
- package/payload/version.yml.template +2 -1
- package/payload/workflows/common/PROJECT-COMMON-AI-PR-SUMMARY.yaml +23 -16
- package/payload/workflows/common/PROJECT-COMMON-AUTO-CHANGELOG-CONTROL.yaml +106 -63
- package/payload/workflows/common/PROJECT-COMMON-ISSUE-HELPER.yaml +17 -15
- package/payload/workflows/common/PROJECT-COMMON-README-VERSION-UPDATE.yaml +55 -45
- package/payload/workflows/common/PROJECT-COMMON-RELEASE-PUBLISH.yaml +90 -72
- package/payload/workflows/common/PROJECT-COMMON-VERSION-CONTROL.yaml +59 -45
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-FIREBASE-CICD.yaml +194 -184
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-PLAYSTORE-CICD.yaml +226 -213
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-SELFHOSTED-CICD.yaml +46 -42
- package/payload/workflows/flutter/PROJECT-FLUTTER-ANDROID-TEST-APK.yaml +334 -241
- package/payload/workflows/flutter/PROJECT-FLUTTER-APP-BUILD-TRIGGER.yaml +152 -128
- package/payload/workflows/flutter/PROJECT-FLUTTER-CI.yaml +246 -188
- package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TEST-TESTFLIGHT.yaml +353 -238
- package/payload/workflows/flutter/PROJECT-FLUTTER-IOS-TESTFLIGHT.yaml +96 -85
- package/payload/workflows/go/PROJECT-GO-CI.yaml +47 -36
- package/payload/workflows/go/PROJECT-GO-PR-PREVIEW.yaml +945 -508
- package/payload/workflows/go/PROJECT-GO-SIMPLE-CICD.yaml +155 -133
- package/payload/workflows/next/PROJECT-NEXT-CI.yaml +76 -60
- package/payload/workflows/next/PROJECT-NEXT-CICD.yaml +97 -77
- package/payload/workflows/python/PROJECT-PYTHON-CI.yaml +62 -47
- package/payload/workflows/python/PROJECT-PYTHON-PR-PREVIEW.yaml +942 -505
- package/payload/workflows/python/PROJECT-PYTHON-SIMPLE-CICD.yaml +148 -126
- package/payload/workflows/react/PROJECT-REACT-CI.yaml +86 -70
- package/payload/workflows/react/PROJECT-REACT-CICD.yaml +112 -92
- package/payload/workflows/spring/PROJECT-SPRING-CI.yml +112 -82
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-NGINX-CICD.yaml +180 -150
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-NONSTOP-TRAEFIK-CICD.yaml +161 -131
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-PR-PREVIEW.yaml +970 -549
- package/payload/workflows/spring/server-deploy/PROJECT-SPRING-SIMPLE-CICD.yaml +193 -162
- package/src/cli/args.js +98 -52
- package/src/cli/help.js +8 -41
- package/src/commands/doctor.js +90 -89
- package/src/commands/dry-run.js +64 -43
- package/src/commands/full.js +79 -77
- package/src/commands/install-settings.js +16 -15
- package/src/commands/interactive-flutter.js +20 -19
- package/src/commands/interactive.js +135 -132
- package/src/commands/purge.js +47 -42
- package/src/commands/status.js +36 -36
- package/src/commands/uninstall.js +43 -41
- package/src/context.js +12 -11
- package/src/core/assets.js +12 -11
- package/src/core/baseline.js +27 -27
- package/src/core/branches.js +29 -27
- package/src/core/branding.js +7 -6
- package/src/core/breaking-check.js +22 -21
- package/src/core/breaking.js +15 -8
- package/src/core/copy/app-files.js +5 -4
- package/src/core/copy/flutter-app.js +8 -8
- package/src/core/copy/gitignore.js +58 -50
- package/src/core/copy/readme.js +102 -36
- package/src/core/copy/simple.js +16 -15
- package/src/core/copy/workflows.js +131 -124
- package/src/core/deploy-style.js +51 -48
- package/src/core/detect-fs.js +57 -57
- package/src/core/detect.js +67 -65
- package/src/core/errors.js +2 -2
- package/src/core/flutter-doctor.js +17 -16
- package/src/core/flutter-hooks.js +33 -32
- package/src/core/flutter-options.js +34 -33
- package/src/core/fsutil.js +12 -12
- package/src/core/installed-stores.js +4 -4
- package/src/core/logger.js +42 -40
- package/src/core/paths-resolve.js +88 -86
- package/src/core/paths.js +10 -10
- package/src/core/release-options.js +8 -8
- package/src/core/removal-exec.js +14 -13
- package/src/core/removal-plan.js +37 -37
- package/src/core/types.js +47 -47
- package/src/core/verify.js +44 -38
- package/src/core/version-yml.js +76 -68
- package/src/core/wizard-env.js +46 -46
- package/src/core/wizard-labels.js +63 -41
- package/src/i18n/catalog/en/cli.js +50 -0
- package/src/i18n/catalog/en/commands.js +188 -0
- package/src/i18n/catalog/en/copy.js +20 -0
- package/src/i18n/catalog/en/core.js +74 -0
- package/src/i18n/catalog/en/core2.js +15 -0
- package/src/i18n/catalog/en/ui.js +221 -0
- package/src/i18n/catalog/en.js +12 -0
- package/src/i18n/catalog/index.js +5 -0
- package/src/i18n/catalog/ko/cli.js +50 -0
- package/src/i18n/catalog/ko/commands.js +188 -0
- package/src/i18n/catalog/ko/copy.js +20 -0
- package/src/i18n/catalog/ko/core.js +74 -0
- package/src/i18n/catalog/ko/core2.js +15 -0
- package/src/i18n/catalog/ko/ui.js +221 -0
- package/src/i18n/catalog/ko.js +10 -0
- package/src/i18n/index.js +44 -0
- package/src/i18n/languages.js +9 -0
- package/src/index.js +132 -97
- package/src/ui/ansi.js +7 -7
- package/src/ui/banner.js +7 -6
- package/src/ui/env-plan.js +82 -81
- package/src/ui/prompts.js +97 -122
- package/src/ui/readline-engine.js +59 -58
- package/src/ui/status-cards.js +37 -31
- package/src/ui/summary.js +90 -89
package/README.ja.md
CHANGED
|
@@ -49,6 +49,8 @@ npx project-auto-wizard --mode full --force --type node --dry-run # preview on
|
|
|
49
49
|
|
|
50
50
|
生成されたファイルをコミットして push してください。`npx project-auto-wizard --mode doctor` は、ワークフローが依存するリポジトリ設定を確認します。
|
|
51
51
|
|
|
52
|
+
メッセージの言語は英語または韓国語(`en` | `ko`)です。`--lang`、環境変数 `PROJECT_AUTO_WIZARD_LANG`、`version.yml` の `language` の順に優先されます。
|
|
53
|
+
|
|
52
54
|
## インストールされるもの
|
|
53
55
|
|
|
54
56
|
| インストール対象 | 用途 |
|
package/README.ko.md
CHANGED
|
@@ -49,6 +49,8 @@ npx project-auto-wizard --mode full --force --type node --dry-run # preview on
|
|
|
49
49
|
|
|
50
50
|
생성된 파일을 커밋하고 push하세요. `npx project-auto-wizard --mode doctor`는 워크플로우가 의존하는 레포 설정을 점검합니다.
|
|
51
51
|
|
|
52
|
+
메시지 언어는 영어 또는 한국어(`en` | `ko`)입니다. `--lang`, 환경변수 `PROJECT_AUTO_WIZARD_LANG`, `version.yml`의 `language` 순서로 우선 적용됩니다.
|
|
53
|
+
|
|
52
54
|
## 설치되는 것
|
|
53
55
|
|
|
54
56
|
| 설치 항목 | 용도 |
|
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ Everything it installs is plain GitHub Actions in your own repository. No API ke
|
|
|
21
21
|
</div>
|
|
22
22
|
|
|
23
23
|
<!-- AUTO-VERSION-SECTION: DO NOT EDIT MANUALLY -->
|
|
24
|
-
## Latest Version : v0.
|
|
24
|
+
## Latest Version : v0.15.0 (2026-09-30)
|
|
25
25
|
|
|
26
26
|
[Full release history](CHANGELOG.md)
|
|
27
27
|
|
|
@@ -50,6 +50,8 @@ npx project-auto-wizard --mode full --force --type node --dry-run # preview on
|
|
|
50
50
|
|
|
51
51
|
Commit the generated files and push. `npx project-auto-wizard --mode doctor` checks the repository settings the workflows depend on.
|
|
52
52
|
|
|
53
|
+
Messages are in English or Korean (`en` | `ko`). Pick one with `--lang`, the `PROJECT_AUTO_WIZARD_LANG` environment variable, or `language` in `version.yml`, in that order of precedence.
|
|
54
|
+
|
|
53
55
|
## What you get
|
|
54
56
|
|
|
55
57
|
| Installed | Purpose |
|
package/README.zh-CN.md
CHANGED
|
@@ -49,6 +49,8 @@ npx project-auto-wizard --mode full --force --type node --dry-run # preview on
|
|
|
49
49
|
|
|
50
50
|
提交生成的文件并 push。`npx project-auto-wizard --mode doctor` 会检查工作流所依赖的仓库设置。
|
|
51
51
|
|
|
52
|
+
消息语言为英语或韩语(`en` | `ko`)。可通过 `--lang`、环境变量 `PROJECT_AUTO_WIZARD_LANG` 或 `version.yml` 中的 `language` 指定,优先级依次降低。
|
|
53
|
+
|
|
52
54
|
## 安装内容
|
|
53
55
|
|
|
54
56
|
| 安装项 | 用途 |
|
|
@@ -1,18 +1,32 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// project-auto-wizard CLI
|
|
2
|
+
// project-auto-wizard CLI entry: passes argv to run() in src/index.js.
|
|
3
3
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
5
5
|
|
|
6
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
6
7
|
const [nodeMajor, nodeMinor] = process.versions.node.split(".").map(Number);
|
|
7
8
|
if (nodeMajor < 20 || (nodeMajor === 20 && nodeMinor < 12)) {
|
|
8
|
-
|
|
9
|
+
// Plain English fallback: the message catalog may not even load on an unsupported Node.
|
|
10
|
+
let message = `Node.js 20.12 or later is required (current: ${process.versions.node})`;
|
|
11
|
+
try {
|
|
12
|
+
// Resolve the language cheaply (--lang flag -> env var) so the message matches the requested language.
|
|
13
|
+
const argv = process.argv.slice(2);
|
|
14
|
+
const at = argv.lastIndexOf("--lang");
|
|
15
|
+
const norm = (v) => String(v ?? "").trim().toLowerCase();
|
|
16
|
+
const { t, setLanguage } = await import(pathToFileURL(join(here, "..", "src", "i18n", "index.js")).href);
|
|
17
|
+
setLanguage(norm(process.env.PROJECT_AUTO_WIZARD_LANG)); // invalid values are ignored by setLanguage
|
|
18
|
+
if (at >= 0) setLanguage(norm(argv[at + 1]));
|
|
19
|
+
const inline = argv.findLast((a) => a.startsWith("--lang="));
|
|
20
|
+
if (inline) setLanguage(norm(inline.slice("--lang=".length)));
|
|
21
|
+
message = t("cli.bin.nodeVersion", { current: process.versions.node });
|
|
22
|
+
} catch { /* keep the English fallback */ }
|
|
23
|
+
console.error(message);
|
|
9
24
|
process.exit(1);
|
|
10
25
|
}
|
|
11
26
|
|
|
12
|
-
const here = dirname(fileURLToPath(import.meta.url));
|
|
13
27
|
const indexPath = join(here, "..", "src", "index.js");
|
|
14
28
|
const { run } = await import(pathToFileURL(indexPath).href);
|
|
15
29
|
|
|
16
30
|
const code = await run(process.argv.slice(2), { cwd: process.cwd() });
|
|
17
|
-
// process.exit()
|
|
31
|
+
// Set exitCode instead of calling process.exit() so piped stdout/stderr is fully flushed before exit.
|
|
18
32
|
process.exitCode = code;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "project-auto-wizard",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
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",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
],
|
|
20
20
|
"scripts": {
|
|
21
21
|
"test": "npm run test:node && npm run test:py",
|
|
22
|
-
"test:node": "node --test --test-concurrency=1",
|
|
22
|
+
"test:node": "node --test --test-concurrency=1 --import ./tests/setup-lang.mjs",
|
|
23
23
|
"test:py": "node scripts/run-py-tests.mjs",
|
|
24
24
|
"generate:workflows": "node scripts/generate-workflows.mjs",
|
|
25
25
|
"generate:workflows:check": "node scripts/generate-workflows.mjs --check",
|
|
@@ -3,46 +3,60 @@
|
|
|
3
3
|
{
|
|
4
4
|
"severity": "warning",
|
|
5
5
|
"types": ["flutter"],
|
|
6
|
-
"title": "Flutter SELFHOSTED
|
|
7
|
-
"message": "SELFHOSTED
|
|
6
|
+
"title": "Flutter SELFHOSTED and TEST-APK now run flutter build directly",
|
|
7
|
+
"message": "SELFHOSTED and TEST-APK run flutter build apk --release directly instead of fastlane build, and the Ruby/fastlane install steps are gone. fastlane is now used only by the three store deploy workflows (PLAYSTORE, IOS-TESTFLIGHT, IOS-TEST-TESTFLIGHT).",
|
|
8
|
+
"title_ko": "Flutter SELFHOSTED·TEST-APK가 flutter build를 직접 실행",
|
|
9
|
+
"message_ko": "SELFHOSTED·TEST-APK가 fastlane build 대신 flutter build apk --release를 직접 실행하고 Ruby·fastlane 설치 스텝이 사라집니다. fastlane은 스토어 배포 3종(PLAYSTORE·IOS-TESTFLIGHT·IOS-TEST-TESTFLIGHT)에서만 사용합니다."
|
|
8
10
|
},
|
|
9
11
|
{
|
|
10
12
|
"severity": "warning",
|
|
11
13
|
"types": ["flutter"],
|
|
12
|
-
"title": "Flutter
|
|
13
|
-
"message": "
|
|
14
|
+
"title": "Flutter env default switched to dart-define",
|
|
15
|
+
"message": "New installs default to dart-define (--dart-define-from-file). Existing installs keep dotenv (a generated .env) when version.yml has no saved value; to change it, use the wizard 'Modify > environment variable method' or --flutter-env-mode.",
|
|
16
|
+
"title_ko": "Flutter 환경변수 기본 방식이 dart-define으로 변경",
|
|
17
|
+
"message_ko": "신규 설치의 기본값이 dart-define(--dart-define-from-file)으로 바뀝니다. 기존 설치는 version.yml에 저장값이 없으면 dotenv(.env 생성)를 유지하며, 바꾸려면 마법사 '수정하기 > 환경변수 방식' 또는 --flutter-env-mode를 쓰세요."
|
|
14
18
|
},
|
|
15
19
|
{
|
|
16
20
|
"severity": "warning",
|
|
17
21
|
"types": ["flutter"],
|
|
18
|
-
"title": "Flutter
|
|
19
|
-
"message": "FIREBASE
|
|
22
|
+
"title": "Flutter workflows now run from FLUTTER_PROJECT_DIR",
|
|
23
|
+
"message": "FIREBASE, SELFHOSTED, CI, TEST-APK and IOS-TEST-TESTFLIGHT now run from the Flutter root (FLUTTER_PROJECT_DIR), like PLAYSTORE. For a monorepo where Flutter lives in a subfolder, set it with --paths flutter=<path>.",
|
|
24
|
+
"title_ko": "Flutter 워크플로우가 FLUTTER_PROJECT_DIR 기준으로 동작",
|
|
25
|
+
"message_ko": "FIREBASE·SELFHOSTED·CI·TEST-APK·IOS-TEST-TESTFLIGHT도 PLAYSTORE처럼 Flutter 루트(FLUTTER_PROJECT_DIR)에서 동작합니다. Flutter가 하위 폴더에 있는 모노레포는 --paths flutter=<경로>로 지정하세요."
|
|
20
26
|
},
|
|
21
27
|
{
|
|
22
28
|
"severity": "warning",
|
|
23
29
|
"types": ["flutter", "go", "next", "python", "react", "spring"],
|
|
24
|
-
"title": "
|
|
25
|
-
"message": "CI
|
|
30
|
+
"title": "Register only ci-gate as the monorepo CI required check",
|
|
31
|
+
"message": "CI workflows (Flutter, Go, Next, Python, React, Spring CI) always run and skip their jobs when nothing changed. To use them as a required check, register only the CI Gate (ci-gate), not the individual jobs.",
|
|
32
|
+
"title_ko": "모노레포 CI required check는 ci-gate 하나만 등록",
|
|
33
|
+
"message_ko": "CI 워크플로우(Flutter·Go·Next·Python·React·Spring CI)는 항상 실행되고 변경이 없으면 job을 건너뜁니다. required check로 쓰려면 개별 job이 아닌 CI Gate(ci-gate) 하나만 등록하세요."
|
|
26
34
|
}
|
|
27
35
|
],
|
|
28
36
|
"0.12.0": [
|
|
29
37
|
{
|
|
30
38
|
"severity": "warning",
|
|
31
|
-
"title": "AI
|
|
32
|
-
"message": "GitHub Models
|
|
39
|
+
"title": "AI summary is now a GitHub Copilot opt-in and is off by default",
|
|
40
|
+
"message": "With GitHub Models retired, the AI summary engine is now GitHub Copilot CLI. It consumes AI Credits, so it defaults to off (copilot_ai: false). After updating, release notes and PR summaries are rule-based. To keep using it, reinstall with --copilot or set copilot_ai to true in version.yml and run again.",
|
|
41
|
+
"title_ko": "AI 요약이 GitHub Copilot opt-in으로 바뀌어 기본으로 꺼짐",
|
|
42
|
+
"message_ko": "GitHub Models 종료로 AI 요약 엔진이 GitHub Copilot CLI로 바뀌었고, AI Credits를 소비하므로 기본값이 꺼짐(copilot_ai: false)입니다. 업데이트 후 릴리스 노트·PR 요약은 규칙 기반으로 만들어집니다. 계속 쓰려면 --copilot으로 다시 설치하거나 version.yml의 copilot_ai를 true로 바꾼 뒤 다시 실행하세요."
|
|
33
43
|
}
|
|
34
44
|
],
|
|
35
45
|
"0.12.1": [
|
|
36
46
|
{
|
|
37
47
|
"severity": "warning",
|
|
38
48
|
"types": ["spring"],
|
|
39
|
-
"title": "Spring nexus
|
|
40
|
-
"message": "PROJECT-SPRING-NEXUS-PUBLISH.yml
|
|
49
|
+
"title": "Spring nexus and GitHub Packages publish options removed",
|
|
50
|
+
"message": "PROJECT-SPRING-NEXUS-PUBLISH.yml and PROJECT-SPRING-GITHUB-PACKAGES-PUBLISH.yml are no longer installed, and PROJECT-SPRING-NEXUS-CI.yml became PROJECT-SPRING-CI.yml, which is always installed. On update, untouched old files are deleted and modified ones are moved to .bak. To keep deploying, move the .bak into a workflow you maintain yourself.",
|
|
51
|
+
"title_ko": "Spring nexus·GitHub Packages publish 옵션 제거",
|
|
52
|
+
"message_ko": "PROJECT-SPRING-NEXUS-PUBLISH.yml·PROJECT-SPRING-GITHUB-PACKAGES-PUBLISH.yml을 더 이상 설치하지 않고, PROJECT-SPRING-NEXUS-CI.yml은 PROJECT-SPRING-CI.yml로 바뀌어 항상 설치됩니다. 업데이트하면 손대지 않은 이전 파일은 삭제되고 수정한 파일은 .bak으로 옮겨집니다. 계속 배포하려면 .bak을 직접 관리하는 워크플로우로 옮기세요."
|
|
41
53
|
},
|
|
42
54
|
{
|
|
43
55
|
"severity": "warning",
|
|
44
|
-
"title": "Secret
|
|
45
|
-
"message": "PROJECT-COMMON-SECRET-FILE-UPLOAD.yaml
|
|
56
|
+
"title": "Secret server backup workflow (secret_backup option) removed",
|
|
57
|
+
"message": "PROJECT-COMMON-SECRET-FILE-UPLOAD.yaml is no longer installed. If you had it, untouched files are deleted on update and modified ones are moved to .bak. To keep using it, move the .bak into a workflow you maintain yourself.",
|
|
58
|
+
"title_ko": "Secret 서버 백업 워크플로우(secret_backup 옵션) 제거",
|
|
59
|
+
"message_ko": "PROJECT-COMMON-SECRET-FILE-UPLOAD.yaml을 더 이상 설치하지 않습니다. 설치해 두었다면 업데이트 때 손대지 않은 파일은 삭제되고 수정한 파일은 .bak으로 옮겨집니다. 계속 쓰려면 .bak을 직접 관리하는 워크플로우로 옮기세요."
|
|
46
60
|
}
|
|
47
61
|
]
|
|
48
62
|
}
|
|
@@ -1,108 +1,164 @@
|
|
|
1
|
-
# @wizard ask
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
1
|
+
# User-facing question text for @wizard ask markers.
|
|
2
|
+
# Format 1 (legacy, still supported): KEY: "label"
|
|
3
|
+
# Format 2 (block): label/help/example indented by 2 spaces under KEY
|
|
4
|
+
# Format 3 (type override): a "{type}.KEY" key holds type-specific text
|
|
5
|
+
# Language: label/help/example are English (the default); add label_ko/help_ko/example_ko for Korean.
|
|
6
|
+
# A field with no language variant falls back to the plain field.
|
|
7
|
+
# Lookup order: {type}.KEY -> KEY -> legacy -> fallback (KEY name)
|
|
8
|
+
# Defaults/resolvers do not belong here (the @wizard marker owns them).
|
|
7
9
|
|
|
8
10
|
PROJECT_NAME:
|
|
9
|
-
label: "
|
|
10
|
-
|
|
11
|
+
label: "Service identifier (English slug)"
|
|
12
|
+
label_ko: "서비스 식별자 (영문 슬러그)"
|
|
13
|
+
help: "Used as-is for the Docker container name, image name and deploy domain prefix. Lowercase with hyphens is recommended."
|
|
14
|
+
help_ko: "Docker 컨테이너명·이미지명·배포 도메인 prefix에 그대로 사용됩니다. 소문자-하이픈 권장."
|
|
11
15
|
example: "my-service"
|
|
12
16
|
|
|
13
17
|
flutter.APP_ARTIFACT_NAME:
|
|
14
|
-
label: "
|
|
15
|
-
|
|
18
|
+
label: "App artifact name (English)"
|
|
19
|
+
label_ko: "앱 산출물 이름 (영문)"
|
|
20
|
+
help: "Used for the built APK file name, artifact name and build history file name."
|
|
21
|
+
help_ko: "빌드된 APK 파일명·아티팩트명·빌드 히스토리 파일명에 사용됩니다."
|
|
16
22
|
example: "my-app"
|
|
17
23
|
|
|
18
24
|
SERVICE_DOMAIN:
|
|
19
|
-
label: "
|
|
20
|
-
|
|
25
|
+
label: "Service domain"
|
|
26
|
+
label_ko: "서비스 도메인"
|
|
27
|
+
help: "The production domain the service is reached at after deploy. Replace it with a domain you actually own."
|
|
28
|
+
help_ko: "배포 후 외부에서 접속할 운영 도메인입니다. 실제 보유한 도메인으로 바꿔야 합니다."
|
|
21
29
|
example: "api.example.com"
|
|
22
30
|
|
|
23
31
|
JAVA_VERSION:
|
|
24
|
-
label: "
|
|
25
|
-
|
|
32
|
+
label: "Build JDK version"
|
|
33
|
+
label_ko: "빌드 JDK 버전"
|
|
34
|
+
help: "JDK version of the GitHub Actions build runner. Usually 21 for Spring, 17 for Flutter Android."
|
|
35
|
+
help_ko: "GitHub Actions 빌드 러너의 JDK 버전입니다. Spring은 보통 21, Flutter Android는 17."
|
|
26
36
|
example: "21"
|
|
27
37
|
|
|
28
38
|
DEPLOY_PORT:
|
|
29
|
-
label: "
|
|
30
|
-
|
|
39
|
+
label: "Exposed port"
|
|
40
|
+
label_ko: "외부 노출 포트"
|
|
41
|
+
help: "The host (server) port that maps to the container. Pick one that does not clash with other services."
|
|
42
|
+
help_ko: "호스트(서버)에서 컨테이너로 연결할 포트입니다. 다른 서비스와 겹치지 않게 정하세요."
|
|
31
43
|
example: "8080"
|
|
32
44
|
|
|
33
45
|
ENABLE_VOLUME_MOUNT:
|
|
34
|
-
label: "
|
|
35
|
-
|
|
46
|
+
label: "Enable volume mount"
|
|
47
|
+
label_ko: "볼륨 마운트 사용"
|
|
48
|
+
help: "When on, the host/container paths below are applied to the real deploy and the volume is mounted. When off (default), the paths are ignored even if filled in."
|
|
49
|
+
help_ko: "켜면 아래 호스트/컨테이너 경로가 실제 배포에 반영되어 컨테이너에 볼륨이 마운트됩니다. 끄면(기본값) 경로를 입력해도 무시됩니다."
|
|
36
50
|
example: "true"
|
|
37
51
|
|
|
38
52
|
VOLUME_HOST_PATH:
|
|
39
|
-
label: "
|
|
40
|
-
|
|
53
|
+
label: "Host (NAS) volume path"
|
|
54
|
+
label_ko: "호스트(NAS) 볼륨 경로"
|
|
55
|
+
help: "The real directory on the server where data is stored permanently."
|
|
56
|
+
help_ko: "서버에 데이터를 영구 저장할 실제 디렉토리 경로입니다."
|
|
41
57
|
example: "/volume1/projects/my-service"
|
|
42
58
|
|
|
43
59
|
VOLUME_CONTAINER_PATH:
|
|
44
|
-
label: "
|
|
45
|
-
|
|
60
|
+
label: "Container mount path"
|
|
61
|
+
label_ko: "컨테이너 내부 마운트 경로"
|
|
62
|
+
help: "Where the volume above appears inside the container."
|
|
63
|
+
help_ko: "컨테이너 안에서 위 볼륨이 보일 위치입니다."
|
|
46
64
|
example: "/mnt/my-service"
|
|
47
65
|
|
|
48
66
|
SSH_AUTH_METHOD:
|
|
49
|
-
label: "SSH
|
|
50
|
-
|
|
51
|
-
|
|
67
|
+
label: "SSH authentication method"
|
|
68
|
+
label_ko: "SSH 인증 방식"
|
|
69
|
+
help: "How to connect to the deploy server. Enter one of the two values exactly."
|
|
70
|
+
help_ko: "배포 서버 접속 방식입니다. 둘 중 하나를 그대로 입력하세요."
|
|
71
|
+
example: "password or key"
|
|
72
|
+
example_ko: "password 또는 key"
|
|
52
73
|
|
|
53
74
|
SSH_PORT:
|
|
54
|
-
label: "SSH
|
|
55
|
-
|
|
75
|
+
label: "SSH port"
|
|
76
|
+
label_ko: "SSH 포트"
|
|
77
|
+
help: "The port SSH listens on at the deploy server (usually 22 for regular servers, a custom port for NAS and similar)."
|
|
78
|
+
help_ko: "배포 서버에서 SSH가 열려 있는 포트입니다 (일반 서버는 보통 22, NAS 등은 따로 정한 포트)."
|
|
56
79
|
example: "22"
|
|
57
80
|
|
|
58
81
|
BLUE_PORT:
|
|
59
|
-
label: "
|
|
60
|
-
|
|
82
|
+
label: "Zero-downtime deploy Blue port"
|
|
83
|
+
label_ko: "무중단 배포 Blue 포트"
|
|
84
|
+
help: "Host port of the Blue side of the containers that alternate as Blue/Green. Must not clash with other services or the Green port."
|
|
85
|
+
help_ko: "Blue/Green으로 번갈아 뜨는 컨테이너 중 Blue 쪽 호스트 포트입니다. 다른 서비스·Green 포트와 겹치지 않게 정하세요."
|
|
61
86
|
example: "8080"
|
|
62
87
|
|
|
63
88
|
GREEN_PORT:
|
|
64
|
-
label: "
|
|
65
|
-
|
|
89
|
+
label: "Zero-downtime deploy Green port"
|
|
90
|
+
label_ko: "무중단 배포 Green 포트"
|
|
91
|
+
help: "Host port of the Green side of the containers that alternate as Blue/Green. Must differ from the Blue port."
|
|
92
|
+
help_ko: "Blue/Green으로 번갈아 뜨는 컨테이너 중 Green 쪽 호스트 포트입니다. Blue 포트와 달라야 합니다."
|
|
66
93
|
example: "8081"
|
|
67
94
|
|
|
68
95
|
NGINX_RP_CONF:
|
|
69
|
-
label: "Nginx
|
|
70
|
-
|
|
96
|
+
label: "Nginx reverse proxy config file path"
|
|
97
|
+
label_ko: "Nginx 리버스 프록시 설정 파일 경로"
|
|
98
|
+
help: "The server's Nginx config file whose proxy_pass port is switched between Blue/Green on deploy. A wrong path breaks the zero-downtime switch."
|
|
99
|
+
help_ko: "배포 때 proxy_pass 포트를 Blue/Green으로 바꿔 쓰는 서버의 Nginx 설정 파일입니다. 경로가 틀리면 무중단 전환이 동작하지 않습니다."
|
|
71
100
|
example: "/etc/nginx/sites-enabled/my-service.conf"
|
|
72
101
|
|
|
73
102
|
NGINX_BACKUP_DIR:
|
|
74
|
-
label: "Nginx
|
|
75
|
-
|
|
103
|
+
label: "Nginx config backup folder"
|
|
104
|
+
label_ko: "Nginx 설정 백업 폴더"
|
|
105
|
+
help: "Server folder where a backup is kept before the config file is changed."
|
|
106
|
+
help_ko: "설정 파일을 바꾸기 전에 백업을 남길 서버의 폴더입니다."
|
|
76
107
|
example: "/volume1/projects/nginx/backups"
|
|
77
108
|
|
|
78
109
|
JAR_PATH:
|
|
79
|
-
label: "
|
|
80
|
-
|
|
110
|
+
label: "Build artifact (JAR) path"
|
|
111
|
+
label_ko: "빌드 산출물(JAR) 경로"
|
|
112
|
+
help: "Path of the JAR to put into the PR preview container after the Gradle build (relative to the project root, wildcards allowed)."
|
|
113
|
+
help_ko: "Gradle 빌드 후 PR 프리뷰 컨테이너에 넣을 JAR 파일 경로입니다 (프로젝트 루트 기준, 와일드카드 가능)."
|
|
81
114
|
example: "build/libs/*.jar"
|
|
82
115
|
|
|
83
116
|
PREVIEW_DOMAIN_SUFFIX:
|
|
84
|
-
label: "PR
|
|
85
|
-
|
|
117
|
+
label: "PR preview domain suffix"
|
|
118
|
+
label_ko: "PR 프리뷰 도메인 접미사"
|
|
119
|
+
help: "The trailing part of each PR preview server address. Wildcard DNS for this domain must point at the server (Traefik)."
|
|
120
|
+
help_ko: "PR마다 뜨는 프리뷰 서버 주소의 뒷부분입니다. 이 도메인의 와일드카드 DNS가 서버(Traefik)를 가리켜야 합니다."
|
|
86
121
|
example: "pr.example.com"
|
|
87
122
|
|
|
88
123
|
PROJECT_TARGET_DIR:
|
|
89
|
-
label: "PR
|
|
90
|
-
|
|
124
|
+
label: "PR preview host volume path"
|
|
125
|
+
label_ko: "PR 프리뷰 호스트 볼륨 경로"
|
|
126
|
+
help: "Server data directory to mount into the PR preview container. Leave empty to skip mounting."
|
|
127
|
+
help_ko: "PR 프리뷰 컨테이너에 마운트할 서버의 데이터 디렉토리입니다. 비워 두면 마운트하지 않습니다."
|
|
91
128
|
example: "/volume1/projects/my-service"
|
|
92
129
|
|
|
93
130
|
PROJECT_MNT_DIR:
|
|
94
|
-
label: "PR
|
|
95
|
-
|
|
131
|
+
label: "PR preview container mount path"
|
|
132
|
+
label_ko: "PR 프리뷰 컨테이너 마운트 경로"
|
|
133
|
+
help: "Where the host volume above appears inside the PR preview container."
|
|
134
|
+
help_ko: "위 호스트 볼륨이 PR 프리뷰 컨테이너 안에서 보일 위치입니다."
|
|
96
135
|
example: "/mnt/my-service"
|
|
97
136
|
|
|
98
137
|
ISSUE_HELPER_CREATE_BRANCH:
|
|
99
|
-
label: "
|
|
100
|
-
|
|
138
|
+
label: "Auto-create a branch when an issue is opened"
|
|
139
|
+
label_ko: "이슈 생성 시 브랜치 자동 생성"
|
|
140
|
+
help: "When an issue is opened, a branch is created from the base branch automatically. Keep the default (no) if you do not want that."
|
|
141
|
+
help_ko: "이슈가 열리면 base 브랜치 기준으로 브랜치를 자동으로 만듭니다. 원치 않으면 기본값(아니오)을 그대로 두세요."
|
|
101
142
|
example: "true"
|
|
102
143
|
|
|
103
144
|
# workflow filename (partial match) -> human readable short name
|
|
104
|
-
# wizard uses this to build "[usage]" in env questions.
|
|
145
|
+
# the wizard uses this to build "[usage]" in env questions. `_workflow_names_ko` holds the Korean names.
|
|
105
146
|
_workflow_names:
|
|
147
|
+
NONSTOP-NGINX: "Zero-downtime deploy (Nginx)"
|
|
148
|
+
NONSTOP-TRAEFIK: "Zero-downtime deploy (Traefik)"
|
|
149
|
+
PR-PREVIEW: "PR preview"
|
|
150
|
+
SIMPLE-CICD: "Single-server deploy"
|
|
151
|
+
REACT-CICD: "Frontend deploy"
|
|
152
|
+
REACT-CI: "Frontend build"
|
|
153
|
+
NEXT-CICD: "Frontend deploy"
|
|
154
|
+
NEXT-CI: "Frontend build"
|
|
155
|
+
PYTHON-CI: "Build check"
|
|
156
|
+
FLUTTER-ANDROID-SELFHOSTED: "Android self-hosted deploy"
|
|
157
|
+
FLUTTER-ANDROID-PLAYSTORE: "Play Store deploy"
|
|
158
|
+
FLUTTER-ANDROID-FIREBASE: "Firebase deploy"
|
|
159
|
+
ISSUE-HELPER: "Issue helper"
|
|
160
|
+
|
|
161
|
+
_workflow_names_ko:
|
|
106
162
|
NONSTOP-NGINX: "무중단배포(Nginx)"
|
|
107
163
|
NONSTOP-TRAEFIK: "무중단배포(Traefik)"
|
|
108
164
|
PR-PREVIEW: "PR 프리뷰"
|
|
@@ -1,42 +1,54 @@
|
|
|
1
1
|
# ===================================================================
|
|
2
|
-
#
|
|
2
|
+
# This file is user-owned. Edit the per-mode behavior here.
|
|
3
3
|
# ===================================================================
|
|
4
4
|
#
|
|
5
|
-
# Google Play
|
|
6
|
-
# PROJECT-FLUTTER-ANDROID-PLAYSTORE-CICD
|
|
7
|
-
#
|
|
8
|
-
# project-auto-wizard
|
|
5
|
+
# Fastfile template for Google Play deployment.
|
|
6
|
+
# The PROJECT-FLUTTER-ANDROID-PLAYSTORE-CICD workflow copies this file to android/fastlane/Fastfile
|
|
7
|
+
# and then runs `bundle exec fastlane deploy_internal`.
|
|
8
|
+
# project-auto-wizard does not overwrite this file if it already exists, so feel free to edit it.
|
|
9
9
|
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
19
|
-
#
|
|
10
|
+
# Deploy modes (passed by the workflow via the DEPLOY_MODE environment variable)
|
|
11
|
+
# +---------------+------------+----------------+-----------------------------------------+
|
|
12
|
+
# | DEPLOY_MODE | track | release_status | Behavior |
|
|
13
|
+
# +---------------+------------+----------------+-----------------------------------------+
|
|
14
|
+
# | store_only | internal | completed | Upload to the internal testing track |
|
|
15
|
+
# | store_prepare | production | draft | Upload to production as a draft |
|
|
16
|
+
# | | | | (release manually in Play Console) |
|
|
17
|
+
# | store_submit | production | completed | Go all the way to a production review |
|
|
18
|
+
# +---------------+------------+----------------+-----------------------------------------+
|
|
19
|
+
# Unknown or empty values are treated as store_only.
|
|
20
20
|
#
|
|
21
|
-
#
|
|
22
|
-
# PACKAGE_NAME
|
|
23
|
-
# AAB_PATH
|
|
24
|
-
# GOOGLE_PLAY_JSON_KEY
|
|
25
|
-
# VERSION_NAME
|
|
26
|
-
# VERSION_CODE
|
|
27
|
-
# DEPLOY_MODE
|
|
21
|
+
# Environment variables passed by the workflow
|
|
22
|
+
# PACKAGE_NAME App package name (ANDROID_PACKAGE_NAME secrets/variables)
|
|
23
|
+
# AAB_PATH Absolute path of the .aab to upload
|
|
24
|
+
# GOOGLE_PLAY_JSON_KEY Path to the service account JSON key file
|
|
25
|
+
# VERSION_NAME Version name (release name in Play Console)
|
|
26
|
+
# VERSION_CODE Version code (matches the changelog file name)
|
|
27
|
+
# DEPLOY_MODE Deploy mode from the table above
|
|
28
28
|
#
|
|
29
|
-
#
|
|
30
|
-
#
|
|
29
|
+
# The workflow writes the changelog to android/fastlane/metadata/android/ko-KR/changelogs/<VERSION_CODE>.txt,
|
|
30
|
+
# and upload_to_play_store finds it by version code under metadata_path.
|
|
31
|
+
|
|
32
|
+
# Look up a user-facing message in the installed catalog so it follows `language` in version.yml.
|
|
33
|
+
# Finds the repo root by walking up to .github/scripts/messages.py (it reads ./version.yml from there);
|
|
34
|
+
# falls back to the key when the catalog is unavailable (for example when fastlane runs on a laptop).
|
|
35
|
+
def paw_msg(key, **params)
|
|
36
|
+
root = Dir.pwd
|
|
37
|
+
root = File.dirname(root) until File.exist?(File.join(root, ".github", "scripts", "messages.py")) || root == File.dirname(root)
|
|
38
|
+
out = IO.popen(["python3", File.join(root, ".github", "scripts", "messages.py"), "get", key, *params.map { |k, v| "#{k}=#{v}" }], chdir: root, err: File::NULL, &:read)
|
|
39
|
+
$?.success? && !out.to_s.strip.empty? ? out.chomp : key
|
|
40
|
+
rescue StandardError
|
|
41
|
+
key
|
|
42
|
+
end
|
|
31
43
|
|
|
32
44
|
default_platform(:android)
|
|
33
45
|
|
|
34
46
|
platform :android do
|
|
35
|
-
desc "AAB
|
|
47
|
+
desc "Uploads the AAB to Google Play (DEPLOY_MODE: store_only | store_prepare | store_submit)"
|
|
36
48
|
lane :deploy_internal do
|
|
37
49
|
package_name = ENV["PACKAGE_NAME"].to_s.strip
|
|
38
50
|
if package_name.empty?
|
|
39
|
-
UI.user_error!("
|
|
51
|
+
UI.user_error!(paw_msg("fastlane.package_name_empty"))
|
|
40
52
|
end
|
|
41
53
|
|
|
42
54
|
aab_path = ENV["AAB_PATH"].to_s.strip
|
|
@@ -44,7 +56,7 @@ platform :android do
|
|
|
44
56
|
version_name = ENV["VERSION_NAME"].to_s.strip
|
|
45
57
|
version_code = ENV["VERSION_CODE"].to_s.strip
|
|
46
58
|
if aab_path.empty? || json_key.empty? || version_name.empty? || version_code.empty?
|
|
47
|
-
UI.user_error!("
|
|
59
|
+
UI.user_error!(paw_msg("fastlane.android_env_required"))
|
|
48
60
|
end
|
|
49
61
|
|
|
50
62
|
deploy_mode = ENV["DEPLOY_MODE"].to_s.strip
|
|
@@ -57,17 +69,17 @@ platform :android do
|
|
|
57
69
|
when "store_only"
|
|
58
70
|
["internal", "completed"]
|
|
59
71
|
else
|
|
60
|
-
UI.important("
|
|
72
|
+
UI.important(paw_msg("fastlane.deploy_mode_unknown", deploy_mode: deploy_mode)) unless deploy_mode.empty?
|
|
61
73
|
["internal", "completed"]
|
|
62
74
|
end
|
|
63
75
|
|
|
64
|
-
# lane
|
|
65
|
-
#
|
|
76
|
+
# The lane runs from the android/fastlane directory that holds this Fastfile, so this points to
|
|
77
|
+
# the same android/fastlane/metadata/android path where the workflow writes the changelog.
|
|
66
78
|
metadata_path = File.expand_path("metadata/android")
|
|
67
79
|
changelog_file = File.join(metadata_path, "ko-KR", "changelogs", "#{version_code}.txt")
|
|
68
|
-
UI.important("
|
|
80
|
+
UI.important(paw_msg("fastlane.changelog_missing", file: changelog_file)) unless File.exist?(changelog_file)
|
|
69
81
|
|
|
70
|
-
UI.message("
|
|
82
|
+
UI.message(paw_msg("fastlane.play_deploy", deploy_mode: deploy_mode.inspect, track: track, release_status: release_status))
|
|
71
83
|
|
|
72
84
|
upload_to_play_store(
|
|
73
85
|
package_name: package_name,
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
3
|
<!--
|
|
4
|
-
|
|
4
|
+
This file is user-owned. Replace the 3 placeholders wrapped in double underscores with real values, then commit.
|
|
5
5
|
|
|
6
|
-
PROJECT-FLUTTER-IOS-TESTFLIGHT / PROJECT-FLUTTER-IOS-TEST-TESTFLIGHT
|
|
7
|
-
xcodebuild -exportArchive -exportOptionsPlist ExportOptions.plist
|
|
8
|
-
|
|
9
|
-
(
|
|
6
|
+
The PROJECT-FLUTTER-IOS-TESTFLIGHT / PROJECT-FLUTTER-IOS-TEST-TESTFLIGHT workflows use it when building the IPA with
|
|
7
|
+
xcodebuild -exportArchive -exportOptionsPlist ExportOptions.plist.
|
|
8
|
+
The workflow aborts if any placeholder is left.
|
|
9
|
+
(This comment does not spell out the placeholders, because the workflow checks that none remain after you fill in the values.)
|
|
10
10
|
|
|
11
|
-
teamID Apple Developer Team ID (10
|
|
12
|
-
provisioningProfiles
|
|
13
|
-
|
|
11
|
+
teamID Apple Developer Team ID (10 characters, Membership in your developer.apple.com account)
|
|
12
|
+
provisioningProfiles Key is the app bundle ID (e.g. com.example.app),
|
|
13
|
+
value is the provisioning profile name (same as the GitHub Secret IOS_PROVISIONING_PROFILE_NAME)
|
|
14
14
|
-->
|
|
15
15
|
<plist version="1.0">
|
|
16
16
|
<dict>
|